// startEndCharInput.ino // Reads chars between { } into a String, skip the rest // the flushing timeout is set to 0 to disable it in this case // https://www.forward.com.au/pfod/ArduinoProgramming/SoftwareSolutions/index.html // Pros: Simple. Non-Blocking, Robust flushes the input until finds the start, {, then reads until } or timeout or input line limit // Cons: Nothing really, except it is un-necessary in almost all case. 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 = 0; // 1sec set to 0 for no timeout if (!flushing) { // just return return false; } // else 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 } // 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 startChar = '{'; char endChar = '}'; bool flushToStart = true; void loop() { if (flushToStart = flushUntil(flushToStart, startChar)) { // flush until find { } else { // flushing finished read until } if (readStringUntil(input, endChar, 0)) { // read until find } int idx = input.lastIndexOf(endChar); if (idx >= 0) { input.remove(idx); // remove the } Serial.print(F(" got a line of input '")); Serial.print(input); Serial.println("'"); } else { Serial.print(F(" reached limit or timeout without } '")); Serial.print(input); Serial.println("'"); } input = ""; // clear after processing for next line flushToStart = true; // flush until next { found } } }