Много пропущенных байтов с последовательной связью

У меня есть настройка с последовательной связью от Raspberry Pi до Arduino. Он передает данные со скоростью 9600 бод на обоих устройствах, а также от Raspberry Pi 3b+ GPIO-14,UART0,TX0 до Arduino Nano RX0. Между настройками есть переключатель уровня, как рекомендовано учебниками AdaFruit. Я отправляю данные с Raspberry Pi следующим образом:

#loop here
m = []
m.append(255)
m.append(i) // значение индекса между 0-150
m.append(p[0][i]) // значение между 0-254
m.append(p[1][i]) // значение between 0-254
m.append(p[2][i]) // значение между 0-254
#print statement here
'''
Data: [255, 94, 0, 0, 0, 255, 95, 254, 0, 0, 255, 96, 0, 254, 0]
...
'''

И получение данных на Arduino как таковое:

void serialEvent() {
  while (Serial.available()) {
    // получить новый байт:
    byte inChar = (byte)Serial.read();
    sprintf(printString, "Received: %d", inChar);
    Serial.println(printString);
  }
}
/*
Received: 255
Received: 94
Received: 0
Received: 255
Received: 95
Received: 254
Received: 0
Received: 255
Received: 96
Received: 0
Received: 254
Received: 255
Received: 94
Received: 0
Received: 0
Received: 0
Received: 255
Received: 254
Received: 255
...
*/

Есть идеи, почему так много пропущенных байтов и как это исправить?

EDIT: @juraj Между ними есть земля. Я измерял с помощью портативного осциллографа. Я могу опубликовать фотографию установки завтра.

@Edgar Bonet Функция цикла пуста и выглядит следующим образом:

void loop() {
}

Кроме того, у меня нет никаких данных, отправляемых обратно на Raspberry Pi. У меня полностью отключен последовательный провод TX от Arduino

, 👍2

Обсуждение

Не имеет значения, проводите вы TX или нет. Serial.println() в любом случае занимает одно и то же время. Вы пытались сократить строку, например, просто шестнадцатеричное представление полученных байтов?, @the busybee

Re: “У меня полностью отключен последовательный провод TX от Arduino”: это не имеет значения. Arduino все равно, и он даже не знает, что провод отсоединен. Он все еще отправляет данные. Это требует времени: примерно в 14 раз больше времени, чем потребовалось для получения данных., @Edgar Bonet

@EdgarBonet Не могли бы вы уточнить, почему он отправляет данные? Это из - за инструкции serial print?, @errolflynn

Да, “Serial.println (...)”означает "пожалуйста, отправьте эти данные"., @Edgar Bonet


1 ответ


1

Без полных кодов мы можем только догадываться. Я предполагаю, что последовательный буфер приема на Arduino переполнен.

Одна из причин, по которой это может произойти, заключается в том, что serialEvent() вызывается недостаточно часто. Эта функция вызывается ядром Arduino на каждой итерации цикла, сразу после возврата loop (). Если ваш loop () занимает слишком много времени (например, вы используете delay () или блокирующее ожидание), буфер приема может переполниться до того, как serialEvent () сможет его очистить.

Другая причина заключается в том, что Raspberry Pi отправляет слишком много данных слишком быстро. Для каждого байта, полученного Arduino, он должен отправить обратно от 13 до 15 байт. Если слишком много данных поступает слишком быстро, буфер передачи в конечном итоге заполняется, и тогда Serial.println() становится очень медленно, потому что он должен ждать, пока байты действительно выйдут на провод. Это, в свою очередь, замедляет работу serialEvent() до такой степени, что он может вызвать переполнение приемного буфера.

Edit: Если это (Малина, отправляющая данные слишком быстро) является причиной проблемы, очевидное решение состоит в том, чтобы отправить данные медленнее, как:

repeat:
    send a message
    delay for some suitable time
,

Я полностью согласен с Эдгаром Боне. Вы отправляете от 13 до 15 байт на входной байт. Это требует времени в аппаратном обеспечении, независимо от того, есть ли у вас что-то подключенное к нему или нет. Таким образом, вы ожидаете, что он неправильно прочитает данные после 1/15 размера выходного буфера, который по умолчанию составляет 64 байта., @Nick Gammon

@NickGammon Спасибо, это звучит разумно для меня. Есть ли у кого-нибудь из вас предложения по правильному приему данных и отладке? Должен ли я подключить TX и RX и сделать какое-то подтверждение?, @errolflynn

У меня есть пост [здесь](http://www.gammon.com.au/forum/?id=11329) об отладке с использованием SPI (а также I2C), если у вас есть эти контакты свободны. Это намного быстрее, чем использование последовательной связи., @Nick Gammon

@errolflynn Также уменьшит длину ваших отладочных сообщений, это поможет. Например, вместо "Получено:" отправьте "R"., @Nick Gammon