Post navigation

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?

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.

Disclosure of Material Connection: Some of the links in the post above are “affiliate links.” This means if you click on the link and purchase the item, I will receive an affiliate commission. Regardless, I only recommend products or services I use personally and believe will add value to my readers. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: “Guides Concerning the Use of Endorsements and Testimonials in Advertising.”

I mean to say how can one handle such an issue when it comes to communicating with a Bluetooth module. I am currently trying to communicate between 2 hc-05 bluetooth modules, and there a lot of time lag.

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.

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.

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.

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

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.

I have a very interesting problem for you i wonder if you might like put some light on the subject I’m using a HC05 blue-tooth module using the software serial calls on an Arduino UNO and I have found something quite strange with this Ive written the application for my mobile in android and a simple application for the Arduino It works fine connects at 9600 baud and uses default settings for stop bits etc

I am simply turning on and off an led via the ports of the Arduino on receiving correct commands via bluetooth TX and RX

Here is the problem Its a very perplexing but interesting problem and suggest that there is either a bug in the hardware itself or the initial serial routines haven’t been set properly

I can obviously use both hardware ports and a virtual software port at the same time also works but there is a big huge question mark over this

The only time the software or hardware serial port will respond to the blue tooth module is if I send a character doesn’t matter what character to the hardware port first There after this all works A ok responds to bluet-tooth data transfers and activates the LED

What could I be doing wrong do you think

Ive got past the problem , however Im not saying to much about the solution because in my mind I shouldn’t have to do this but i have to use additional components to solve the problem I just would like to know what you think about this and why the atmel 323p or arduino uno does this

Hi, I found this article very useful in trying to debug the serial communication to create a constant transfer per second. Unfortunately, it still creates a periodic burst of different transfers. Using the very basic code:

sends most of the data thru at 137 lines per second. About 6% of the time (not an insignificant number when trying to collect specifically timed data) the data transmits at 141 or 142 sets of “00000” per second, which is 35 characters more per second.

I added Serial.flush(); after the println, hoping that would make things stable, but now it seems that every 25 seconds there is a drop in the transfer down to 133 lines (sets of “00000”) per second.

I’m using a python script to read the serial and write to a file, so i’m at a loss to understand if it is the python script or the Arduino serial.

Considering the problem went from excess data without the flush to “missing” data with the flush, it would seem that the Arduino would be the likely cause.

The Arduino is a real-time system and is not likely the issue of the bursting, on its own. The issue is either a) your Arduino code or b) something on the PC side (the driver, the OS, the language’s stack, etc… way more things to go “wrong.”).

Serial.flush() changing the behavior suggests whatever else the rest of your Arduino code is doing, isn’t allowing the Serial’s transmit buffer to “stay full.” I’d look closer at what the rest of your code is doing and make sure it isn’t either blocking events filling the transmit buffer OR that it isn’t filling so quickly that the ISR sending serial characters is pausing.

The intent of the experiment was to determine if Arduino serial communication could be used, reliably, to collect timed sample data vs buying an expensive DAQ system. The 2 line code above is the complete code. I made sure to strip everything else out just to monitor the data streaming.

9600 was used to get a baseline, and if 9600 has timing issues then it follows that any higher bitrate also has timing issues to varying degrees.

Other suggested solutions to the timing problem were to add a timestamp to the serial output to mark when the data was taken, using millis() for example, vs when the data was received in the data file, trying to eliminate any bottlenecks. That solution works pretty well up to a point, until the length of runtime makes millis() a very long number (greater than 3 hours, for example) and then the overhead of sending time along with the data slows things down a bit.

Ultimately, the fact that getting from the Arduino to an external data file has variable time steps eliminates it from heavy duty data collection work for me.

You misunderstand my comment about going faster than 9600. It isn’t a “timing issue.” It’s math. You may be putting more data into the buffer than 9600 can transmit. When the transmit buffer is full, Serial.print() will pause until the entire string passed to it can be placed into the transmit buffer. While I would expect that to mean your Arduino continue to stream without interruption, it could give unpredictable results depending on what the rest of your code does. So in that case either fill the buffer slower or transmit the data faster. Or secret option #3, don’t send ASCII data use Serial.write() and send binary data instead.

All that said, the Arduino isn’t going to be the issue. PC operating systems seem to buffer Serial Data / Virtual COM Ports, making them difficult to use for a real-time application without timestamps.

To get around your sending millis() as a timestamp you have two options: 1) Pad the string so the amount of data sent is always the same (like with sprintf()) or 2) Use Grey Code and only send difference between stamps (that’s how logic analyzers usually stamp their data.)

Thanks. This is really informative. I am using an Arduino Uno with a HC-06 to send the times at which a simple switch is pressed to my PC. Works fine except there are delays in receiving the data sometimes lasting 10 ore more seconds and then it starts flowing again. The data will be received fine with no delay between switch change and data arriving at the PC but then data will stop halfway through a data string, seemingly frozen for 3-12 seconds, and then in a burst the rest of the data comes through?

The problem does not occur when I send data over the USB port – only for Bluetooth.

Does the HC-06 have a buffer? Is there anyway to force it to continue to transmit? Thanks

The Code for clearing the Input Buffer is wrong as a lot of copies in the Net. Arduino is way faster than the data arrives. So Serial.available() could be < 1 before all data is there and the while loop is finished before. I wonder why such a fail is widespreaded in the net.

No, the code for clearing the buffer is 100% correct. Your understanding of when to use it is wrong (which limits the fail to a single person.). How do you know when “all the data is there”? Unless your byte-level protocol has a method for identifying when a transmission is complete, you will never know when “all the data is there.” Clearing the input buffer does just that, empties whatever data is in the buffer at the time the while-loop runs.

But that is not that what most users want. If I broadcast some Data and all Clients but one should discard the data then this code won’t work. It has absolutely no use then. When should I use your code? The same wrong assumption is the while (available > 0) { read }. If there is no data and it will be, than the loop will end before all data ist there. My solution for this is to send the first Byte with the number of all next bytes. The only way for me not to send the data as a char string and to spare bytes which are used for comma separation.

Serial in Arduino projects is usually a peer to peer communication. You’re over complicating a simple request people have. While you probably make valid points for your corner case, they don’t apply here.

If you’re doing a straight serial read, then you’re also reading the header and trying to print meaningless (to us) data.

If you expect the header data to be stripped off by the H/W, make sure you have compatible devices or do it yourself in S/W. There’s ACL, SCO, LMP, HCI, SDP, SMP and a whole bunch of other TLAs that packetize the data you’re transmitting that, under normal circumstances, we never see. If you examine the ISO/OSI stack, serial.read deals with the physical and data link layers while bluetooth rides up a couple of layers higher.

Hi, please move inputString=””; before while(….). InputString needs to be initialized in order your += expression to work. Otherwise the system is picking up some garbage for the initial value of the inputString.

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.

About Me

With 15 years of experience in electronics, marketing, sales, and teaching I boil seemingly difficult concepts down to the core, so that anyone can learn what they need to finish that next great project.