Delay() not work in wake up after power down

Hi Guys,

I'm using Arduino mini-Pro (3.3V, 8MHz) and go to power down normally using the powerdown library LowPower.h. The device is waken up by IO interrupt and it can do so successfully. However, in my wakeup routine, the delay() function does not function properly. Can anyone help me on this?
Below is my main loop:

void loop() 
{
    // Allow wake up pin to trigger interrupt on low.
    attachInterrupt(digitalPinToInterrupt(UP),press_up , LOW);
    attachInterrupt(digitalPinToInterrupt(DOWN), press_down, LOW);
    
    // Enter power down state with ADC and BOD module disabled.
    // Wake up when wake up pin is low.
    // Sleeping here......
    Serial.println("Sleep now!");
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
}

Here is my wakeup routine:

void press_up()
{
    // Just a handler for the pin interrupt.
    Serial.println("UP key is pressed!");
    detachInterrupt(digitalPinToInterrupt(UP)); 
    ADCSRA = keep_ADCSRA;
    bat_level = analogRead(ADC); //Measure battery
    if (bat_level > THRESHOLD) digitalWrite(LO,HIGH); //turn on LED if battery okay
    digitalWrite(M1,HIGH); //Rotate the motor
    delay(MOVE_TIME); //for one second
    digitalWrite(M1,LOW); //Stop and press the key for a while
    delay(MIN_TIME)

;

Thanks,
Henry

Interrupts are disabled in an ISR. The delay() function (and millis()) uses interrupts. Don't expect delay() or millis() to work in an ISR.

Thanks!! Then how to enable the interrupts?

@Henry_Chan, please read How to get the best out of this forum and, as described,apply code tags to the code that you posted. Thanks

I see that you are using Serial print in the ISR, as well. Serial print also uses interrupts.

You don't. What you should do is, in the ISR, only set a flag that tells the main program that the interrupt occurred. Then in the main program (in the loop() function), if the flag is set, run the code that is now in the ISR and clear the flag.

So the ISR looks like:

void press_up()
{
     bool pressUpOccurred = true;  // flag is set
}

and in loop() something like:

if(pressUpOccurred)
{
     Serial.println("UP key is pressed!");
    detachInterrupt(digitalPinToInterrupt(UP)); 
    ADCSRA = keep_ADCSRA;
    bat_level = analogRead(ADC); //Measure battery
    if (bat_level > THRESHOLD) digitalWrite(LO,HIGH); //turn on LED if battery okay
    digitalWrite(M1,HIGH); //Rotate the motor
    delay(MOVE_TIME); //for one second
    digitalWrite(M1,LOW); //Stop and press the key for a while
    delay(MIN_TIME)
    pressUpOccurred = false;  // flag is cleared
}

Many Thanks! It works perfectly now!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.