Help with adding millis() and replace delay(100) in this sketch

I want to replace delay(100) with millis and still have the blinking led

Thank You

const byte button=2;                     
const byte LED=5;                 
boolean blinking = false;
unsigned long blinkInterval=250;                      
unsigned long currentMillis;                        
unsigned long previousMillis;                       
void setup()
{
    pinMode(button,INPUT);
    pinMode(LED,OUTPUT);
    digitalWrite(LED,HIGH); 
}
void loop()
{

    if(!blinking )
    {
        currentMillis = millis();

        unsigned long blinkInterval=100;
        if((unsigned long)(currentMillis - previousMillis) >= blinkInterval)
        { 
            digitalWrite(LED,!digitalRead(LED)); 
            //I  added += here to stop jitter and clock drifting as suggested in Arduino forums
            previousMillis += currentMillis;
        }
    } else 
    {
        digitalWrite(LED,LOW); 
    }

    int reading=digitalRead(button);
    delay(100); 

    if(reading==LOW) 
    { blinking =true; }
    else
    { blinking =false; }
}

To make it easy for people to help you please modify your post and use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to my text editor.

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

it's hard to read you code with all the comments lines

consider the following code which monitors several switches and flashes the corresponding LED

// scan multiple buttons; flash LED corresponding to button pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
    Serial.begin (9600);

    for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], HIGH);
        pinMode      (ledPins [n], OUTPUT);

        pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

// -----------------------------------------------------------------------------
int ledOn = -1;

void loop (void)
{
    static unsigned long msecLst = 0;
           unsigned long msec    = millis();

    for (unsigned n = 0; n < N_PINS; n++)  {
        byte but = digitalRead (butPins [n]);

        if (butLst [n] != but)  {
            butLst [n] = but;

            if (LOW == but) {     // button pressed
                if (ledOn)
                    digitalWrite (ledOn, HIGH); // off
                ledOn = ledPins [n];
            }
        }
    }

    if (-1 != ledOn)  {
        if (msec - msecLst > 100)  {
            msecLst = msec;
            digitalWrite (ledOn, ! digitalRead (ledOn));
        }
    }

    delay (10);         // debounce
}

Hello Thanks for your reply but I don't want to use delay like you show in your code

it's a very short 10 msec delay to prevent scanning a switch too quickly.

delete it. it may not be necessary

A sample sketch was given to you in post #21 in your previous thread.

It shows how to make/control/adjust many TIMERs.

If you take the time to review the sketch, hopefully things will click in for you.

https://forum.arduino.cc/index.php?topic=684573.msg4606814#msg4606814

The switch handling in this sketch ‘does not’ use delay()s.

gcjr:
it's a very short 10 msec delay to prevent scanning a switch too quickly.

delete it. it may not be necessary

Yes, than you, but the reason for millis is to not block code like delay does. For this simple sketch it doesn't matter but I want to look to the future for more complex sketches and always use millis and debounce

Switch debouncing and millis TIMERs is covered in the example you were given and told about (3 times now), however, you don’t seem to take any direction.

Good luck.

stspringer:
but I want to look to the future for more complex sketches and always use millis and debounce

ok. i replaced the use of delay() with the use of millis().

if you're concerned about more complex sketches why wasn't this simple change obvious to you?

// scan multiple buttons; flash LED corresponding to button pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
    Serial.begin (9600);

    for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], HIGH);
        pinMode      (ledPins [n], OUTPUT);

        pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

// -----------------------------------------------------------------------------
int ledOn = 0;

void loop (void)
{
    unsigned long msec    = millis();

    static unsigned long msecLst2 = 0; 
    if (msec - msecLst2 > 10)  {
        msecLst2 = msec;

        for (unsigned n = 0; n < N_PINS; n++)  {
            byte but = digitalRead (butPins [n]);

            if (butLst [n] != but)  {
                butLst [n] = but;

                if (LOW == but) {     // button pressed
                    digitalWrite (ledOn, HIGH); // off

                    if (ledOn == ledPins [n])
                        ledOn = 0;
                    else
                        ledOn = ledPins [n];
                }
            }
        }
    }

    static unsigned long msecLst = 0;
    if (ledOn)  {
        if (msec - msecLst > 100)  {
            msecLst = msec;
            digitalWrite (ledOn, ! digitalRead (ledOn));
        }
    }

}

