1.01: millis + micros
General Info
What are timing functions? (test)
After last year you may have realized that although the delay() function is easy to use, it has some drawbacks (skip to the Notes + Warnings). If you use delay() in a program it will stop all activity on the Arduino until the delay is finished. You cannot perform any other task at that time period.
The solution to this problem is to use millis() or micros() in your code. Respectively, these functions return the number of milli- or micro-seconds that have passed since the Arduino board is powered up or reset - essentially, the runtime of the current program.
Check In
Which case would it better to use millis() or micros() over delay()?
The millis/micros Overflow Problem
The millis() and micros() both store the current time since the Arduino started, in an unsigned long variable.
On the Arduino Uno, an unsigned long is stored on 4 bytes, or 32 bits. Values for the variable range from 0 to 4,294,967,295 (2^32 – 1).
When you keep incrementing a variable, it will eventually reach the maximum possible value. After this value, the variable comes back to 0. That’s what we call overflowing.
To determine how long it will take to overflow, we use:
(max val of unsigned long) / (# milli/microsecs in 1 sec) / (# secs in 1 hr) / (# hrs in 1 day if nec.)
For millis(): 2^32 / 1000 / 3600 / 24 = 49.7 days
For micros(): 2^32 / 1000000 / 60 = 71.6 minutes
So 71.6 minutes, the value you get from micros() will overflow (reset to zero), and keep incrementing until it reaches the max value again, and again and again. So with just over an hour to overflow, a micros() overflow is very likely. For millis(), it will take more than 49 days, but you still can’t ignore that. We will address the overflow problem in our next tutorial.
When to Use millis() vs micros()
The 2 things to keep in mind are the time resolution, and the duration before an overflow. If your program requires executing actions with a resolution higher than one millisecond, then use micros(). If not, just use millis(), which is significantly less likely to overflow. In this class, we will likely only use millis().
New Vocabulary
Timing Functions
Time since program state in milliseconds: millis()
Time since program start in microseconds: micros()
What it Does
millis() // Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.
micros() // Returns the number of microseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 70 minutes. On the Arduino Uno, this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four).
Syntax
time1 = millis(): sets variable time1 to the time in milliseconds since the program started running
time2 = micros(): sets variable time2 to the time in microseconds since the program started running
Returns
Number of milli- or micro-seconds since the Arduino started running the current program.
Data type: unsigned long
Check In
What is the maximum value in an unsigned long variable?
Example
Example Using micros() and millis()
This example code prints on the serial port the number of milliseconds passed since the Arduino board started running the code itself. To use microseconds, just substitute micros() for millis().
Practice
Practice: Time Flies When You’re Having Fun
Convert the millisecond count to seconds and print the time every second. After 10 seconds, have the program turn on the built-in LED at pin 13 (that LED is onboard - no need to build a circuit!).
Hint: You may want to use a comparison operator to create a condition for the 2nd half of the challenge!
Challenge
Challenge: Blink and You’ll Miss It
Use the millis() function to blink the built-in LED at pin 13.
- The blink should have a 50% duty cycle (equal time on and off)
- The blink should have a frequency of 2Hz (2 on/off cycles per second)
- Do not use the
delay()function
Some Hints:
- Think about the “delay” as the difference in time between the time when the LED state was last changed and the current time and plan your condition(s) accordingly
- You may want to create a variable for the delay between on/off OR for the period of the cycle
Useful but not necessary: Logical Not (!) can flip the HIGH/LOW state of a bool variable (for the state)