licketylips
licketylips

Reputation: 13

Arduino nested timers

I have an Arduino Uno which hads an LED on pin 2 and audible alarm on pin 9. I am wanting a sketch to do the following Using multiple timers ;

1.blink a Led forever , 2.Sound initial 1st alarm for 1min after the first 6 mins (do this only once) then; 3. Alarm off for 1 min; 4. Sound alarm for 1 minute 5. Do steps 3 & 4 forever (whilst blinking the LED throughout)

The code below will blink the led & sound the alarm (& turn it off) in a loop , however I'm unable to get the initial first alarm to work. Any help is appreciated, I'm not wanting to use the delay function as it stops the LED.

const int LEDpin = 2;
const int ALMpin = 9;

const long LEDonDuration = 200;// ON time for LED
const long LEDoffDuration = 300;// OFF time for LED

const long ALMonDuration = 60000;      // Alm ON duration (milliseconds) 1mins=60000 
const long ALMoffDuration = 120000;      // Alm OFF duration (milliseconds) 2mins=120000 

long rememberTime=0;// this is used by the code for LED
long rememberALMTime=0;// this is used by the code for ALM

int LEDState =LOW;// initial state of LED
int ALMState =LOW;// initial state of ALM

int value = 0;

void setup() {

  pinMode(LEDpin,OUTPUT);// define LEDpin as output
  digitalWrite(LEDpin,LEDState);// set initial state
  digitalWrite(ALMpin,ALMState);// set initial state
    
//  pinMode (9, OUTPUT);
  Serial.begin (9600); // initialize serial communications:
  Serial.println("Alarm pin Status = LO");
   }
void loop() {
      if( LEDState ==HIGH )
       {
          if( (millis()- rememberTime) >= LEDonDuration){   
          LEDState =LOW;// change the state of LED
          rememberTime=millis();// remember Current millis() time
          }
       }
       else
       {   
          if( (millis()- rememberTime) >= LEDoffDuration){     
          LEDState =HIGH;// change the state of LED
          rememberTime=millis();// remember Current millis() time
          }
       }

if( ALMState ==HIGH )
 {
    if( (millis()- rememberALMTime) >= ALMonDuration){   
    ALMState =LOW;// change the state of ALM
        Serial.println("Pin Status = LO");
    rememberALMTime=millis();// remember Current millis() time
    }
 }
 else
 {   
    if( (millis()- rememberALMTime) >= ALMoffDuration){     
    ALMState =HIGH;// change the state of ALM
        Serial.println("Pin Status = HI");
    rememberALMTime=millis();// remember Current millis() time
    }
 }

 digitalWrite(LEDpin,LEDState);// turn the LED ON or OFF
 digitalWrite(ALMpin,ALMState);// turn the ALM ON or OFF
}

Tried starting an initial delay bit it stopped the LED.

Upvotes: 0

Views: 47

Answers (1)

ChipChop Gizmo
ChipChop Gizmo

Reputation: 401

I think it should be written like this:

const int LEDpin = 2;
const int ALMpin = 9;
int LEDState = LOW;
int ALMState = LOW;

bool init_alarm_ done = 0; //track when the initial alarm is done

unsigned long led_blink_timer = 0;
unsigned long alarm_timer = 0;


void setup() {

  pinMode(LEDpin,OUTPUT);// define LEDpin as output
  digitalWrite(LEDpin,LEDState);// set initial state
  digitalWrite(ALMpin,ALMState);// set initial state
    
  Serial.begin (9600); // initialize serial communications:
  Serial.println("Alarm pin Status = LO");
}




void loop() {

      if(millis() - led_blink_timer >= 60000){
         if(LEDState == HIGH){
            LEDState = LOW;
         }else{
            LEDState = HIGH;
         }
         digitalWrite(LEDpin,LEDState);

         led_blink_timer = millis();
      }

      if(init_alarm_done == 0){ //we haven't completed the first alarm after 6 mins
         if(millis() >= 360000){ // 6 mins have passed
            ALMState = HIGH;
            init_alarm_done = 1; // flag that init alarm is done so we don't check this if block again
            alarm_timer = millis(); // reset the 1 min timer
            digitalWrite(ALMpin,LEDState); // sound the alarm

         }
      }else{ // we have completed the first 6 mins alarm wait
         if(millis() - alarm_timer >= 60000){ // 1 minute has passed
            if(ALMState == HIGH){
               ALMState = LOW;
            }else{
               ALMState = HIGH;
            }
            alarm_timer = millis(); // reset the timer
            digitalWrite(ALMpin,LEDState); // sound the alarm
         }
      }

}

This should work and it's non blocking. The idea is tho check the timers first and then do the check for pins HIGH/LOW state otherwise you end up duplicating the checks.

Also, in your loop code you are constantly pushing the alarm/led pins to LOW/HIGH at the end, you don't need to do that. Once you set a pin to LOW/HIGH it will keep that state.

Hope this helps

Upvotes: 0

Related Questions