// flushingInput.ino // Reads chars into a String until newline '\n' // https://www.forward.com.au/pfod/ArduinoProgramming/SerialReadingParsing/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, see Taming Arduino Strings // https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html 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 } }