Передача структуры

Тема в разделе "ESP8266, ESP32", создана пользователем GeoShu, 27 дек 2021.

  1. GeoShu

    GeoShu Гик

    Как передать структуру между Ардуино и ESP8266 по UART?
    Перерыл все форумы, нигде нет ответа.
    Задача такая: есть датчик температуры, подключенный к NANO, NANO по Lora (подключен к UART) обменивается данными с ESP8266 (к ESP подключена Lora тоже по UART).
    Для начала работы датчика отправляется запрос от ESP8266 к NANO с настройками. Настройки передаю через структуру. В структуре данные разных типов - String, float, uint16_t, uint8_t.
    При передаче от ESP к NANO эта структура принимается, но происходит сдвиг между битами и в принятой структуре данные получаются не правильными.
    Про порядок расположения данных читал - сначала "тяжелые", потом "легкие".
    Нашел что-то близкое на форумах, там пишут про передачу данных побитно.
    Передатчик:
    Код (C++):
    struct StrSend {
      String testStr;
      uint16_t test;
      uint8_t  crc;
    };
    StrSend dataTx;

    void setup () {
      SendStr.testStr = "testing";
      SendStr.test = 1234;
      SendStr.crc = crc8((byte*)&dataTx, sizeof(dataTx) - 1);
    }

    void loop() {
    Tx();
    delay(1000);
    }

    void Tx() {
        for (byte i = 0; i < sizeof(dataTx); i++) {
              LoraUART.print(*((byte*)&dataTx + i));
        }
    }

    byte  crc8(byte *buffer, byte size){
        byte crc = 0;
        for(byte i = 0; i < size; i++){
            byte data = buffer[i];
            for(int j = 8; j > 0; j--){
               crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1);
               data >>= 1;
            }
        }
        return crc;
    }
    Как правильно принять эти данные?

    И второй вопрос:
    Не правильно считается crc на ESP. Пробовал посчитать без отправки структуры:

    Код (C++):
    void setup () {
      SendStr.testStr = "testing";
      SendStr.crc = crc8((byte*)&dataTx, sizeof(dataTx) - 1);
     
      byte crc = crc8((byte*)&dataTx, sizeof(dataTx));
      Serial.println(crc);
    }
    Получается случайное число. На NANO crc считается верно.
     
  2. SergeiL

    SergeiL Оракул Модератор

    Было уже на форуме.
    Ищем по ключевым словам: pragma pack
     
    GeoShu нравится это.
  3. GeoShu

    GeoShu Гик

    Спасибо за наводку. Почитал. Там пишут, что синтаксис для разных компиляторов отличается. Может подсказать, где можно почитать про Arduino IDE?

    А по поводу CRC можете что-нибудь сказать?
     
  4. parovoZZ

    parovoZZ Гуру

    Не надо передавать никаких структур. Все передачи побайтно.
     
    GeoShu и ale нравится это.
  5. SergeiL

    SergeiL Оракул Модератор

    Так там же есть пример для Arduino IDE.
    Как раз для ESP и AVR.
     
    GeoShu нравится это.
  6. GeoShu

    GeoShu Гик

    Спасибо. Как передавать я в своем вопросе попытался написать. А как собрать потом эти байты обратно в структуру?
    И как контрольную сумму для всего этого считать, а то часто происходят потери пакетов.
     
  7. GeoShu

    GeoShu Гик

    Да, пример видел, вот только там нет ссылок на документацию, не хотелось бы глупо копировать буквы не понимая что они означают. А документацию я не смог найти в поисковиках (для Ардуино Иде)
     
  8. ale

    ale Нерд

    структуры по uart передавать легко. на стороне передатчика сериализуете структуру, на стороне приемник - десериализуете. Попутно понимаете, что все есть байты и передача чего бы то ни было сводиться к передаче байтов. parovoZZ как обычно сказал все что нужно ранее)) А конторльную сумму считайте как вам надо, но лучше возьмите за основу действующие алгоритмы
     
    GeoShu нравится это.
  9. parovoZZ

    parovoZZ Гуру

    а с ней что не так?
     
  10. akl

    akl Гуру

    чет мне кажется в таких вещах использовать объект String как-то некомильфо? не лучше ли обычную си-строку с заранее известным размером и т.д.?

    хотя, если как-то че-то передается, то наверно нормально
     
    SergeiL нравится это.
  11. parovoZZ

    parovoZZ Гуру

    И передача и приём через массивы. Те поля в структуре, которые занимают более одного байта, перед отправкой и после получения необходимо разбирать и собирать вручную. Все эти прагма пак и прочие костыли - это выстрел в ногу.
     
  12. parovoZZ

    parovoZZ Гуру

    найди в тырнете библиотеку на CRC16 и считай.
     
  13. parovoZZ

    parovoZZ Гуру

    стринги - это же массив символов. Сиречь байтов. Берёте указатель на начало этого массива и передаёте, пока не встретите конец строки. В это плане строка чем-то удобна, так как не надо выяснять её длину заранее.
     
  14. akl

    akl Гуру

    не шарю как там в ардуине, но в обычном си++ вроде как в такой структуре как у ТС будет лежать указатель на объект, а
    sizeof(dataTx) соответственно будет всегда 8 байтов или типа того, независимо от того какой длины текст в этом объекте был введен (а он там может быть введен в любой момент и вообще он как бы динамический же)
     
    SergeiL нравится это.
  15. SergeiL

    SergeiL Оракул Модератор

    Pragma pack - далеко не костыль, а нормальный рабочий инструмент.
    Просто нужно понимать, что нужно сделать, и что ты делаешь.
    Конечно для мигания светодиодом никакие Прагмы не нужны, а если копнуть поглубже, то без них и не обойтись.
     
  16. parovoZZ

    parovoZZ Гуру

    зачем сайзоф, если любая строка в конце обязана иметь символ "\0"? Иначе это массив символов, а не строка.
     
  17. parovoZZ

    parovoZZ Гуру

    все стандарты (и не только), с которыми доводилось работать, описывают поля в пакете, но никак не структуру. А уж как там будешь складывать полученные поля и куда - сугубо личная воля программиста.
     
  18. akl

    akl Гуру

    это ТС использует сайзоф.

    у меня стойкое ощущение, что у него должен там передаваться не текст, а тупо числа в виде адреса некоего объекта в памяти
     
  19. SergeiL

    SergeiL Оракул Модератор

    Да конечно. :)
    Можно и указателями, и структурами не пользоваться - все это "сугубо личная воля "программиста""
    А "pragma" - далеко не только "pack". Существует более 40 директив у pragma.
     
  20. GeoShu

    GeoShu Гик

    Так я ж и считаю. Но на нано она считается правильно, а на есп нет. Кусок кода в вопросе написал.