Edison, thank you very much for your help, I will study your code.

The reason I posted was that, using the code I posted, it used delay(100). I wanted to alter that original code and change the delay(100) to a millis function.

I see that you sent all new code, which is fine and I appreciate it. But for a learning exercise, I wanted to see if I could change that delay(100) to a millis without writing a new program. I tried numerous times and failed.

The led only blinked when I left the delay(100) active, even with my attempted millis update. The program always compiled and ran but the led stayed on all the time, no blink. When I uncommented the delay(100) the program blinked the led. That confuses me and I was hoping to figure out why it was doing that.

I hope you don't think I am being anal about it. I just thought if I was an arduino coder and someone brought me that sketch, I would like to be able to add a millis function without writing a new program from scratch.

Is my way of thinking incorrect?

I really appreciate what you sent, and I will study it. But I am still puzzled over the original script I posted.

Please advise me of what you think.

Thank you again for all your time and help.

gcjr:
ok. i replaced the use of delay() with the use of millis().

if you're concerned about more complex sketches why wasn't this simple change obvious to you?

// scan multiple buttons; flash LED corresponding to button pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
   Serial.begin (9600);

for (unsigned n = 0; n < N_PINS; n++)  {
       digitalWrite (ledPins [n], HIGH);
       pinMode      (ledPins [n], OUTPUT);

pinMode      (butPins [n], INPUT_PULLUP);
       butLst [n]  = digitalRead (butPins [n]);
   }
}

// -----------------------------------------------------------------------------
int ledOn = 0;

void loop (void)
{
   unsigned long msec    = millis();

static unsigned long msecLst2 = 0;
   if (msec - msecLst2 > 10)  {
       msecLst2 = msec;

for (unsigned n = 0; n < N_PINS; n++)  {
           byte but = digitalRead (butPins [n]);

if (butLst [n] != but)  {
               butLst [n] = but;

if (LOW == but) {     // button pressed
                   digitalWrite (ledOn, HIGH); // off

if (ledOn == ledPins [n])
                       ledOn = 0;
                   else
                       ledOn = ledPins [n];
               }
           }
       }
   }

static unsigned long msecLst = 0;
   if (ledOn)  {
       if (msec - msecLst > 100)  {
           msecLst = msec;
           digitalWrite (ledOn, ! digitalRead (ledOn));
       }
   }

}

From the gist of things, you can probably fix this issue by using a Finite State Maching (FSM) where the states are controlled by a software timer.

Edison, thank you very much for your help, I will study your code.

The reason I posted was that, using the code I posted, it used delay(100). I wanted to alter that original code and change the delay(100) to a millis function.

I see that you sent all new code, which is fine and I appreciate it. But for a learning exercise, I wanted to see if I could change that delay(100) to a millis without writing a new program. I tried numerous times and failed.

The led only blinked when I left the delay(100) active, even with my attempted millis update. The program always compiled and ran but the led stayed on all the time, no blink. When I uncommented the delay(100) the program blinked the led. That confuses me and I was hopeing to figure out why it was doing that.

I hope you don't think I am being anal about it. I just thought if I was an arduino coder and someone brought me that sketch, I would like to beable to add a millis function without writing a new program from scratch.

Is my way of thinking incorrect?

I really appreciate what you sent, and I will study it. But I am still puzzled over the original script I posted.

Please advise me of what you think.

Thank you again for all your time and help.

gcjr:
ok. i replaced the use of delay() with the use of millis().

if you're concerned about more complex sketches why wasn't this simple change obvious to you?

