1

I am just playing with the UART interface of my board to learn about how it works. Since I have only one board, I send data out just to receive them by my own board, which is working so far.

Now I wanted to find out what Serial.setTimeout() is for. As per description on the Arduino homepage, it sets the maximum time for to wait for data. The description says, upon others Serial.find() will use it.

So I set Serial.setTimeout() to 100ms, and between sending and trying to receive data, I put a delay of 500ms. Therefore my expectation would be, Serial.find() will not detect a message, since there is more than 100ms no traffic on the bus. But I am still recieving data, it seems that the Serial.setTimeout() has no effect.

What is wrong in my understanding/usage of Serial.setTimeout()?

Here is my example sketch:

#include <M5Stack.h> // needed for my board M5Stack

HardwareSerial Serial2(2); // R2: Recieve Serial2, 17: Transmit Serial2  --> connnect pin R2 and 17

unsigned char buf_recive[1];
unsigned char buf_transmit[2] = {0x42, 0x00};

void setup()
{
  M5.begin();
  Serial.begin(9600);    // setting baud rate for COM3
  Serial2.begin(9600);   // setting baud rate for M5Stack2M5Stack communication
  Serial2.setTimeout(100);    //set the Timeout to 100ms
}

void loop()
{
  delay(500);
  // send buf_transmit
  Serial2.write(buf_transmit, 2);
  delay(500);
  // detect first byte of recieve message
  if (Serial2.find(0x42))
  { //start to read when detect 0x42
    Serial2.readBytes(buf_recive, 1);
    Serial.println(buf_recive[0]);
  }
  buf_transmit[1] = buf_transmit[1] + 0x01; // just to see that something's going on
}

And here some prove, that I am still receiving data:

enter image description here

0
1

The bytes are received to rx buffer with interrupt in the core. The find() function finds them there after the 500 millis delay. Timeout is to wait for the next byte if the rx buffer is empty.

The timeout is good if you know that the other side sends a collection of characters or bytes. Like for example a line sent from Serial Monitor or a Http request on networking client. The transmition has small gaps between bytes, but you want to receive it at once. So a function waiting a little for the next byte is useful.

Serial, networking Client classes and other Arduino stream classes inherit reading functions from the Stream class. This class has all the read and parse functions. There are 3 non blocking functions available, read and peek. All other read and parse functions use the timeout and wait for the next byte if the rx buffer is empty.

try this sketch with Serial Monitor

void setup() {
  Serial.begin(115200);
  Serial.setTimeout(10000);
}

void loop() {
  if (Serial.available()) {
    String s = Serial.readString();
    s.trim();
    Serial.println(s);
  }
}

send a line from Serial Monitor. a couple of characters. then send fast another line and then wait longer then 10 secs and send one more.

6
  • I tried this by changing Serial2.write(buf_transmit, 2); to Serial2.write(buf_transmit[0]); delay(200); Serial2.write(buf_transmit[1]);, which should simulate the gap between the bytes, but I am still receiving, obviously I have still not understood. Do you have a hint what I am doing wrong?
    – RJPlog
    Mar 30 '19 at 16:51
  • gap yes, but you read the rx buffer after both writes were received to rx buffer. you can't simulate it with one MCU
    – Juraj
    Mar 30 '19 at 16:59
  • you can test it with Serial Monitor.
    – Juraj
    Mar 30 '19 at 17:06
  • ok, doing it on one device seems stupid. Any idea how I could set a timeout on the Serial Monitor?
    – RJPlog
    Mar 30 '19 at 17:29
  • 1
    I added a test to answer
    – Juraj
    Mar 30 '19 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.