Arduino: Timing Code with Millis() as a Stopwatch

Since most Arduino boards do not have debug capability, this limits the programmer to using Serial.prints. A useful piece of information might be knowing how long certain parts of code are running. Here’s a simple example that demonstrations:

  1. How to properly use Serial.flush() (hint: it’s for TRANSMIT, not RECEIVE!)
  2. How long Serial.print()s can “tie up” the Arduino.


At 9600 baud, you’ll see that the Arduino is only busy for about 20 milliseconds in the first chunk of code, but busy for 93 milliseconds in the next. That’s because the Arduino (since 1.0) started using a transmit-buffer. Did you know your code doesn’t wait for a Serial.print to finish?

If you aren’t familiar with the F(), read this article on how the F()-macro can help prevent lock-ups.

Experiments to trystopwatch_000018042439

  1. Change the baud rate
  2. Add (or remove) text to see how timing changes
  3. Put delays() after each Serial.print()

The Code

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();

  // Wait until TX buffer is empty and print a seperator
  Serial.flush();
  Serial.println(F("---"));
  Serial.flush();

   // 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();

  Serial.println();  Serial.println();  Serial.println();

  // Print Results for the non-flush calls
  Serial.print(F("Without flush, Serial.println()s return control in: "));
  Serial.print( millisNoFlushStop - millisNoFlushStart);
  Serial.println(F(" milliseconds."));

  Serial.println();

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

  // Stop the code.
  while(1);

}

// This will never get executed.
void loop() {
}

Now that you’ve seen the code, give some the experiments listed a try. Post questions below.

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