// scan multiple buttons; flash LED corresponding to button pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
    Serial.begin (9600);

for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], HIGH);
        pinMode      (ledPins [n], OUTPUT);

pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

// -----------------------------------------------------------------------------
int ledOn = 0;

void loop (void)
{
    unsigned long msec    = millis();

static unsigned long msecLst2 = 0;
    if (msec - msecLst2 > 10)  {
        msecLst2 = msec;

for (unsigned n = 0; n < N_PINS; n++)  {
            byte but = digitalRead (butPins [n]);

if (butLst [n] != but)  {
                butLst [n] = but;

if (LOW == but) {    // button pressed
                    digitalWrite (ledOn, HIGH); // off

if (ledOn == ledPins [n])
                        ledOn = 0;
                    else
                        ledOn = ledPins [n];
                }
            }
        }
    }

static unsigned long msecLst = 0;
    if (ledOn)  {
        if (msec - msecLst > 100)  {
            msecLst = msec;
            digitalWrite (ledOn, ! digitalRead (ledOn));
        }
    }

}

stspringer:
I looked at your code that you sent and it works really well. I will study it. It looks really different from other millis code I have seen, seems like a different way to skin a cat. I like it. Thank you for your time and effort.

I am studying it again this morning I see now you are using array's. I know about arrays from programming in Visual Basic, nice and clean looking code.

stspringer:
Edison, thank you very much for your help, I will study your code.

The reason I posted was that, using the code I posted, it used delay(100). I wanted to alter that original code and change the delay(100) to a millis function.

I see that you sent all new code, which is fine and I appreciate it. But for a learning exercise, I wanted to see if I could change that delay(100) to a millis without writing a new program. I tried numerous times and failed.

The led only blinked when I left the delay(100) active, even with my attempted millis update. The program always compiled and ran but the led stayed on all the time, no blink. When I uncommented the delay(100) the program blinked the led. That confuses me and I was hopeing to figure out why it was doing that.

I hope you don't think I am being anal about it. I just thought if I was an arduino coder and someone brought me that sketch, I would like to beable to add a millis function without writing a new program from scratch.

Is my way of thinking incorrect?

I really appreciate what you sent, and I will study it. But I am still puzzled over the original script I posted.

Please advise me of what you think.

Thank you again for all your time and help.

gcjr:
ok. i replaced the use of delay() with the use of millis().

if you're concerned about more complex sketches why wasn't this simple change obvious to you?

// scan multiple buttons; flash LED corresponding to button pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
   Serial.begin (9600);

for (unsigned n = 0; n < N_PINS; n++)  {
       digitalWrite (ledPins [n], HIGH);
       pinMode      (ledPins [n], OUTPUT);

pinMode      (butPins [n], INPUT_PULLUP);
       butLst [n]  = digitalRead (butPins [n]);
   }
}

// -----------------------------------------------------------------------------
int ledOn = 0;

void loop (void)
{
   unsigned long msec    = millis();

static unsigned long msecLst2 = 0;
   if (msec - msecLst2 > 10)  {
       msecLst2 = msec;

for (unsigned n = 0; n < N_PINS; n++)  {
           byte but = digitalRead (butPins [n]);

if (butLst [n] != but)  {
               butLst [n] = but;

if (LOW == but) {     // button pressed
                   digitalWrite (ledOn, HIGH); // off

if (ledOn == ledPins [n])
                       ledOn = 0;
                   else
                       ledOn = ledPins [n];
               }
           }
       }
   }

static unsigned long msecLst = 0;
   if (ledOn)  {
       if (msec - msecLst > 100)  {
           msecLst = msec;
           digitalWrite (ledOn, ! digitalRead (ledOn));
       }
   }

}

This really helped to replaced with millis!
Appreciate your effort and hard work. Thank you!

clicker test
click speed test

Delay() blocks the execution of the program. So you can't mix timers.

I alway find it a challenge to write code in as few as possible statements.
The blink program could be

