Hi, I am was wondering if there is a way the read ONLY the last info sent in the Serial communication.
I am testing with 2 Boards and RS-485. I don't want my Serial to overflow so I don't want to send the same information twice (or more) in a row. I only want to send a piece of info trough the Serial when a change of state occurs.
I only want to send a piece of info trough the Serial when a change of state occurs.
So what is the problem ?
Test the state and compare it with the state the previous time you checked
If it has changed then send the message and save the state to a variable ready to check for a change next time
I think you are asking about flushing your RX buffer so you only read the last data?
There is a long version and a short version. In the short version, just call sfReader.skipToDelimiter(); whenever you want to clear the RX buffer upto the next delimiter OR until no more data received for the timeout period
Long version
// flushingInput.ino
// Reads chars into a String until newline '\n'
// https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/index.html
// Pros: Simple. Non-Blocking, Robust flushes the input until timeout or find a termination, until_c, char
// Cons: Nothing really.
String input;
// returns true if still flushing, else false if flushing finished either by finding until_c char or by timeout
bool flushUntil(bool flushing, char until_c) {
static bool timerRunning; static unsigned long timerStart; // timeout static variables
static const unsigned long timeout_mS = 1000; // 1sec set to 0 for no timeout
if (!flushing) { // just return
return false;
} // else
if ((timeout_mS > 0) && (!timerRunning)) { // only start if we have a non-zero timeout
timerRunning = true;
timerStart = millis();
}
while (Serial.available()) {
timerRunning = false; // set true below if don't return first
char c = Serial.read();
if (c == until_c) {
return false; // not flushing any more
}
// restart timer running
if (timeout_mS > 0) { // only start if we have a non-zero timeout
timerRunning = true;
timerStart = millis();
}
}
if (timerRunning && ((millis() - timerStart) > timeout_mS)) {
timerRunning = false;
return false; // not flushing any more
}
return true; // still flushing
}
void setup() {
Serial.begin(9600);
for (int i = 10; i > 0; i--) {
Serial.print(' '); Serial.print(i);
delay(500);
}
Serial.println();
Serial.println(F("flushingInput.ino"));
input.reserve(20); // expected line size
bool stillFlushing = true; // start flushing
while ((stillFlushing = flushUntil(stillFlushing, '\n'))) {
// loop here until input is emptied or find a newline
}
// stillFlushing == false here
Serial.println(F(" Finished flushing Input"));
}
// read Serial until until_c char found or limit char read or timeout, returns true when found/limited else false
// non-blocking, until_c, if found, is returned as last char in String, updates input String with chars read
bool readStringUntil(String& input, char until_c, size_t char_limit) { // call with char_limit == 0 for no limit
static bool timerRunning; static unsigned long timerStart; // timeout static variables
static const unsigned long timeout_mS = 1000; // 1sec set to 0 for no timeout
while (Serial.available()) {
timerRunning = false; // set true below if don't return first
char c = Serial.read();
input += c;
if (c == until_c) {
return true;
}
if (char_limit && (input.length() >= char_limit)) {
return true;
}
// restart timer running
if (timeout_mS > 0) { // only start if we have a non-zero timeout
timerRunning = true;
timerStart = millis();
}
}
if (timerRunning && ((millis() - timerStart) > timeout_mS)) {
timerRunning = false;
return true;
}
return false;
}
char terminatingChar = '\n';
void loop() {
if (readStringUntil(input, terminatingChar, 20)) { // read until find newline or have read 20 chars, use 0 for unlimited no chars
if (input.lastIndexOf(terminatingChar) >= 0) { // could also use check if (input[input.length()-1] == terminatingChar) {
Serial.print(F(" got a line of input '")); Serial.print(input); Serial.println("'");
} else {
Serial.print(F(" reached limit or timeout without newline '")); Serial.print(input); Serial.println("'");
}
input = ""; // clear after processing for next line
}
}
Or the short version
// SafeStringReader_timeoutFlushing.ino
// Reads chars into a SafeString until newline '\n'
// uses line limit, timeout and input flushing
// https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/index.html
//
// download SafeString library from Arduino library manager
// or from the tutorial page
// https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
//
// Pros: Minimal Code. Non-Blocking, Robust flushes any initial partial input, if skipToDelimiter() called in setup().
// Skips un-expected long input lines (missing terminator).
// Returns un-terminated input, if a timeout is set. Option echoOn() setting to echo all input.
// Cons: Nothing really, except needs SafeString library to be installed.
#include "SafeStringReader.h"
createSafeStringReader(sfReader, 20, "\r\n"); // a reader for upto 20 chars to read lines terminated by \r or \n or nothing
void setup() {
Serial.begin(9600);
for (int i = 10; i > 0; i--) {
Serial.print(' '); Serial.print(i);
delay(500);
}
Serial.println();
Serial.println(F("SafeStringReader_timeoutFlushing.ino"));
//SafeString::setOutput(Serial);
sfReader.setTimeout(1000); // set 1 sec timeout
sfReader.skipToDelimiter(); // flush initial data until either find delimiter or timeout
sfReader.connect(Serial); // read from Serial
}
void loop() {
if (sfReader.read()) { // got a line or timed out delimiter is NOT returned
if (sfReader.hasError()) { // input length exceeded
Serial.println(F(" sfReader hasError. Input overflowed and skipped to next delimiter."));
}
if (sfReader.getDelimiter() == -1) { // no delimiter so timed out
Serial.println(F(" timeout without newline or carrage return"));
}
Serial.print(F(" got a line of input '")); Serial.print(sfReader); Serial.println("'");
// no need to clear sfReader as read() does that
}
}