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. So serial.print() followed by serial.flush() cause some delay. can we control this delay by serial.setTimeOut(). Because I have a watchdog timer, and I dont want this delay to trigger the watchdog timer. thanks

  2. The article discusses print(), without mentioning write() — this leaves few questions in fog: is described output buffering feature related to print() only (and not write() ) or author mentions print() only, assuming that great majority of prefers print() over write()? It would be good to provide clarification on this.

  3. Hi Mr.Lewis, Great Information But how do I make my BT Master and slave communication effective,like soft real time. Thanks from germany – Vipul

  4. I think it is important to stress that flush() means the content of the stream is transferred to the stream output until the stream is empty. It is not about clearing or getting rid of. It is just to force the accumulated data in the stream to move on to the output.

  5. Great stuff James, found this discussion while looking for solutions to a problem I am having using Serial.print.

    I am using Serial.println to debug some simple code:

    digitalWrite(redpin, HIGH);  // set the red LED on
     Serial.println("Red");  
    delay(1000);
    

    But, if I put in three sets of this sequence as in driving three different LEDs, it will not compile (Verify). I get this error –

    Arduino: 1.6.8 (Windows XP), Board: “Arduino Nano, ATmega328”
    (lotta other stuff in here…..)
    collect2.exe: error: ld returned 5 exit status

    exit status 1
    Error compiling for board Arduino Nano.

    If I comment out any one of the Serial.println lines it compiles fine.
    Any suggestion on what I am doing wrong??

      • This is the whole sketch.

        const int redpin=11;
        const int bluepin=10;
        const int greenpin=9;
        void setup() {                
          // initialize the digital pin as an output.
          // Pin 13 has an LED connected on most Arduino boards:
          pinMode(greenpin, OUTPUT);   
          pinMode(bluepin, OUTPUT); 
          pinMode(redpin, OUTPUT); 
          Serial.begin(9600);
        }
        
        void loop() {
          digitalWrite(greenpin, LOW);  
          digitalWrite(bluepin, LOW); 
          digitalWrite(redpin, HIGH);  // set the red LED on
          Serial.println("Red");    
           delay(1000);              // wait for a second
          digitalWrite(greenpin, LOW); 
         digitalWrite(bluepin, LOW);
         digitalWrite(redpin, LOW); // set the LED off
          delay(1000);              // wait for a second
          digitalWrite(greenpin, LOW);  
          digitalWrite(bluepin, HIGH); // set the blue LED on
          digitalWrite(redpin, LOW);  
          Serial.println("Blue");
         
          delay(1000);              // wait for a second
          
          digitalWrite(greenpin, LOW); 
          digitalWrite(bluepin, LOW);     // set the LED off
          digitalWrite(redpin, LOW); 
          delay(1000);              // wait for a half second
          
          digitalWrite(greenpin, HIGH);   // set the green LED on 
          digitalWrite(bluepin, LOW); 
          digitalWrite(redpin, LOW);
          Serial.println("Green LED is on.");
          delay(1000);              // wait for a second
          digitalWrite(greenpin, LOW);  // set the LED off
         digitalWrite(bluepin, LOW);
         digitalWrite(redpin, LOW);
          delay(1000);              // wait for a second
        }
        
        • I don’t see any issues and it compiles fine for me. It is possible there is a stray non-visible character somewhere throwing off the compiler (well actually the linker). It is more likely something is wrong with your install. I would try re-installing the IDE. Maybe even try a version older just to see if anything changes.

          • Thanks for your help James. I will try your suggestions and will report back what I find. I have done quite a bit of cut and paste from other sketches I have built, so some stray characters may have crept in.

            Wes

          • Sketch compiled fine in 1.0.6. I uninstalled and then re-installed 1.6.8, still no joy. Installed latest version 1.8.4 and it compiled the sketch just fine. Machine is WXPSP3, so kinda old. But, I am now back on track. At least for now. Thanks James, as always, a big help.

            Wes

  6. Hi
    Greetings!
    The code:
    while (Serial.available())
    Serial.read();

    is also not working as in case of blinking of a Led when we give a bunch of strings it displays invalid for a no. of times.
    Kindly help me with the alternative code to flush the values.

    Thanks in advance

  7. hi
    i have a serial communication ,i should catch 32 bit from my hall encoder, i use if(serial.available()>=4);
    the arduino(mega 2560) wait for it till catch all data and then the main loop take a long time to run(20 times in each sec.), i need it to be faster than it !! any suggestions??!!
    TNX

  8. Hi James,

    Brilliant website! Has been massively helpful in getting me up to speed with my Arduino projects. However, I have one major issue with my work that I’m wondering if you can help me to understand. Every time I re-upload a new sketch to the Arduino I get a load of garbage in the transmit buffer. I’ve tried using the Serial.flush() statement in my setup loop (with a view to clearing it the first time it runs.) As a double measure I’m also reading the serial bus on my bluetooth receiving device (mobile) and clearing the serial buffer read string to = “” (on screen initialization)…. but whenever I open my app and connect for the first time after a new sketch is uploaded the same thing happens. Typically it crashes the app with a series of dingbat type symbols… but next time I reopen the app it runs fine.

    Any tips for which device needs to be instructed to clear, and how best to achieve this. I’ve tried putting flushes and clear read buffer at all points in my program but nothing seems to work. Seems really odd – almost like the bluetooth module holds data in between.

    • If you’re having hang-ups or other issues it isn’t because of the strange characters in the buffer. The strange characters are a symptom of whatever the actual problem is.

      The Bluetooth module probably has its own buffer (and so does the PC). Don’t connect your PC (Arduino’s USB Port) and Bluetooth module to the same Serial pins.

      In UART/serial communications, there is almost never any time you need to empty a buffer. Either side’s software should be able to handle any data it receives. In fact, the primary reason for the Serial.flush() isn’t to empty the buffer but to let you know that all characters have been transmitted. (Which is why its behavior changed in Arduinio 1.0.There is almost never a good reason to “empty” the receive buffer either.)

      You have another issue with your setup, it isn’t because of extra characters. Could be a wiring, power, or software issue.