Hi. I need to read a string from the serial port into a buffer. I intended for the function to time out after a set length of time in case there is no data available and if so, it returns false.
When there is a string in the buffer, it returns true.
The problem is, the function is blocking my main loop, but I want to be able to check buttons, display things, etc. while the serial function is running if it returns false.
The main loop of my program uses this function for input from the serial port and based on which state the main switch statement is in, the string will be used as input to the program.
So I'm basically doing:
void loop() {
checkButtons();
if (readResponse(buffer, 64, SERIAL_TIMEOUT)) {
// do something with the input
}
}
There must be a better way than those two while loops in the readResponse function.
Can anyone suggest an alternative?
The existing code is written for use with char arrays. I didn't want to use String classes for memory fragmentation reasons.
As you point out, the function is blocking, so move the body of the function code into the main loop.
Most people choose to terminate the input string and take action when a CR or other suitable line terminator is reached, rather than use a timeout. But use a timeout if you wish.
Another approach is to rewrite the function so that it returns immediately if no character is waiting to be added to the input string, or continues, then returns a value that indicates whether an entire line was successfully input, or a timeout occurred. An example is the TinyGPS++ library, which reads and interprets a GPS serial stream using non-blocking code.
@jremington: Thanks. I don't really want to add the body of the function to the main loop, though. I'm trying to keep the whole thing modular both for code re-use and ease of maintenance in the future.
I'll bookmark the link though.
Thank you for your advice. I'd forgotten about the TinyGPS++ library.
@koloha: Thanks. That looks like just what I was after.
You took out those two horrible while loops and made the whole thing non-blocking.
The function returns true if there's data or false if there's not. Perfect!
I'm not sure why I had a timeout really. It's not really needed is it?
The only thing that's a bit confusing is the additional Serial.read after you check for CR/LF is that to make sure those chars don't wind up in the buffer the next time the function is called?
Thanks again.
H