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 actually 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 really 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 clear the “incoming” buffer, like many people think.  It pauses your program until the transmit buffer is finished.

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 allows your program to keep running, with the transmitting happening in the background.

An easy 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 we 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 may not be an issue or a problem.  However, it is a behavior to know about.  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 clear the output buffer?  This code will do it, which you can put into a function like “flushReceive()” or something equally clever.

  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 transmits 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.

written by

Capacitor Expert by Day, Enginerd at Night. On paper I have a EE which I use to make things blink, beep, and fly. I created and enjoy making the AddOhms Tutorials at addohms.com. You can follow James on Twitter @baldengineer or on Google+.
Related Posts

2 Responses to "When do you use the Arduino’s Serial.flush()?"

  1. Sid Young says:

    How big is the buffer? If you are not connected to a serial device and the code is pumping out text into the buffer what happens if you never connect back up?

    Reply
    • James says:

      Serial UARTs are asynchronous. The transmitting side does not wait for the receiving side to acknowledge a bit or byte has been received. I don’t remember the size of the buffer, but it is probably on the order of 64 or 128 bytes. However, the time it takes to empty that buffer will be constant only limited by the baud rate used.

      Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

©2014 Baldengineer Productions, Inc.