Как читать последовательные данные без блокировки с помощью ESP8266

I'm deconding one electronic device serial protocol and using ESP8266 for this task. Устройство постоянно посылает 202 байта данных, и я понял начало и конец.

Весь пакет выглядит следующим образом:

71 С8 01 10 56 55 62 49 00 05 00 00 00 00 00 00 00 00 00 00 19 15 11 55 16 5е 55 05 09 00 00 00 00 00 00 00 00 00 80 8ф 80 8а В2 71 71 97 99 00 00 00 00 00 00 00 00 00 00 00 80 85 15 8а 85 85 н0 7Б 78 7е 1Ф 1Ф 1Ф 79 79 8д 8д 9Д 96 71 В7 8е 8е 8е 8е 80 85 А3 7б 8а 8а 8а 94 94 9э 9э 82 90 8б 05 65 78 С1 0В 00 00 00 00 00 00 00 00 55 56 55 21 53 15 5а 05 12 12 19 00 00 00 00 00 00 00 00 Е2 се 0d с 71 81 72 се 0С 92 81 В0 00 АА АВ В0 В6 9С 7С 32 32 32 32 32 80 В7 АФ компакт 9а переменного тока 79 80 77 80 ФФ 91 01 29 59 00 00 3В 0В 1С 51 59 01 36 79 01 01 С3 02 00 ДД 02 00 05 00 00 01 00 00 06 01 01 01 01 01 0а 14 00 00 00 77

Здесь start "header" - это 0x71 и 0xc8, а последние 202 байта-это контрольная сумма дырки 201 байт.

Цель состоит в том, чтобы получить допустимые данные 202 байта, проверив, содержит ли start 0x71 и 0xc8

Мои чтения выглядят так, как это улучшить в лучшем случае?

void readSerial()
{
  if (Serial.available() > 0) {
    data_length = Serial.readBytes(data, 202);
       while (Serial.available()) {
      delay(2);
      Serial.read();
    }
  }
  else data_length = 0;
}

, 👍0


1 ответ


0

Во-первых, я думаю, что протокол, вероятно, немного отличается. Первый байт-71. Следующий байт, по-видимому, будет следующим числом байтов (шестнадцатеричный код C8 равен 200). Последний байт-это контрольная сумма.

Поэтому вам нужно проверить 71, когда это будет получено, вы сможете прочитать следующий байт (количество байтов), данные и контрольную сумму.

Поэтому код должен быть примерно таким:

void readSerial()
{
   if (Serial.available() > 0) 
   {
      uint8_t readByte = Serial.read(); // uint8_t = 8-разрядное целое число без знака
      if (readByte == 71)
      {
         // Прочитать сообщение
         data_length = Serial.read();
         data_length = Serial.readBytes(data, data_length);
         checksum = Serial.read();
         // Проверить контрольную сумму
      }
      else 
      {
         data_length = 0;
      }
   }
}

(примечание: код не проверен)

Что касается предотвращения блокировок, вам придется читать их один за другим, а тем временем выполнять другие задачи.

Обновление

Предполагая, что чтение начинается, когда отправитель, возможно, уже отправляет, и предполагая, что сообщение всегда начинается с 71 C8.

Создайте перечисление, которое показывает, сколько "начальных байтов" прошло (71 C8-начальные байты).

enum EStartByte
{
   WaitForMessage,
   FirstStartBytePassed,
   ReadMessage
};

enum EStartByte startByte = WaitForMessage;

void readSerial()
{
   while (Serial.available())
   {
      switch (startByte)
      {
      case WaitForMessage: 
          // Ожидание первого стартового байта
          if (Serial.readByte() == 0x71)
          {
               startByte = FirstStartBytePassed; 
          }
          break;

      case FirstStartBytePassed: 
          // Ожидание второго стартового байта
          if (Serial.readByte() == 0xC8)
          {
               startByte = ReadMessage; // Start reading
          }
          else
          {
               startByte = WaitForMessage;
          }
          break;

      case ReadMessage:
          // Считывание данных
          data_length = Serial.readBytes(data, 200);
          checksum = Serial.read();
          // Проверьте контрольную сумму

          startByte = WaitForMessage; // Начать сначала
          break;
      }
   }
}
,

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен на chat](https://chat.stackexchange.com/rooms/102906/discussion-on-answer-by-michel-keijzers-how-to-read-serial-data-without-any-bloc)., @VE7JRO