How to clear the Serial buffer?

I want a delay that will watch the Serial for keyboard input and break the delay. I found the following delay-part of “myDelay” function and added the “if (Ser…” to suit what I thought it should be.

I started out using “Serial.flush(” as per the Arduino instructions but after a frustrating hour finally found it no longer does what it says it should. OK, so then I went for “break” and that didn’t work, so then this and it still is not clearing the Serial buffer before exiting.

If it is waiting and I enter a single-Serial character it does what I want.
If I enter several characters as in “dddd” it will display four times rapidly indicating the Serial buffer is not empty when it arrives the next time around.

How can I flush the Serial input buffer of characters so that Break means break?

void setup() 
{ Serial.begin(115200);
}
void loop() 
{ myDelay(30*1000);
}
void myDelay(unsigned long ms)
{ unsigned long start = millis();
  Serial.println("waiting");
  do 
  { if (Serial.available())
    { char t;
      do
      { t = Serial.read();
      } while (Serial.available() > 0);
      start = ms;
    }
  } while (millis() - start < ms);
}

Same way you'd flush any buffer - keep reading it until it is empty.

How can I flush the Serial input buffer of characters so that Break means break?

Break always means break. You do, however, actually need to use break somewhere.

The problem is that the simple code while(Serial.available()) {Serial.read();} runs so much faster than serial. It can't know that there is a serial character part-way through transmission because the Serial system only knows after the character has fully arrived.

You could throw a delay in there but that is only useful for a very short demo program. A real program has work to do, like driving a motor and checking it hasn't hit its end stop.

So if you want to have one letter start some action and then ignore the carriage-return-linefeed following it, you need to check the serial buffer for some milliseconds after the first character arrives and recognize that these characters aren't needed to do any other action.

This kind of user interface code rapidly gets messy and there's no way to make it not messy. User interfaces just have to be like that.

Have a look at Serial Input Basics

...R

This kind of user interface code rapidly gets messy and there's no way to make it not messy.

Of course, if the idea is to throw the carriage return and line feed away, it is better to just not send them.

AWOL:
Same way you'd flush any buffer - keep reading it until it is empty.

That's what I was trying to do with the "do-while"

Do you people actually give help anymore or just offer up snide comments?

Since my code isn't working AND I posted all the code to avert the inevitable ("we can't know without the code") cheap shots, I was vainly hoping for a remedial code snippet or correction.

I had tried "break" in place of the "start = ms;" to no avail. Hell, I even got so desperate I tried a "goto" approach.

@PaulS:
Reading back a few years here, you used to be very helpful. I am a moderator on a Mechanical Engineering forum so I know how repetitive some questions can be, but rest assured I spent several hours and a lot of searching before asking here. But, alas, all to no useful avail - again.

I have read quite a few unkind reports on these forums written by people struggling to grasp Arduino's weird interpretations of C/C++. I say "weird," as the Support page for Serial.flush() shows what should do exactly what I need, but apparently (as I read) it's working functionality has been changed.

People programming Arduinos are mostly hobbyists who are learning by trial and error. Spending six months learning C/C++ before plugging anything into a USB port is not on their calendar and they should not be discouraged or punished as a result.

We all had to learn everything at one time. So practical consideration to a small plea for fairer treatment to all, might be a nice thing. We all should be doing as much as we can to help others along rather than mostly chest thumping to try and indicate how stupid they are for needing to ask.

Well, IF I am correct thinking this is a help forum.

1 Like

I read your first post, I cannot understand what you are trying to accomplish.

Can you explain what you want to happen when a char is read over serial?

do
      { t = Serial.read();
      } while (Serial.available() > 0);

Even if there's nothing to read, read it anyway, then see if there's something there to read.

I admit, I was puzzled, by all the time-related stuff, and if you were trying to flush the serial buffer, why you were doing it in something with "delay" in its name.

Probably the smarter thing to do, if I understand your problem, would be to not throw all the data away. Instead, save a variable with what you read last. When you read the next character if it is the same as the last one you read then do nothing (throw it away) but if it is different then act on it. That would save you from potentially throwing away something that you might care about.

WaitSome:
Do you people actually give help anymore or just offer up snide comments?

I don't see the snide comments.

#1 gives you a very succinct answer to your question.
#2 Answers one of your side questions and gives you a valuable clue
#3 Gives you a very good description of why your method isn't working and what you could do to solve it
#4 Points you to a tutorial that could be invaluable if you would read it
#5 Gives you another alternative to solving your problem
#6 Is you whining about some snide comment that I just don't see anywhere
#7 Is asking for more clarification of the problem since you seem to not like the answers you've got so far
#8 Points out a flaw in your logic that you could correct and probably get better results
#9 Gives you yet another way to solve the problem and avoid another potential problem hiding in your original solution

What part was snide or ugly? I've seen that sort of thing around here, but certainly not on this thread.

WaitSome:
I say "weird," as the Support page for Serial.flush() shows what should do exactly what I need, but apparently (as I read) it's working functionality has been changed.

Which "Support" page are you looking at?

https://www.arduino.cc/en/Serial/Flush

flush()

Description

Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.)

AWOL:

do

{ t = Serial.read();
     } while (Serial.available() > 0);



Even if there's nothing to read, read it anyway, then see if there's something there to read.


I admit, I was puzzled, by all the time-related stuff, and if you were trying to flush the serial buffer, why you were doing it in something with "delay" in its name.

This is an old thread, but no need to start a new one. I'm a cautious type and don't like the idea of doing a Serial.read() if there might not be anything to read. So I added an if (I've shown it all, and it's for Wire):

void receiveEvent(int howMany) {
  while (Wire.available()) {
    h10 = Wire.read();
    hU = Wire.read();
    min10 = Wire.read();
    minU = Wire.read();
  }
  if (Wire.available()) {        // clears out any junk
    do {byte junk = Wire.read();}
    while (Wire.available() > 0);
  }
  hours = h10*10 + hU;
  minutes = min10*10 + minU;
  
Serial.print(hours); Serial.print(" : "); Serial.println(minutes);
}

Of course, we should really be using the supplied int 'howMany', but I haven't got my head round that yet.

Of course, we should really be using the supplied int 'howMany', but I haven't got my head round that yet.

Or ditch the do/while statement that always executes the body at least once, in favor of a while statement that is smart enough to check first.

If you wrote it as a while and not a do-while then there would be no need for the if since the while would check first. Not that there's anything wrong with calling read when nothing is there. It just returns -1 in that case.