Blinking LED for 20 exact seconds within a While loop

Hey guys,

I don't know if this question is supposed to be in this cateogory but please help. I am trying to develop my first project in which I have an LED, a button and a buzzer, and what I want is that when the button is pressed, the LED blinks for 20 minutes, then the buzzer makes a sound and then the LED becomes like constantly lit for 5 minutes.

For the 20 and the 5 minutes I am using a while loop with millis() but when I am actually like testing it out and having the value of seconds be <= 1200000 (20 minutes in ms), I have a cronometer and it doesn't like stop. I believe this is probably due to the delay(500) i am using for the LED to blink and this probably has an easy fix and method but as I said I am new to this so any help would be appreciated. I am including the code below if you guys want to point out anything else I may be making a mistake with.

int redLED = 3;
int blueLED = 4;
int button = 6;
int buzzer = 5;

int starttime = 0;
int endtime = 0;



void setup() {
 Serial.begin(9600); //remove when end
 pinMode(A0, INPUT); //potentiometer
 pinMode(buzzer, OUTPUT);
 pinMode(redLED, OUTPUT);
 pinMode(blueLED, OUTPUT);
 pinMode(button, INPUT_PULLUP);
 
 digitalWrite(redLED, LOW); //initialize all these as off, LEDs as well as we need to see in the void loop which one will be turne on
 digitalWrite(blueLED, LOW);
 digitalWrite(buzzer, LOW);

}

void loop() {

  digitalWrite(redLED, HIGH);
  while (digitalRead(button) == HIGH){ //while loop that stops everything until user presses the button to start

    
    }


  digitalWrite(buzzer, HIGH);
  delay(100);
  digitalWrite(buzzer, LOW);
  starttime = millis();
  endtime = starttime;
  while ((endtime - starttime) <=1200000) // do this loop for up to 1000mS = 1S, 20x60x1000=1200
  {
    digitalWrite(redLED, LOW);
    delay(500);
    digitalWrite(redLED, HIGH);
    delay(500);
    endtime = millis();
  }

  digitalWrite(buzzer, HIGH);
  delay(100);
  digitalWrite(buzzer, LOW);

 starttime = millis();
  endtime = starttime;
  while ((endtime - starttime) <=120000) // do this loop for up to 1000mS = 1S, 20x60x1000=1200
  {
    digitalWrite(redLED, HIGH);
    endtime = millis();
  }
 
digitalWrite(buzzer, HIGH);
  delay(2000);
  digitalWrite(buzzer, LOW);
}```

Hi, your variables are declared as Int (-32,768 to 32,767) they will overflow. You should declare them as long ( -2,147,483,648 to 2,147,483,647).

redLED was not declared

hey sorry, it was declared I just copied and pasted wrong, missing the first line

or
The header pin number for the redLED was not declared?

No, redLED was not declared just like I wrote it.

@atmnsm678413 found the answer.

Do you mean the led appears to be lit but is not actually lit? Almost but not quite constantly lit?

So you are not actually testing it but you are almost testing it?

The chronometer is not happy about stopping?

Which one of the following will work?

byte redLED;   //declaration deos not imply definition

or

byte redLED = 3; //definition does imply declaration

No, thank you, Off Topic Bear.

you need to constantly monitor millis()

look this over

  • use a sec/half-sec timer and wait that many sec/half-sec
  • using half-sec timer to toggle an LED once every sec
  • use a simple sequenced to wiat to start, wait the 20 minutes and run the buzzer
#undef MyHW
#ifdef MyHW
int redLED  = 12;
int blueLED = 11;
int buzzer  = 10;
int button  = A1;
enum { Off = HIGH, On = LOW };      // LED

#else
int redLED  = 3;
int blueLED = 4;
int button  = 6;
int buzzer  = 5;
enum { Off = LOW, On = HIGH };      // LED
#endif

const unsigned long TwentyMinsHSecs = 10;   // 2 *20L *60L; // small test values
const unsigned long TwoMinsHSecs    =  4;   // 2 *2L  *60L;

const unsigned long HalfSecMsec     = 500;
      unsigned long msec0;
      unsigned halfSecs;


enum { Idle,Timer, Buzzer };
int state = Idle;

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

    // clock seconds
    if (0 < halfSecs && msec - msec0 >= HalfSecMsec)  {
        msec0 += HalfSecMsec;
        halfSecs--;
        digitalWrite (blueLED, ! digitalRead (blueLED));  // toggle LED
    }

    // check state
    switch (state)  {
    case Idle:
        Serial.println ("Idle");
        if (LOW == digitalRead (button)) {  // wait for start button press
            state    = Timer;
            msec0    = msec;
            halfSecs = TwentyMinsHSecs;     // set timer

            digitalWrite (redLED, Off);
            digitalWrite (buzzer, On);
            delay (100);
            digitalWrite (buzzer, Off);
        }
        break;

    case Timer:
        Serial.println ("Timer");
        if (0 == halfSecs)  {               // wait for timer to expire
            state    = Buzzer;
            halfSecs = TwoMinsHSecs;        // set timer

            digitalWrite (buzzer,  On);
        }
        break;

    case Buzzer:
        Serial.println ("Buzzer");
        if (0 == halfSecs)  {               // wait for timer to expire
            state    = Idle;

            digitalWrite (buzzer,  Off);
            digitalWrite (redLED,  On);
        }
        break;
    }
}

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

    pinMode (button,  INPUT_PULLUP);

    pinMode (buzzer,  OUTPUT);
    pinMode (redLED,  OUTPUT);
    pinMode (blueLED, OUTPUT);

    digitalWrite (buzzer,  Off);
    digitalWrite (blueLED, Off);
    digitalWrite (redLED,  On);
}

For test purposes, take 20 sec for 20 min.

Given below a sketch to --
Blink the onBoard LED of UNO R3 for 20 sec at 1 sec interval using millis() function.

unsigned long pr1Millis = millis();
unsigned long pr2Millis = millis();
byte ledState = HIGH;
byte redLED = 13;

void setup() {

  pinMode(redLED, OUTPUT);

  do  //blinking redLED for 20 sec at 1 sec interval
  {
    digitalWrite(redLED, ledState);
    if (millis() - pr1Millis >= 1000) {
      ledState = !ledState;
      pr1Millis = millis();
    }
  } while (millis() - pr2Millis <= 20000);
  digitalWrite(redLED, LOW);
}

void loop() {
  
}