Как использовать Serial.setTimeout()
Я просто играю с интерфейсом UART своей платы, чтобы узнать, как он работает. Поскольку у меня только одна плата, я отправляю данные только для того, чтобы получить их на своей собственной плате, которая пока работает.
Теперь мне хотелось узнать, для чего нужен Serial.setTimeout(). Согласно описанию на домашней странице Arduino, оно устанавливает максимальное время ожидания данных. В описании сказано, что в других случаях Serial.find() будет его использовать.
Поэтому я установил для Serial.setTimeout() значение 100 мс, а между отправкой и попыткой получения данных я установил задержку в 500 мс. Поэтому я ожидаю, что Serial.find() не обнаружит сообщение, поскольку трафик на шине отсутствует более 100 мс. Но я все еще получаю данные, похоже, Serial.setTimeout() не имеет никакого эффекта.
Что не так в моем понимании/использовании Serial.setTimeout()?
Вот мой пример скетча:
#include <M5Stack.h> // нужно для моей платы M5Stack
HardwareSerial Serial2(2); // R2: получение Serial2, 17: передача Serial2 --> соедините контакты R2 и 17
unsigned char buf_recive[1];
unsigned char buf_transmit[2] = {0x42, 0x00};
void setup()
{
M5.begin();
Serial.begin(9600); // установка скорости передачи данных для COM3
Serial2.begin(9600); // установка скорости передачи данных для связи M5Stack2M5Stack
Serial2.setTimeout(100); //устанавливаем тайм-аут на 100 мс
}
void loop()
{
delay(500);
// отправляем buf_transmit
Serial2.write(buf_transmit, 2);
delay(500);
//обнаружение первого байта полученного сообщения
if (Serial2.find(0x42))
{ //начинаем читать, когда обнаруживаем 0x42
Serial2.readBytes(buf_recive, 1);
Serial.println(buf_recive[0]);
}
buf_transmit[1] = buf_transmit[1] + 0x01; // просто чтобы увидеть, что что-то происходит
}
И вот некоторые доказательства того, что я все еще получаю данные:
@RJPlog, 👍2
1 ответ
Лучший ответ:
Байты поступают в буфер rx с прерыванием в ядре. Функция find() находит их там после задержки в 500 миллис. Таймаут — ожидание следующего байта, если буфер приема пуст.
Тайм-аут хорош, если вы знаете, что другая сторона отправляет набор символов или байтов. Например, строка, отправленная из Serial Monitor, или запрос Http на сетевом клиенте. Передача имеет небольшие промежутки между байтами, но вы хотите получить ее сразу. Поэтому функция, немного ожидающая следующего байта, полезна.
Последовательные, сетевые клиентские классы и другие классы потоков Arduino наследуют функции чтения от класса Stream. Этот класс имеет все функции чтения и анализа. Доступны 3 неблокирующие функции: доступны
, чтение
и просмотр
. Все остальные функции чтения и анализа используют таймаут и ждут следующего байта, если буфер rx пуст.
попробуйте этот скетч с помощью Serial Monitor
void setup() {
Serial.begin(115200);
Serial.setTimeout(10000);
}
void loop() {
if (Serial.available()) {
String s = Serial.readString();
s.trim();
Serial.println(s);
}
}
отправьте строку из Serial Monitor. пара символов. затем быстро отправьте еще одну строку, затем подождите более 10 секунд и отправьте еще одну.
- В чем разница между библиотеками Software Serial? Какая из них совместима с Arduino Nano?
- Отправить структуру через Serial
- Может ли Arduino Leonardo одновременно использовать USB-порт и последовательные контакты RX TX?
- Последовательная связь между несколькими устройствами (или ардуино)
- как отправить данные в Adafruit Bluefruit Feather (32u4) через Bluetooth?
- Arduino UART (TX/RX) multidrop 1 master 50 slaves
- Когда дело доходит до связи UART-RS485, в чем разница между модулем "MAX485" и модулем "HW-0519"?
- Двоичный в десятичный с использованием побитовых операторов
Я попробовал это, изменив
Serial2.write(buf_transmit, 2);
наSerial2.write(buf_transmit[0]); задержка(200); Serial2.write(buf_transmit[1]);
, который должен имитировать разрыв между байтами, но я все равно получаю, очевидно, я еще не понял. Есть ли у вас подсказка, что я делаю неправильно?, @RJPlogпробел да, но вы читаете буфер rx после того, как обе записи были получены в буфер rx. вы не можете смоделировать это с помощью одного MCU, @Juraj
вы можете проверить это с помощью Serial Monitor., @Juraj
ок, делать это на одном устройстве кажется глупым. Есть идеи, как установить тайм-аут на последовательном мониторе?, @RJPlog
Я добавил тест для ответа, @Juraj
Спасибо, этот тест очень помог в понимании. Теперь я также понял, почему не работает ни с одним MCO., @RJPlog