void setup() {  pinMode(13, OUTPUT);}
void loop() {   digitalWrite(13,bitRead(millis(),8) );  }

Explanation: bitRead returns the value of the 8th bit of millis(). This bit changes value every 28 ms = 256 ms.

femmeverbeek:
I alway find it a challenge to write code in as few as possible statements.
The blink program could be

I don't find that a challenge at all. I very specifically avoid doing that as I want my code to be easy to understand when I come back to it 6 months later.

Write code so it is as easy as possible to read and to understand. The style of code makes no difference to the compiler.

...R

Hello All,

This is exactly what I was looking for. It uses the original code where delay(100) was used instead of millis(). Turns out this handy function void timeDelay() works like a charm.

the line while(millis()- presentMillis <= 100) //checking if 1000 ms has elapsed was a new one, I never saw a while statement in millis before.

It works! just call it like this timeDelay(); //delay(timer);

Thank all of you for your help and patience.

I found this on the forum and thought it was a reply to my question and I wanted to thank the coder but unbelievably I couldn't find it in my question section, I can't explain how I found it, crazy, If someone sees the post please let me know who sent it. I can't find it in my question section.

const byte button=2;                     
const byte LED=5;                 
boolean blinking = false;
unsigned long blinkInterval=250;                     
unsigned long currentMillis;                       
unsigned long previousMillis;                       
void setup()
{
    pinMode(button,INPUT);
    pinMode(LED,OUTPUT);
    digitalWrite(LED,HIGH);
}
void loop()
{

    if(!blinking )
    {
        currentMillis = millis();

        unsigned long blinkInterval=100;
        if((unsigned long)(currentMillis - previousMillis) >= blinkInterval)
        {
            digitalWrite(LED,!digitalRead(LED));
            //I  added += here to stop jitter and clock drifting as suggested in Arduino forums
            previousMillis += currentMillis;
        }
    } else
    {
        digitalWrite(LED,LOW);
    }

    int reading=digitalRead(button);
    //delay(100);
    //this replaces delay and it works
    timeDelay();//delay(timer);

    if(reading==LOW)
    { blinking =true; }
    else
    { blinking =false; }
}
void timeDelay()
{
  //replaces delay(100);
  unsigned long presentMillis = millis();//read present time of Arduino Timer
  while(millis()- presentMillis <= 100)  //checking if 1000 ms has elapsed
  {
    ; //do nothing
  }
}

These are the same :frowning:

They are blocking code execution for that amount of time.

Try to avoid blocking code in your sketches.


delay(100);

while(millis()- presentMillis <= 100)

Hello All,

I got altered this code I got from post #8 "Thank You" to try and create a pedestrian button for crossing traffic.

I got it working but I had to use a function I googled called SoftReset();

It works, my question is, is it ok to do a software reset or is it frowned upon?

It I didn't use the softreset my button press wouldn't function after my code got to where softreset is

Please advise if you have a safer better way. Thank You

// scan multiple buttons; flash LED corresponding to button pressed
// useing arrays

//original
//byte Pedestrian_Button_Pin_2 [] = { A1, A2, A3 };
//byte Pedestrian_Red_led_Pin_5 [] = { 10, 11, 12 };

//blink red led 5 with button pin 2
// you can't use same button for different led's each button controls 1 led
byte Pedestrian_Button_Pin_2 [] = { 2 };


byte Pedestrian_Red_led_Pin_5 [] = { 5 };

byte Pedestrian_Green_led_Pin_7 [] = { 7 };


//boolean Pedestrian_Green_led_State = false;
boolean Pedestrian_Green_led_State = false;


#define N_PINS sizeof(Pedestrian_Button_Pin_2)

//this array is empty
byte butLst [N_PINS] = {};

unsigned long led_blink_speed = 500;
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

unsigned long Pedestrian_Green_led_Time_On = 3000;



