Uno Multitasking! How to Use Milli in Uno R3 Code
Delay statements are great and all, especially for their simplicity, but they can really put a damper on things when trying to multitask your Arduino. Forget delay and hop on the millis() train!
BOM:
Why?
It’s pretty easy to just throw in a delay statement whenever you need your microcontroller to pause briefly, but it’s a real bummer when you are trying to do other things, like monitor a button push. As my Arduino skills have improved, I figured it was time to drop the delay and learn to be able to multitask my Arduino. Yes, it does add a bit more code to your programs, but it, in turn, makes you a more skilled programmer and increases the potential of your Arduino. To do so, we will need to learn how to use the “millis()” command.
How?
You see, delays pause your Arduino’s program, making it incapable of doing anything else in that time period. Instead of pausing our entire program for a specified time, we will learn to count how much time has passed before completing an action. This, of course, is accomplished with our good friend “millis()” and a few variable friends to store our data. To make things easy, we’ll start with everybody’s first sketch, “Blink,” but instead we will “Blink without Delay.”
First begin like any other program, declaring any necessary pins or variables, such as your LED on pin 13. We’ll also need an integer to store the current state of the LED. This will be set to LOW as the initial LED state is off. Then declare a variable “previousMillis” of type “unsigned long.” Instead of using “int,” unsigned long variables are 32 bits, for variables whose value can become very large—like the potential amount of time we may want to wait until an action is taken.
“previousMillis” will be used to store the last time our LED blinked. “const long” is also 32 bits but will never change, or is constant. We will set this to 1000 and use it as our pause time, measured in milliseconds because we always want to pause for 1000ms. Then, of course, remember to declare your pinMode for your LED as usual.
// constants won't change. Used here to set a pin number :
const int ledPin = 13; // the number of the LED pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change :
const long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
Then we move onto the loop! Remember, instead of delaying, we want to count how much time has passed since our last blink, in our case, 1000ms. If the stated time has passed, it’s time to change the state of our LED, either from off to on or vice versa.
First, we will set the unsigned long “currentMillis” equal to “millis()” which places the current time count in millis. This will help us determine if the difference between current time and previous time has surpassed 1000ms. To do so we say, “if current time minus the previous time our LED blinked is greater than or equal to our assigned value of 1000ms, store the time of the most recent blink as previousMillis.” This will help us remember how long it’s been since the last blink the next time around the loop.
Then, if the LED state is LOW, make it HIGH, else, make it LOW. Then digitalWrite the LED HIGH or LOW depending on the previous state.
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Remember to take it slow and break down the code into smaller sections that you can more easily understand. If you don’t get it just yet, that’s okay—it takes some practice. If you do understand it and get it working, try adding in a second LED to the mix and get them blinking at different rates. More information on this subject can be found on Adafruit Industries website, where Bill Earl has provided a three-part series on multi-tasking your Arduino—even adding motors and addressable LEDs to the mix so check it out! Thanks again for following along!
Other MIT-i Innovations:
- The Cat-Apult! (an Arduino-controlled servo for makers)
- The Launchpad-Based Laser Tripwire Alarm! (a launchpad security system)
- The Arduino UNIVERSAL Remote Control! (an IR receiver for your entire house)
- The Crop Duster Buster! (a clap-controlled odor-management system)
- The Traffic Light Controller! (an Arduino delay statement lesson)
- The Dancing Ghostbusters Toaster! (a lesson on solenoids and inductive loads)
- The Raspberry Pi Object Detection Cat Toy! (a lesson on the RPi GPIO)
- The Zambroombi! (an object-avoidance robot)
- The Holiday Season Analog Alarm! (a gift-defending system)
- The Santa Cam! (a holiday motion-activated camera)
- The IoT Beaglebone Beagle Treat Dispenser-Feeder! (a poor excuse for automation)
- The Punxsutawney 5000! (an interesting way to avoid the cold)
- The BIG Arduino Piano! (a PWM musical instrument)
- The Trinamic Stepper Motor Drivers! (a stepper motor lesson)
- The Debra 2: An Analog Device’s Soil Moisture Sensor (a live moisture sensor)
- Maxim Integrated’s Sound Activated Rave Goggles (a musical Neopixel application)
- Fruit Drums (a Circuit Playground adventure in music)
- F.U.N. with B.L.E. (STMicro’s Newest BLE Device)