Проблема потери данных по UART, arduino

Все прочитали, вроде даже поняли, взяли паяльник - а нифига не получается? Скорее сюда! Поможем. Чем можем...
Ответить
Anton991
Родился
Сообщения: 14
Зарегистрирован: Пн авг 28, 2017 12:31:32

Проблема потери данных по UART, arduino

Сообщение Anton991 »

Здравствуйте. У меня возникла проблема следущего рода: по UART приходят данные большими пакетами 200-256 байт, я их считываю но конец обрывается, у меня подозрения что это из за буфера UART. Плата wemos D1. Доходят около 150 байт

Код ниже, Serial запущен на скорости 115200

Код: Выделить всё

String  msg;
while (Serial.available() > 0) {
    byte inChar = Serial.read();
    msg += inChar;
}
Serial.println(msg);
Как можно решить проблему потери данных?

P.S. в файле HardwareSerial.h буфер пробывал увеличивать до 256 и до 255, не помогло.

#define SERIAL_TX_BUFFER_SIZE 255
#define SERIAL_RX_BUFFER_SIZE 255

Возможности уменшить пакеты с отправителя тоже нету
Реклама
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Проблема потери данных по UART, arduino

Сообщение arkhnchul »

дело не в буфере. Передача идет последовательно по одному символу, причем заметно медленнее, чем контроллер обычно может обрабатывать принятые данные. Ваш кусок кода быстро выгребает все, что есть в буфере, Serial.available() возвращает 0 (ибо следующий символ еще не успел придти), и цикл чтения на этом завершается.
Определяйте окончание передачи пакета как-нибудь иначе.
Реклама
Anton991
Родился
Сообщения: 14
Зарегистрирован: Пн авг 28, 2017 12:31:32

Re: Проблема потери данных по UART, arduino

Сообщение Anton991 »

[uquote="arkhnchul",url="/forum/viewtopic.php?p=3241820#p3241820"]дело не в буфере. Передача идет последовательно по одному символу, причем заметно медленнее, чем контроллер обычно может обрабатывать принятые данные. Ваш кусок кода быстро выгребает все, что есть в буфере, Serial.available() возвращает 0 (ибо следующий символ еще не успел придти), и цикл чтения на этом завершается.
Определяйте окончание передачи пакета как-нибудь иначе.[/uquote]
Да такая проблема была, но тогда было так, что считывался первый байт. Но при следующем цикле loop, считывались остальные. Я это решил вставив delay(2), сейчас же обрезается конец посылки, и при прохождении одного цикла loop, когда действие снова доходит до считывания данных с ком порта, там данных никаких нет, буфер пуст. Если бы проблема была в высокой скорости считывания то в буфере бы остались данные, которые извлеклись бы в следующем цикле loop

Добавлено after 1 hour 11 minutes 49 seconds:
Поясню еще, отправителем является GPS модуль отправляет RAW данные, я подцепился к ком порту и смтрел что доходит а что обрубается, вот код прошивки arduino (wemos d1 если быть точнее):

Код: Выделить всё

void setup() {
  // start serial port:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}
void loop() {
Serial.println( "++++++++++++++++++BEGIN++++++++++++++++");
 int i=1;
 while (Serial.available() > 0) {
   byte inChar = Serial.read();
   
   Serial.print("#"+ String(i)+ ": ");
   Serial.println(inChar, HEX);
   i=i+1;
   delay(5);   
   }
  Serial.println( "________________END_________________");
}
скриншот ниже демонстрирует, что происходит какая-то ерунда под конец посылки.
Изображение
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Проблема потери данных по UART, arduino

Сообщение arkhnchul »

и снова нет, вы слишком полагаетесь на предсказуемость задержек

как понимаю, у вас там протокол UBX. В его спецификации вполне подробно описан формат пакета:
- Every Message starts with 2 Bytes: 0xB5 0x62
- 1 Byte Class Field follows. The Class defines the basic subset of the message
- 1 Byte ID Field defines the message that is to follow
- 2 Byte Length Field is following. Length is defined as being the length of the payload, only. It does not
include Sync Chars, Length Field, Class, ID or CRC fields. The number format of the length field is an
unsigned 16-Bit integer in Little Endian Format.
- The Payload is a variable length field.
- CK_A and CK_B is a 16 Bit checksum whose calculation is defined below.
собственно, вам нужно обнаружить старт передачи по приему символа 0xB5, удостовериться в этом приемом символа 0x62, прочитать байты Class и ID, прочитать два байта Length - это будет размер поля данных, прочитать length байт данных, прочитать два байта чексуммы. Только после этого можно считать пакет принятым и что-то с ним делать.
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «Практика»