Как использовать 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; // просто чтобы увидеть, что что-то происходит
}

И вот некоторые доказательства того, что я все еще получаю данные:

, 👍2


1 ответ


Лучший ответ:

3

Байты поступают в буфер 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 секунд и отправьте еще одну.

,

Я попробовал это, изменив 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