When do you use the Arduino’s Serial.flush()?

In the Arduino library, the Serial object has a method called “flush().”  Often users go throwing it into programs without fully understanding what it does. It doesn’t help that it’s functionality changed when version 1.0 of the Arduino IDE was released.

Does Serial.flush() affect the Transmit Buffer or the Receive Buffer and when do you need to use it?

What does Serial.flush() do?

From the Arduino reference for Serial.flush (found on this page):

Waits for the transmission of outgoing serial data to complete.

The key to that statement is “outgoing”.   Serial.flush() doesn’t empty the “incoming” buffer as many people think.  It pauses your program while the transmit buffer is flushed.

Serial.print() / Transmits Are Interrupt Based

Something you may not realize is that when you issue a Serial.print(), that function returns almost immediately.  Instead of waiting until the string has been transmitted, print() sets up a buffer for the string, and then is transmitted via interrupts one character at a time.  This method allows your program to keep running, with the transmitting happening in the background.

A simple way to see this behavior is to send long sentences and time them,  like in the next section.

The difference between flush() and no flush()

Borrowing code from the millis() as a stopwatch example, we can see the difference between using flush() or not using flush() when sending data over Serial.

The Code Without a Flush

void setup() {
  // Give some time to open serial monitor after programming
  delay(2500);
  Serial.begin(9600);

  // Store the current time (start the clock)
  unsigned long millisNoFlushStart = millis();
  // Transmit some psuedo-random text
  Serial.println(F("How long will it take to transmit the following:"));
  Serial.println(F("abcdefghijklmnopqrstuvwxyz"));
  Serial.println(F("done"));
  // Store the current time (stop the clock)
  unsigned long millisNoFlushStop = millis();
  Serial.print(F("Without flush, Serial.println()s return control in: "));
  Serial.print( millisNoFlushStop - millisNoFlushStart);
  Serial.println(F(" milliseconds."));
}
void loop() {}

Results

So this code is “done” in 20 milliseconds.  This sounds pretty good, right?  Okay, let’s look what happens if you call Serial.flush() before counting the time.

The Code WITH a Serial.flush()

void setup() {
  // Give some time to open serial monitor after programming
  delay(2500);
  Serial.begin(9600);

  // Store the current time (start the clock)
  unsigned long millisWithFlushStart = millis();
  // Transmit the same psuedo-random text as before
  Serial.println(F("How long will it take to transmit the following:"));
  Serial.println(F("abcdefghijklmnopqrstuvwxyz"));
  Serial.println(F("done"));
  // This time, let TX buffer flush before "stopping" the clock
  Serial.flush();
  // Store the current time (stop the clock)
  unsigned long millisWithFlushStop = millis();

  // Print results for flushed calls
  Serial.print(F("WITH flush, Serial.println()s return control in: "));
  Serial.print( millisWithFlushStop - millisWithFlushStart);
  Serial.println(F(" milliseconds."));
}

void loop() {
}

Results

Just by adding a Serial.flush() line, now the same code takes almost 90 milliseconds to complete!  That’s 4.5 times longer.  This difference in time may not be an issue or a problem.  However, it is a behavior to understand.  If you want your code to wait for a serial string to be finished sending, you need to make use of Serial.flush().

How do you clear the incoming Serial buffer?

Since the flush() method only clears the transmit buffer, how do you empty the receive (or incoming) buffer?  This code will do it, which you can put into a function like “flushReceive()” or something equally amusing.

  while(Serial.available())
    Serial.read();

Conclusion

For most programs, the transmit buffer is a good thing.  It’ll keep your Arduino from getting tied up waiting for Serial transfers to finish.  However, if you have critical timing mixed in with Serial.print()s, you need to keep in mind that your timing might change.  That’s where the Serial.flush() comes into play.  It gives you a chance to wait until all Serial.print()ing is done.

Long comments, URLs, and code tend to get flagged for spam moderation. No need to resubmit.

ALL comments submitted with fake or throw-away services are deleted, regardless of content.

Don't be a dweeb.

Leave a comment

47 thoughts on “When do you use the Arduino’s Serial.flush()?

  1. An unorthodox method to clear (instantly!) incoming serial buffer is to disable receiver by clearing RXENn bit of UCSRnB register; where n is Serial id
    eg. bitClear(UCSR0B, RXEN0);
    enable it back… et voila!
    You win time; you loose safety