Вычисление CRC строки на arduino в связке с esp8266.

Тема в разделе "Arduino & Shields", создана пользователем Gomez, 29 сен 2018.

  1. Gomez

    Gomez Гик

    В общем, дело такое - получаю на esp8266 какую-то строку (String) не очень большой длины, байт 300-400 (по-разному). Эту строку я отправляю Ардуино, и хотелось бы, чтобы и на ESP при этом вычислилась CRC, и на Ардуино при получении - тоже. В общем, Ардуино отправляет CRC обратно на ESP, и если контрольная сумма совпадает, то все ОК.

    Нашел такой вариант
    Код (C++):
    uint8_t crc8(const uint8_t *addr, uint8_t len) {
      uint8_t crc = 0;
      while (len--) {
        uint8_t inbyte = *addr++;
        for (uint8_t i = 8; i; i--) {
          uint8_t mix = (crc ^ inbyte) & 0x01;
          crc >>= 1;
          if (mix) crc ^= 0x8C;
          inbyte >>= 1;
        }
      }
      return crc;
    }
    Но я, как всегда, запутался со всякими конвертациями.
    Мне бы STRING скормить и STRING же получить в качестве CRC.
    Это лучше делать до вызова функции или лучше функцию как-то дописать?

    Может, есть более простой способ получения CRC для таких случаев?
     
  2. Mitrandir

    Mitrandir Гуру

    String.C_str()
    Получите указатель на нуль заверщенную строку чаров и там ваша функция мчитает срц
     
  3. Gomez

    Gomez Гик

    То есть типа
    Код (C++):
    myStrCrc = crc8(myStr.c_str(), myStr.length());
    Ругается компилятор invalid conversion from 'const char*' to 'const uint8_t*
     
  4. Mitrandir

    Mitrandir Гуру

    Поменяйте тип аргумента или приведите тип указателя
     
  5. Gomez

    Gomez Гик

    Иже херувимы. :)

    Нашел даже проще вариант CRC
    Код (C++):
    byte stringChecksum(char *s)
    {
        byte c = 0;
        while(*s != '\0')
            c ^= *s++;
        return c;
    }
    Пробую превратить свою строку в эти char-ы, будь они неладны
    Код (C++):
    for (int i = 0; i < s.length(); i++)
    {
      char c = s[i];
    }
    И опять "гранаты не той системы". :mad:
     
    Последнее редактирование: 29 сен 2018
  6. DIYMan

    DIYMan Guest

    Код (C++):
    myStrCrc = crc8((const uint8_t*)myStr.c_str(), myStr.length());
    И волосы мягкие и шелковистые.
     
    Igor68, Gomez и Mitrandir нравится это.
  7. Gomez

    Gomez Гик

    Спасибо!!
    Экспериментирую теперь с первым и вторым методом вычисления CRC (меняя Ваш пример вызова функций, конечно)
    Но на выходе в serialPrint(myStrCrc) получаю двух-трехзначное число. Самое смешное, что оно разное, если действительно что-то изменить в строке типа
    Код (C++):

    storeSettings=y&f_ssid=tempa&f_pass=123&f_press=15&f_url=http://site1.ru/index.php&f_url_res=http://site2.ru/index.php&f_openw=http://site3.ru/data?key=78e0ca7013d047519e6426d255d9455e&f_reb=2&f_showreb=0
    Но мне что-то подсказывает, что трехзначное число не может описать все количество комбинаций символов в этой строке. :)
     
  8. Оно и не должно. Если вам нужна полная избыточность, то строку нужно просто дублировать.
     
    Gomez нравится это.
  9. Gomez

    Gomez Гик

    Нет-нет, мне не нужна дотошная проверка - не ракету на орбиту вывожу. Значит, так и должно быть - тогда вполне устраивает. Просто думал, что я теперь и с полученным числом обращаюсь не так. :)

    Действительно гоню - это ж byte.

    Код (C++):
    byte stringChecksum(char *s)
    {
        byte c = 0;
        while(*s != '\0')
            c ^= *s++;
        return c;
    }
    Я просто, к стыду своему, строчку c ^= *s++; не совсем понимаю, и эти звездочки еще...
    Поэтому не понимаю метода получения crc.
     
    Последнее редактирование: 29 сен 2018
  10. Это не crc. Первая функция в теме - crc. Эта функция просто сворачивает строку через xor. Не очень хорошая контрольная сумма.
     
    parovoZZ нравится это.
  11. Gomez

    Gomez Гик

    У меня первая выдает тоже трехзначные числа, но повторяющиеся зачастую. Видимо, там надо еще и полученное значение как-то в String конвертировать. Поэтому смирился со второй. :D

    Я подумал - к "контрольному числу" присоединю длину полученной строки и для контроля успешности передачи по serial будет вполне достаточно.
     
    Последнее редактирование: 30 сен 2018