// -----------------------------------------------------------------------------
void setup (void)
{
    Serial.begin(9600);  //without this you won't see Serial.println on your serial monitor

    
    
    //create n here Green led starts off LOW
    for (unsigned n = 0; n < N_PINS; n++)  {
        //turn on all the led's
        digitalWrite (Pedestrian_Green_led_Pin_7 [n], LOW );
        pinMode      (Pedestrian_Green_led_Pin_7 [n], OUTPUT);
    }
    
    //create n here
    for (unsigned n = 0; n < N_PINS; n++)  {
        //turn on all the led's
        digitalWrite (Pedestrian_Red_led_Pin_5 [n], HIGH );
        pinMode      (Pedestrian_Red_led_Pin_5 [n], OUTPUT);

        //read the inputs from all the buttons
        pinMode      (Pedestrian_Button_Pin_2 [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (Pedestrian_Button_Pin_2 [n]);
    }
}

// -----------------------------------------------------------------------------

//this ledOn is the led pin number
int ledOn = 0;

void loop (void)
{
    //millis code here
    unsigned long msec    = millis();

    //notice static here
    static unsigned long msecLst2 = 0;
    if (msec - msecLst2 > 10)  {
         //original code here
         msecLst2 = msec;
        //my edit here
        //msecLst2 += msec;

        for (unsigned n = 0; n < N_PINS; n++)  {
            byte but = digitalRead (Pedestrian_Button_Pin_2 [n]);

            if (butLst [n] != but)  {
                butLst [n] = but;

                if (LOW == but) {     // button pressed
                    
                    Pedestrian_Green_led_State = true;
                    digitalWrite (Pedestrian_Red_led_Pin_5 [0], LOW); // off
                    if (Pedestrian_Green_led_State==true){
                      ledOn = 7; 
                      //digitalWrite (ledOn, HIGH); // off
                    }
                    else
                    {
                     if (ledOn == Pedestrian_Red_led_Pin_5 [n])
                        ledOn = 0;
                     else
                        ledOn = Pedestrian_Red_led_Pin_5 [n];    
                    }
                         
                }
            }
        }
    }

    //here is the led blinking code
    //note: += will not work here in millis
    
    //notice static here variable msecLst for millis
    static unsigned long msecLst = 0;
    
    if (Pedestrian_Green_led_State==false)
    {
      
    
      if (ledOn)  {
        //this controls blikn speed
        //if (msec - msecLst > 100)  {
        if (msec - msecLst > led_blink_speed)  {  
            //original code here note using += here breaks the program no blink of led
            //this works
             msecLst = msec;
            //breaks the blinking led
            //msecLst += msec;
            //Serial.println(ledOn);
            digitalWrite (ledOn, ! digitalRead (ledOn));
              
        } //end second if
        
      } //end first if
     
    
    }
    else if (Pedestrian_Green_led_State==true)
    {
      //Serial.println(ledOn);
      //digitalWrite (ledOn, ! digitalRead (ledOn)); 
      digitalWrite (Pedestrian_Red_led_Pin_5 [0], LOW); // off
      digitalWrite (Pedestrian_Green_led_Pin_7 [0], HIGH); 
      //delay (3000);
      timeDelay();
      Serial.println("Hello");
      digitalWrite (Pedestrian_Green_led_Pin_7 [0], LOW);
      digitalWrite (Pedestrian_Red_led_Pin_5 [0], HIGH);
      bool Pedestrian_Green_led_State = false;
      softReset();
      //exit(0);
      //return;
      
    }

    
} //end void loop


void timeDelay()
{
  //replaces delay();
  unsigned long presentMillis = millis();//read present time of Arduino Timer
  while(millis()- presentMillis <= 3000)  //checking if 1000 ms has elapsed
  {
    ; //do nothing
  }
}

void softReset()
{
asm volatile ("  jmp 0");
}

They are the same? what's the fix for this particular code I posted, not a newly written code

Thanks

larryd:
These are the same :frowning:

They are blocking code execution for that amount of time.

Try to avoid blocking code in your sketches.


delay(100);

while(millis()- presentMillis <= 100)