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)
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
}