You’ve recently learned about millis() and can’t way to delete all of your references to delay(). The problem is that you don’t know quite how to convert your code into millis()-compatible code. Here is a (running) list of millis() examples I’ve put together to help.
Baldengineer’s Arduino millis() Examples
- Arduino Multitasking – Step by step examples of how to convert delay() code into millis() based code, to simulate multitasking.
- Police Lights – Flash two LEDs like strobing police lights
- Control ON and OFF time for a flashing LED. – More control than “blink without delay”
- Stopwatch Example – Calculate how much time code takes to execute
- Chasing LEDs – Larson-scanner style chasing pattern
- De-bounch a button (or switch) – No need for de-bouncing capacitor
- Delayed events after a button push – Timed events (button push is just example.)
- analogWrite() PWM Fading – No delay() and a simple function to keep a LED fading with PWM
- Detect Short and Long Button Press – Give one button multiple functions
You might also want to check out my “Blink Without Delay – Line by Line Tutorial.” It is a much more in-depth explanation than the comments provided with the Arduino IDE example.
59 Comments
I did create a library (muTimer) which provides a delayOnOff() and cycleOnOff() function. It might be interesting for you and this topic.
It internally works with the millis() function.
https://github.com/MichaelUray/muTimer
Hi Tim,
I´m trying to use millis() to control the DC motors of my Sumorobot. My problem is that when i try to use millis my code doesnt work correctly, but when i use delay it works well. I know that im making mistakes when I change my code from delay () to millis(). Can you send me an email to help me? I need help, its for a proyect with my secondary school. Thanks and respects from argentina.
You cannot replace delay() with millis(). You must re-write the logic of your code. Unfortunately, I do not provide one-on-one email help. I would suggest posting your code and question on the “Programming Guidance” section of the Arduino.cc fourms.
Hi Tim,
(From one bald engineer to another…)
I tried using the millis() approach to multi-task my Arduino but unfortunately it didn’t work. It turned out that the processing time to read a couple of sensors and perform some math on the results was so long (hundreds of milliseconds) that other tasks (flashing led’s based on results) didn’t get updated in time, so the flashing sequences were completely messed up. Any suggestions?
Move your timed code into a function. Inside of that function do your millis() check. Then sprinkle calls to that function throughout long operations.
Thanks James ( sorry I called you Tim!). I’ll give that a try and let you know how it works out. As I am using standard Arduino library routines to deal with the sensors, it may then become necessary to copy the library code directly into my sketch and modify it to make the function calls at the appropriate times…assuming the library code is in the public domain.
Oh I forgot to add, and can see why this is creating some confusion,
the front and rear lights are off the same pin (im using a mosfet to drive the leds, in parallel, all white, no issue so far
and the side maker lights are another pin, mosfet etc, so there are only 2 pins, just need another funcition
sorry for the lack of info..
Hi Tim,
Here is a simpler program. No Mode, only Patterns, You could modify at will each pattern or add new pattern just be sure to update the MaxPattern definition if you do,
Since we have went around this program a lot, the other readers of this Millis() collumn will find boring reading all of our discussions so If you need other modification or need some clarifications, feel free to contact me using my email. Just use my username and add email to it then ampersand then gmail.com.
I will be pleased to help you.
[arduino]
// Arduino program for Strobing Bicycle Lights V 1.00
//
// In this program 4 patterns for 2 lights blinking are sequentially selected by a push button
// Patterns are kept in a 2 dimension Matrix named Event
// The corresponding delays is in the Matrix Delays
#define MaxPattern 4 // Number of pattern of blinking light
#define MaxEvent 9 // Number of max blinking event
#define ledwstrobe 2 // Define white led pin
#define ledrstrobe 3 // Define Red led pin
#define ButtonPin 4 // Define push Button pin. other side connected to ground
// Type of event possible
enum EventType {None,BothLo,BothHi,RedLo,RedHi,WLo,WHi};
// Actual event suite for each pattern. If you have less than MaxEvent, fill with None
EventType Event[MaxPattern][MaxEvent] = {{BothHi,None,None,None,None,None,None,None,None},
{BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,None},
{BothHi,RedLo,None,None,None,None,None,None,None},
{BothLo,None,None,None,None,None,None,None,None}};
// Actual delay suite for each pattern. If you have less than MaxEvent, fill with 0 delay
int Delays[MaxPattern][MaxEvent] = {{0,0,0,0,0,0,0,0,0},
{125,125,750,62,63,62,63,125,0},
{63,63,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0}};
unsigned long NextEventTime = 0; // When millis() >= NextEventTime then Event is due
unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
unsigned long DebounceDelay = 50; // 50ms for general debounce delay
int Pattern = 0; // Keep track on the next pattern. Value 0 – MaxPattern-1
int NextEvent = 0; // Keep track of the next event. Value 0 – MaxEvent-1
int ButtonState = HIGH; // Variable for current button reading
int LastButtonState = HIGH; // Variable for last known button reading
void setup() {
pinMode(ledwstrobe,OUTPUT); // white LED
pinMode(ledrstrobe,OUTPUT); // red LED
pinMode(ButtonPin,INPUT_PULLUP); // put the button to ground to activate
}
void loop() {
// Check the push button
int reading = digitalRead(ButtonPin);
//in the case that the reading is not equal to the last state set the last debounce time to current millis time
if (reading != LastButtonState) {
LastDebounceTime = millis();
}
//check the difference between current time and last registered button press time, if it’s greater
if ((millis()-LastDebounceTime) > DebounceDelay) {
if (reading != ButtonState) {
ButtonState = reading;
if (ButtonState == LOW) { // Button Pushed !
Pattern++; // increment Pattern Index
if (Pattern == MaxPattern) Pattern=0; // Roll over if Mode is too big
NextEvent = 0; // Reset to first Event
NextEventTime = millis(); // Reset the Nextime Event Delay
}
}
}
LastButtonState = reading; // Keep the last button state
if (millis() >= NextEventTime) GoBlink();
// do whatever here
}
// Do the actual blinking
void GoBlink() {
// If we find None return to the start of the list
if (Event[Pattern][NextEvent] == None) NextEvent = 0;
// Do the blink indicated by the NextEvent for the current pattern
switch (Event[Pattern][NextEvent]) {
case BothLo:
digitalWrite(ledwstrobe,LOW);
digitalWrite(ledrstrobe,LOW);
break;
case BothHi:
digitalWrite(ledwstrobe,HIGH);
digitalWrite(ledrstrobe,HIGH);
break;
case RedHi:
digitalWrite(ledrstrobe,HIGH);
break;
case RedLo:
digitalWrite(ledrstrobe,LOW);
break;
case WHi:
digitalWrite(ledwstrobe,HIGH);
break;
case WLo:
digitalWrite(ledwstrobe,LOW);
break;
case None:
break;
}
// Add the next delay to millis() and increment tne NextEvent counter
NextEventTime = millis() + Delays[Pattern][NextEvent];
NextEvent++;
// if we have attained the end of the list, return to the beginning
if (NextEvent == MaxEvent) NextEvent = 0;
}
[/arduino]
Hi Tim,
My last post is in the SPAM box. we have to wait until James can post it. Sorry
Ok will email you for questions, thanks so much for your help
Hi James,
Sure you can delete the others. I’m sorry to have made multiple post. I should have kwnown better.
Thank’s
Dear bald engineer, (Excuse my english)
Something puzzle me about millis()
You used millis() in a way to overcome a roll over problem.
if (millis() – previousMillis > 1000)
I don’t understand where the problem is with
NextTime = millis() + 1000;
if (millis() >= NextTime)
As I understand it, if millis() is at his unsigned long limit when I add a Delay of say 1000 to it, NextTime will have a roll over value of 1000. and when millis() is incremented it will revert to 0 and go up until it attain 1000 and the condition will be true. Where is my error in my reasonning?
Thank’s for helping me understand this question that puzzle me..
The problem is how often the if-statement is checked. Here is a practical example where using the “increment” variable fails.
Let’s say the max millis value is 4,294,967,295. And let’s say when you run “NextTime = millis() + 1000;” millis is 4,294,966,000.
Now let’s say your code is:
[code]
NextTime = millis() + 1000;
if (millis() >= NextTime){}
[/code]
NextTime has the value of 295, because it rolled over. However, millis() has not rolled over yet. So on the next statement, millis() is 4,294,966,002. The if-statement is:
if (4,294,966,000 > 295). That evaluates as true! And will be true until millis() finally rolls over.
Perfect example James. Now I understand why your method is better in the long run.
Thank you very much.
Continue your great work, it help a lot of us coding better programs.
Delays[] contain all the delay for the events. The program will add each one in turn to the millis() counter and each time the loop is executed it will check if millis() is now greater than the old millis()+delay implying that it is now the time to switch something on or off. The GoBlink will check which event is due using the array Events[] and switch on or off the led accordingly.
I made the assumption that your code run indefinitely that blinking pattern and that you wanted your program to do other thing simultaneously. But if this is not the case you could tell me what exactly you want to do. If you want to do many blinking patterns commanded by push button we could alter the solution to suit your need. Just tell me more of what you want to do in detail so I can help you. How many pattern, how many push button, etc.
Thanks very much for your reply and help. Basically, I have 1 push button I am using to toggle through 3 modes, (1) mode is all leds on, (2) mode strobe pattern (3) mode leds off. The problem was all the delays and the push button not responding. Perhaps I could put your function into mode 2, call that function on the 2 nd button push.
void loop() {
if (digitalRead(3) != state) {
state = digitalRead(3);
if (digitalRead(3) == HIGH) {
mode += 1;
if (mode > 2) {
mode = 0;
}
if (mode == 0);{
//all leds on
}
if (mode == 1) {
GoBlink();
}
if (mode == 2){
//all leds off
}
something like this is what Im trying to do. Before, with all the delays in the code, it would hang up the digitalRead on pin 3, so it took like 10 pushes just to get a toggle
Good idea,
You shoud reset the mode = 2 variables when a button is pushed just in case the next mode = 2;
if (digitalRead(3) == HIGH) {
mode += 1;
if (mode > 2) mode = 0;
NextTime = 0;
NextEvent = 0;
}
for mode = 1 you should test if it is time for the next event before jumping to GoBlink()
if (mode == 1 & millis() >= NextTime) GoBlink();
When I have a single very short statement in a “if” i don’t use the bracket. I find it cleaner. But maybe it is not a good practice. Do it the way you prefer.
Good luck!
well basically Im not trying to reset, just need to toggle between modes
your code works great, have the strobes on now, but I want to toggle with a button push, to another mode, like off, on, strobes, then another mode perhaps, front and back on, with side marker leds strobing
I dont know how to implement that with your code, into the mode toggles
Hi Tim, sorry for the delay. ;O)
Here is the code you need. Was tested with success.
Work only for around 49 continous days until millis roll over. ;O)
By the way where are you from?
I’m from Quebec, Canada
#define MaxEvent 9 // number of event
#define ledwstrobe 2 // Define white led pin
#define ledrstrobe 3 // Define Red led pin
#define ButtonPin 4 // Define button pin
// Buttons with Pull-Ups are “backwards” so LOW = Pushed, HIGH = Released
byte Mode = 0; // Mode 0=On, 1=Blink pattern, 2=Off
enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event for blink
EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event
int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
unsigned long NextTime = 0; // When millis() >= NextTime then Event is due
unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
unsigned long DebounceDelay = 50; // 50ms for general debounce delay
int ButtonState = HIGH; //Variable for current button reading
int LastButtonState = HIGH; //Variable for last known button reading
void setup() {
pinMode(ledwstrobe,OUTPUT);
pinMode(ledrstrobe,OUTPUT);
pinMode(ButtonPin,INPUT_PULLUP);
}
void loop() {
// Check the push button
int reading = digitalRead(ButtonPin);
//in the case that the reading is not equal to the last state set the last debounce time to current millis time
if (reading != LastButtonState) {
LastDebounceTime = millis();
}
//check the difference between current time and last registered button press time, if it’s greater
if ((millis()-LastDebounceTime) > DebounceDelay) {
if (reading != ButtonState) {
ButtonState = reading;
if (ButtonState == LOW) { // Button Pushed
Mode++; // increment Mode
if (Mode == 3) Mode=0; // Roll over if Mode is too big
NextEvent = 0; // Reset to first Event
NextTime = millis(); // Reset the Nextime Event Delay
}
}
}
LastButtonState = reading; // Keep the last button state
// do what the Mode variable says
switch (Mode) {
case 0:
digitalWrite(ledwstrobe,HIGH); // LED White On
digitalWrite(ledrstrobe,HIGH); // LED RED On
break;
case 1:
if (millis() >= NextTime) GoBlink(); // If delay is passed, GoBlink
break;
case 2:
digitalWrite(ledwstrobe,LOW); // LED White Off
digitalWrite(ledrstrobe,LOW); // LED Red Off
break;
}
// do whatever here
}
// Blinking routine
void GoBlink() {
switch (Event[NextEvent]) {
case BothLo:
digitalWrite(ledwstrobe,LOW);
digitalWrite(ledrstrobe,LOW);
break;
case BothHi:
digitalWrite(ledwstrobe,HIGH);
digitalWrite(ledrstrobe,HIGH);
break;
case RedHi:
digitalWrite(ledrstrobe,HIGH);
break;
case RedLo:
digitalWrite(ledrstrobe,LOW);
break;
case WHi:
digitalWrite(ledwstrobe,HIGH);
break;
case WLo:
digitalWrite(ledwstrobe,LOW);
break;
}
NextTime = millis() + Delays[NextEvent];
NextEvent++;
if (NextEvent == MaxEvent) NextEvent = 0;
}
Hi Tim, Sorry for the delay(). ;O)
Here is your program tested and working.
By the way, where are you from?
I’m from Quebec, Canada
Have fun!
#define MaxEvent 9 // number of event
#define ledwstrobe 2 // Define white led pin
#define ledrstrobe 3 // Define Red led pin
#define ButtonPin 4 // Define button pin
// Buttons with Pull-Ups are “backwards” so LOW = Pushed, HIGH = Released
byte Mode = 0; // Mode 0=On, 1=Blink pattern, 2=Off
enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event for blink
EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event
int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
unsigned long NextTime = 0; // When millis() >= NextTime then Event is due
unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
unsigned long DebounceDelay = 50; // 50ms for general debounce delay
int ButtonState = HIGH; //Variable for current button reading
int LastButtonState = HIGH; //Variable for last known button reading
void setup() {
pinMode(ledwstrobe,OUTPUT);
pinMode(ledrstrobe,OUTPUT);
pinMode(ButtonPin,INPUT_PULLUP);
}
void loop() {
// Check the push button
int reading = digitalRead(ButtonPin);
//in the case that the reading is not equal to the last state set the last debounce time to current millis time
if (reading != LastButtonState) {
LastDebounceTime = millis();
}
//check the difference between current time and last registered button press time, if it’s greater
if ((millis()-LastDebounceTime) > DebounceDelay) {
if (reading != ButtonState) {
ButtonState = reading;
if (ButtonState == LOW) { // Button Pushed
Mode++; // increment Mode
if (Mode == 3) Mode=0; // Roll over if Mode is too big
NextEvent = 0; // Reset to first Event
NextTime = millis(); // Reset the Nextime Event Delay
}
}
}
LastButtonState = reading; // Keep the last button state
// do what the Mode variable says
switch (Mode) {
case 0:
digitalWrite(ledwstrobe,HIGH); // LED White On
digitalWrite(ledrstrobe,HIGH); // LED RED On
break;
case 1:
if (millis() >= NextTime) GoBlink(); // If delay is passed, GoBlink
break;
case 2:
digitalWrite(ledwstrobe,LOW); // LED White Off
digitalWrite(ledrstrobe,LOW); // LED Red Off
break;
}
// do whatever here
}
// Blinking routine
void GoBlink() {
switch (Event[NextEvent]) {
case BothLo:
digitalWrite(ledwstrobe,LOW);
digitalWrite(ledrstrobe,LOW);
break;
case BothHi:
digitalWrite(ledwstrobe,HIGH);
digitalWrite(ledrstrobe,HIGH);
break;
case RedHi:
digitalWrite(ledrstrobe,HIGH);
break;
case RedLo:
digitalWrite(ledrstrobe,LOW);
break;
case WHi:
digitalWrite(ledwstrobe,HIGH);
break;
case WLo:
digitalWrite(ledwstrobe,LOW);
break;
}
NextTime = millis() + Delays[NextEvent];
NextEvent++;
if (NextEvent == MaxEvent) NextEvent = 0;
}
I try 3 times to upload the code withous success.
Do you have a place I could upload it so you can have it?
Sorry. Long posts get caught in the spam filter. Is the last one okay? Can I delete the others?
Third time I try to put the code. Hope this time it will work
Here is your code Tim. Program is tested and working
Have fun!
[arduino]
#define MaxEvent 9 // number of event
#define ledwstrobe 2 // Define white led pin
#define ledrstrobe 3 // Define Red led pin
#define ButtonPin 4 // Define button pin
// Buttons with Pull-Ups are "backwards" so LOW = Pushed, HIGH = Released
byte Mode = 0; // Mode 0=On, 1=Blink pattern, 2=Off
enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event for blink
EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event
int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
unsigned long NextTime = 0; // When millis() >= NextTime then Event is due
unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
unsigned long DebounceDelay = 50; // 50ms for general debounce delay
int ButtonState = HIGH; //Variable for current button reading
int LastButtonState = HIGH; //Variable for last known button reading
void setup() {
pinMode(ledwstrobe,OUTPUT);
pinMode(ledrstrobe,OUTPUT);
pinMode(ButtonPin,INPUT_PULLUP);
}
void loop() {
// Check the push button
int reading = digitalRead(ButtonPin);
//in the case that the reading is not equal to the last state set the last debounce time to current millis time
if (reading != LastButtonState) {
LastDebounceTime = millis();
}
//check the difference between current time and last registered button press time, if it’s greater
if ((millis()-LastDebounceTime) > DebounceDelay) {
if (reading != ButtonState) {
ButtonState = reading;
if (ButtonState == LOW) { // Button Pushed
Mode++; // increment Mode
if (Mode == 3) Mode=0; // Roll over if Mode is too big
NextEvent = 0; // Reset to first Event
NextTime = millis(); // Reset the Nextime Event Delay
}
}
}
LastButtonState = reading; // Keep the last button state
// do what the Mode variable says
switch (Mode) {
case 0:
digitalWrite(ledwstrobe,HIGH); // LED White On
digitalWrite(ledrstrobe,HIGH); // LED RED On
break;
case 1:
if (millis() >= NextTime) GoBlink(); // If delay is passed, GoBlink
break;
case 2:
digitalWrite(ledwstrobe,LOW); // LED White Off
digitalWrite(ledrstrobe,LOW); // LED Red Off
break;
}
// do whatever here
}
// Blinking routine
void GoBlink() {
switch (Event[NextEvent]) {
case BothLo:
digitalWrite(ledwstrobe,LOW);
digitalWrite(ledrstrobe,LOW);
break;
case BothHi:
digitalWrite(ledwstrobe,HIGH);
digitalWrite(ledrstrobe,HIGH);
break;
case RedHi:
digitalWrite(ledrstrobe,HIGH);
break;
case RedLo:
digitalWrite(ledrstrobe,LOW);
break;
case WHi:
digitalWrite(ledwstrobe,HIGH);
break;
case WLo:
digitalWrite(ledwstrobe,LOW);
break;
}
NextTime = millis() + Delays[NextEvent];
NextEvent++;
if (NextEvent == MaxEvent) NextEvent = 0;
}
[/arduino]
dude thats some serious code! thanks allot btw Im from the US
dude your a genuis….is it possible to add another function that only has the ledrstrobe, for example, strobing and the ledwstrobe HIGH, like to simulate the front and rear lights HIGH (no strobe) and side marker leds, strobing? im still processing how the events map to the delays to the millis..awesome job dude! thanks so much
Hi Tim,
I’m very far from a genius. James is probably nearer to that definition.
Like I said earlier, i’m French Canadian so English is a second language for me, so I don’t fully understand what you want exactly.
Correct me if i’m wrong and you can complete.
So from what I understand, you would like another strobing pattern added. I suppose from another push of the same button. In that new configuration you would have not 2 but 4 lights (LED) In that case the front red light would strobe and the white light would be on at all time. In the back the red would be On and what is side marker?
Or maybe you have 6 LED. 2 for the front, 2 for the back and 2 for the light on the top of the car
So please explain in greater detail so I can try to help you better.
Don’t fuck yourself understanding the code right now cause the next one will be inspired by, but relatively different.
What are you trying to do by the way? Building something you can put on your car to simulate a police car. ;O)
Thanks again for your help and reply. I have total 8 lights, 2 in front, 2 in back and 2 on each side, of the bike
So for the last function, I would like to keep the 2 fronts and 2 backs on or HIGH, and strobe the 4 side lights. Just a cool patter I would like to achieve.
This is just for my bike, to be seen from all angles at night
So this last function would be mode 4, same push button
[code]
int switch1 = 2;
int i[] = {3, 4, 5, 6, 7, 8};
int BASE = 3 ; // the I/O pin for the first LED
int NUM = 6; // number of LEDs
int ledDelay(45);// Delay
void setup() {
pinMode(2, INPUT_PULLUP);
for (int i = BASE; i < BASE + NUM; i ++)
{ pinMode(i, OUTPUT); // set I/O pins as output
digitalWrite(i, HIGH);
delay(ledDelay * 8);
}
}
void loop() {
switch1 = digitalRead(2);
if (switch1 == HIGH) {
for (int i = BASE; i < BASE + NUM; i ++)
{ digitalWrite(i, HIGH);
}
} else {
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay); // delay
}
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, LOW); // set I/O pins as “high”, turn on LEDs one by one
delay(ledDelay); // delay
}
for (int i = BASE + NUM ; i >= BASE; i –)
{
digitalWrite(i, HIGH); // set I/O pins as “high”, turn on LEDs one by one
delay(ledDelay); // delay
}
for (int i = BASE + NUM ; i >= BASE; i –)
{
digitalWrite(i, LOW); // set I/O pins as “high”, turn on LEDs one by one
delay(ledDelay); // delay
}
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
for (int i = BASE + NUM ; i >= BASE; i –)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
digitalWrite(i – 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
for (int i = BASE; i < BASE + NUM – 1; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
for (int i = BASE; i < BASE + NUM – 2; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
for (int i = BASE; i < BASE + NUM – 3; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
for (int i = BASE; i < BASE + NUM – 4; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
for (int i = BASE; i < BASE + NUM – 5; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(3, HIGH);
for (int i = BASE; i < BASE + NUM – 6; i ++)
{
digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
delay(ledDelay);
digitalWrite(i + 1, HIGH);
digitalWrite(i, LOW);
delay(ledDelay); // delay
}
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(3, HIGH);;
delay(ledDelay * 2); // delay
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
digitalWrite(4, LOW);
digitalWrite(3, LOW);
delay(ledDelay * 2); // delay
delay(ledDelay * 2); // delay
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(3, HIGH);
delay(ledDelay * 2); // delay
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
digitalWrite(4, LOW);
digitalWrite(3, LOW);
delay(ledDelay * 2); // delay
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(3, HIGH);
delay(ledDelay * 2); // delay
digitalWrite(8, LOW);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
digitalWrite(4, LOW);
digitalWrite(3, LOW);
delay(ledDelay * 2); // delay
}
}
[/code]
You need to implement a state machine. This is not something I can help you with. If you need one-on-one help, please post your questions on the “Programming” section of the Arduino.cc forums.
i made a mistake in my code. The last “if” should be (NextEvent == MaxEvent) could you correct it?
Fixed.
In response to Tim, Here is how i do it.
Hope this help!
[arduino language=”1″]
#define MaxEvent 9 // number of event
#define ledwstrobe 2 // Define white led pin
#define ledrstrobe 3 // Define Red led pin
enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event
EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event
unsigned long NextTime = 0; // When millis() > NextTime then Event is due
int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
void setup() {
pinMode(ledwstrobe,OUTPUT);
pinMode(ledrstrobe,OUTPUT);
}
void loop() {
if (millis() > NextTime) GoBlink();
// do whatever here
}
void GoBlink() {
switch (Event[NextEvent]) {
case BothLo:
digitalWrite(ledwstrobe,LOW);
digitalWrite(ledrstrobe,LOW);
break;
case BothHi:
digitalWrite(ledwstrobe,HIGH);
digitalWrite(ledrstrobe,HIGH);
break;
case RedHi:
digitalWrite(ledrstrobe,HIGH);
break;
case RedLo:
digitalWrite(ledrstrobe,LOW);
break;
case WHi:
digitalWrite(ledwstrobe,HIGH);
break;
case WLo:
digitalWrite(ledwstrobe,LOW);
break;
}
NextTime = millis() + Delays[NextEvent];
NextEvent++;
if (NextEvent == MaxEvent) NextEvent = 0;
}
[/arduino]
Hi thanks again for your code and help. Does this code you provided solve by delay problem? I have too many delays in my code. It seems you moved the delays into the int Delays[ ]
Hello Tim,
I’m sorry but english is not my first language so i don’t understand your question. (Solve by delay problem, Do you mean Solve my delay problem. If this is the question, the answer is yes) You could add as many event as you want. Just add them in the two arrays Event[] and Delays[] and update the value of MaxEvent to reflect the total number of event. That way your code is free to run anything you want. Each time the loop is executed the program test if the next event is due, if not, it continue, if yes, it go to the GoBlink routine. It is as simple as that.
Tell me if it work for you.
Dear Bald Engineer,
I was wondering if there is a way to turn the strobe pattern below into mills code?
[arduino firstline=”1″]
digitalWrite(ledwstrobe, LOW); //set off white strobe
digitalWrite(ledrstrobe, LOW); //set off red strobe
delay(125);
digitalWrite(ledrstrobe, HIGH); //set on red strobe
delay(125);
digitalWrite(ledrstrobe, LOW); //set off red strobe
delay(750);
digitalWrite(ledwstrobe, HIGH); //set white strobe on
delay(62);
digitalWrite(ledwstrobe, LOW); //set white strobe off
delay(63);
digitalWrite(ledwstrobe, HIGH); //set white strobe on
delay(62);
digitalWrite(ledwstrobe, LOW); //set white strobe off
delay(63);
digitalWrite(ledwstrobe, HIGH); //set white strobe on
delay(125);
digitalWrite(ledwstrobe, LOW); //set white strobe off
delay(0);
}
[/arduino]
Thank you for your reply and help.
Are these int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual
or are those timestamps, for use in the milis code?
im trying to use a push button to toggle through modes, and it wont work with all m delays. will your code solve this issue?
Thank you James for your examples most interesting
Bob
I found this library which helped with a switch cycle tester
I needed to turn on output A on for X seconds, turn it off and then turn on output B for Y seconds then turn it off, decrement a counter and repeat until count = 0
http://lab.dejaworks.com/easy-flip-flop-arduino-library/
Hi, I am trying this on TInkerCad and the turn LED does not blink. I have the sketch exactly like above but the only thing I changed was the codes for the remote buttons.ANy idea why
TinkerCad is a 3D modeling tool (that is no longer supported.) So I have no idea how you would run code there. It works fine on a real Arduino. If it isn’t working in your code, then there is an issue with your code.
Thanks James.. appreciated..I am jus getting into Arduino… Thanks for the prompt response…
Hi Bald Engineer,
Thank you so much for teaching the ways to avoid delays. Thanks to you I have created one of my best projects so far: A Multitasking Arduino Timer. It consists of a fading Led, music, and a timer with a relay to turn off any appliance you would normally plug into the wall.
Come and check it out at https://www.instructables.com/id/The-Multitasking-Final-Countdown-Timer-With-Wirele/
I read all of your examples and I got a few questions.
I want to make codes which control LED.
I intended to turn on/off the LED depending on the distance.(I use ultrasonic sensor to check distance)
For example
if d is between 10cm and 20cm, LED will be on. (d=distance)
And if d is between 10cm and 20cm for 5 seconds, LED will be off though it is in ‘ON-STATE’ distance.
My question is how I can do it by using ‘Millis’.
plz help, especially ‘And if ‘ line .
If you have a specific question, I can try to help. But I can’t provide general project help. I recommend posting on the arduino.cc forums. Look at either the Project Guidance or Programming Questions sections.
hiii, have you got the code. actually i was trying to make a code for 2 ultrasonic sensors which are required to work paralelly.
Please iIno to control 4 led to link one after the order
How to use millis command in coin slot operation? please help thanks. we cannot use delay because it disrupts the process.
Hi i was wondering if you could help me out..i am trying to run a vibrator motor on my arduino along with two other sensors,i want the vibrator motor to start if any of the two sensors are continuously active for 2 minutes ..can you please help me modify my code for millis()
Create a post in the Arduino Forums, in the programming section. Send me a link and I’ll try to help you there.
Hi,
I am trying to make LED blink at 0.7hz like turn signal of cars/motorcycles
Trying to get it work like this:
When a button on IR remote is pressed (hex code : 0x811), turn signal should start blinking at 0.7hz until a button on the remote is pressed again to turn it off (0x11).
Is it possible? I’d really appreciate if you could help me with this.
So far I have succeded to make LEDs on and off using IR remote buttons. But can’t get LEDs start blinking after pressing a key on IR remote and keep constantly blinking until IR remote button is pressed to turn it off.
I have tried blink without delay example but couldn’t get it working.
here is an example code i am using.
[arduino]
#include <IRremote.h>
#include <IRremoteInt.h>
#define irPin 2 //IR receiver on pin 2
int led1 = 3; //LED that turns on and off using IR remote button.
int turn = 12; //turn indicator blinker. Should start blinking at 0.7hz after key on remote is pressed
IRrecv irrecv(irPin);
decode_results results;
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(led1, OUTPUT);
pinMode(turn, OUTPUT);
}
void loop() {
if (irrecv.decode(&results)) {
switch (results.value) {
case 0x837: //IR remote key to turn LED1 ON
digitalWrite(led1, HIGH);
break;
case 0x37: //IR remote key to turn LED1 OFF
digitalWrite(led1, LOW);
break;
case 0x834: //I want to use this key to start blinking ‘turn’ LED at 0.7hz
// don’t know what to do here
break;
case 0x34: //I want to use this key to stop blinking ‘turn’ LED
// don’t know what to do here
break;
}
irrecv.resume();
}
}
[/arduino]
I would do something like this, using millis() and a flag variable. for your cases when you want to turn the LED on and off, you just set the flag. this way each time loop() runs, if the flag is on, the blink is done.
(I don’t have an arduino with me to test this code.)
You can also download here: https://pastebin.com/prQqTWG0
[arduino]
#include <IRremote.h>
#include <IRremoteInt.h>
#define irPin 2 //IR receiver on pin 2
int led1 = 3; //LED that turns on and off using IR remote button.
int turn = 12; //turn indicator blinker. Should start blinking at 0.7hz after key on remote is pressed
bool blinking = false; //defines when blinking should occur
unsigned long blinkInterval = 1420; // number of milliseconds for blink (1/0.7)
unsigned long currentMillis; // variables to track millis()
unsigned long previousMillis;
IRrecv irrecv(irPin);
decode_results results;
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(led1, OUTPUT);
pinMode(turn, OUTPUT);
}
void loop() {
// this code blinks the LED
if (blinking) {
currentMillis = millis(); // better to store in variable, for less jitter
if ((unsigned long)(currentMillis – previousMillis) >= blinkInterval) { // enough time passed yet?
digitalWrite(turn, !digitalRead(turn)); // shortcut to toggle the LED
previousMillis = currentMillis; // sets the time we wait "from"
}
} else {
digitalWrite(turn, LOW); // force LED off when not blinking
}
if (irrecv.decode(&results)) {
switch (results.value) {
case 0x837: //IR remote key to turn LED1 ON
digitalWrite(led1, HIGH);
break;
case 0x37: //IR remote key to turn LED1 OFF
digitalWrite(led1, LOW);
break;
case 0x834: //I want to use this key to start blinking ‘turn’ LED at 0.7hz
blinking = true;
break;
case 0x34: //I want to use this key to stop blinking ‘turn’ LED
blinking = false;
break;
}
irrecv.resume();
}
}
[/arduino]
Wow. it works
Thanks alot, you’re the man. 🙂
I was trying to figure it out for ages. Really appreciate your help.
Thanks again.
Hi,
Wondered if you can assist/ point me in the right direction?
I am thinking about measuring the Overall Equipment Effectiveness of a machine (OEE) via a retro-fitted status box.
Initial thoughts are to have a sensor measuring the speed
While the speed is being in the High status no event
When the speed = 0 [i.e. the machine stops]
I am wanting to record the real time it actually stopped
Then the operator will activate a condition toggle for an array of 3 conditions
1. Waiting for a Material
2. Waiting for an engineer
3. Defect
When the toggle condition is induced this is to be timed (real time)
until the condition is cleared and the machine runs
Could you give me a clue where to find a similar program please?
Thanks in advance
I doubt you’ll find an exact match.
An alternative to a microcontroller based solution would be using a programmable logic controller (PLC). They’re industrial microcontrolllers with programming “languages” designed specifically for working with machines.
Pingback: baldengineer | First Impressions of Electron, a new NodeJS IDE for Arduino
Pingback: baldengineer | millis() Tutorial: Arduino Multitasking
Hi, HELP please…
i want to remove all the delays from the codes below:v
void loop(){
northtogreen(); //change the north signal to green
delay(maindelay*4); //wait for the traffic to pass
northtored(); //change the north signal back to red
delay(maindelay/2); //small delay to allow traffic to clear junction
easttogreen(); //change the east signal to green
delay(maindelay*4);//wait for the traffic to pass
easttored(); //change the east signal back to red
delay(maindelay/2); //small delay to allow the traffic to clear junction
}
void northtogreen(){ //sequence of north lights going to green
digitalWrite(northAmber,HIGH); //Amber on, prepare to go
delay(maindelay); //Time for traffic to see amber
digitalWrite(northRed,LOW); //red off, finished with
digitalWrite(northAmber,LOW); //amber off, finished with
digitalWrite(northGreen,HIGH); //green on, go
}
void northtored(){ //sequence of north lights going to red
digitalWrite(northAmber,HIGH); //Amber on, prepare to stop
digitalWrite(northGreen,LOW); //Green off, finished with
delay(maindelay); //Time for traffic to stop
digitalWrite(northAmber,LOW); //Amber off
digitalWrite(northRed,HIGH); //Red on, stop
}
void easttogreen(){ //sequence of east lights going to green
digitalWrite(eastAmber,HIGH); //Amber on, prepare to go
delay(maindelay); //Time for traffic to see amber
digitalWrite(eastRed,LOW); //red off, finished with
digitalWrite(eastAmber,LOW); //amber off, finished with
digitalWrite(eastGreen,HIGH); //green on, go
}
void easttored(){//sequence of east lights going to red
digitalWrite(eastAmber,HIGH); //Amber on, prepare to stop
digitalWrite(eastGreen,LOW); //Green off, finished with
delay(maindelay); //Time for traffic to stop
digitalWrite(eastAmber,LOW); //Amber off, finished with
digitalWrite(eastRed,HIGH); //Red on, stop
}
thanks 🙂
It really isn’t a simple method like “replace” the calls to delay(). You need to create a state machine. (Which will be a topic for a future post). A state machine is where you create one or more variables that tell your code what to do at certain times. So for example you might have a “AmberState”. When State is 0, the pin is off for 500ms. After 500ms you change the state to 1. Whenever the state is 1 you turn on the pin. When another 500ms passes, you set it back to 0.
Four year later…
[arduino firstline=”1″]
/*
Standard Traffic Light. Red Amber Green on each side
No delay, 2 variables
*/
#define NorthGreenPin 2
#define NorthAmberPin 3
#define NorthRedPin 4
#define EastGreenPin 5
#define EastAmberPin 6
#define EastRedPin 7
#define WaitGreen 30000 // Green for 30 seconds
#define WaitAmber 5000 // Amber for 5 seconds
#define WaitMore 2000 // Red on both side for 2 seconds
unsigned long NextTime = 0;
int NextEvent = 1;
void setup(){
// Assign Pin
pinMode(NorthGreenPin,OUTPUT);
pinMode(NorthAmberPin,OUTPUT);
pinMode(NorthRedPin,OUTPUT);
pinMode(EastGreenPin,OUTPUT);
pinMode(EastAmberPin,OUTPUT);
pinMode(EastRedPin,OUTPUT);
// Start with East Red
digitalWrite(EastRedPin,HIGH);
}
void loop(){
if (millis() > NextTime) CheckLight();
}
void CheckLight(){
switch (NextEvent) {
case 1: // North Green
digitalWrite(NorthRedPin,LOW);
digitalWrite(NorthGreenPin,HIGH);
NextTime = millis() + WaitGreen;
NextEvent = 2;
break;
case 2: // North Green to Amber
digitalWrite(NorthGreenPin,LOW);
digitalWrite(NorthAmberPin,HIGH);
NextTime = millis() + WaitAmber;
NextEvent = 3;
break;
case 3: // North Amber to Red
digitalWrite(NorthAmberPin,LOW);
digitalWrite(NorthRedPin,HIGH);
NextTime = millis() + WaitMore;
NextEvent = 4;
break;
case 4: // East Green
digitalWrite(EastRedPin,LOW);
digitalWrite(EastGreenPin,HIGH);
NextTime = millis() + WaitGreen;
NextEvent = 5;
break;
case 5: // East Green to Amber
digitalWrite(EastGreenPin,LOW);
digitalWrite(EastAmberPin,HIGH);
NextTime = millis() + WaitAmber;
NextEvent = 6;
break;
case 6: // East Amber to Red
digitalWrite(EastAmberPin,LOW);
digitalWrite(EastRedPin,HIGH);
NextTime = millis() + WaitMore;
NextEvent = 1;
break;
}
}
[/arduino]