Arduino Millis Lesson
2017-10-23 | By All About Circuits
License: See Original Project Arduino
Courtesy of All About Circuits
Delay statements are great, especially in their simplicity. However, they can really complicate things when you’re trying to multitask your Arduino. To work around this problems, forget delay and hop on the millis() train!
BOM:
- Arduino Uno
- LED and 220R resistor
- or Texas Instruments LM2758
Why?
It's relatively easy to just throw a delay statement in whenever you need your microcontroller to briefly pause, but it can be a big setback when you are trying to do other things, such as monitor a button push. As my Arduino skills grew, I decided it was time to drop the delay and learn how to multitask my Arduino. It adds a bit more code to your programs, but it also makes you a more skilled programmer and increases the potential of your Arduino. To do so, you need to learn how to use the "millis()" command.
How?
Delays pause your Arduino's program, making it unable to do anything else during that time period. Rather than pausing your entire program for a specified time, you must learn to count how much time has passed before completing an action. This can be accomplished with "millis()" and a few variables to store your data. To make things easy, start with everybody's first sketch, "Blink." However, instead you will "Blink without Delay."
You’ll begin like any other program, declaring necessary pins or variables, such as your LED on pin 13. You’ll also need an integer to store the LED’s current state. Set this 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 you may want to wait until an action is taken.
"previousMillis" will be used to store the last time your LED blinked. "const long" is also 32 bits and is constant. You need to set this to 1000 and use it as your pause time, measured in milliseconds because you always want to pause for 1000ms. Lastly, 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 you can move onto the loop! Remember, instead of delaying, you want to count how much time has passed since your last blink, which in the case of this project, is 1000ms. If the stated time has passed, it's time to change the state of your LED, either from off to on, or vise versa.
First you will set the unsigned long "currentMillis" equal to "millis()" which puts the current time count in millis. This will help you determine if the difference between current time and previous time has surpassed 1000ms. To do so, say, "if current time minus the previous time your LED blinked is greater than or equal to your assigned value of 1000ms, store the time of the most recent blink as previousMillis." This will help you to 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);
}
}
You can always take it slow and break down the code into smaller, more understandable sections. If you quite there yet, that's okay—it does take practice. If you do understand it and get it working, try adding in a second LED 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!
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum