Sleeping CPU - It wakes up once before finally going to sleep for good

I notice when it times out and goes to sleep (set to 10 seconds for testing purposes), it wakes back up, then goes to sleep again for good (until I trip the interrupt pin). My interrupt is set as CHANGE, not LOW. I wonder if this is why it does this, or if I have a little problem in my code. Here’s the code, this is what puts it to sleep in the main loop:

long idleTime = 10000; //1800000; //if we’ve been idle this long, we’ll go to sleep
if (millis() - wakeTime > idleTime) { //has it been 30 minutes since the ants were fed?
digitalWrite(receiverPowerPin, HIGH); //this turns OFF receiver
sleep_now(); //if the mower’s still in use, it’ll wake right back up from the interrupt on the mercury switch
//WE WAKE UP HERE, SO RESET/RESTART THINGS:
Serial.println(“We’re awake again!”);
wakeTime = millis();
digitalWrite(receiverPowerPin, LOW); //this turns ON receiver
}
}

And this is the sleep_now() routine:

void wake ()
{
// cancel sleep as a precaution
sleep_disable();
// must do this as the pin will probably stay low for a while
detachInterrupt (0);
} // end of wake

void sleep_now() {
// disable ADC
ADCSRA = 0;
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// Do not interrupt before we go to sleep, or the
// ISR will detach interrupts and we won’t wake.
Serial.println(“Going to sleep”);
Serial.flush();
delay(50);
noInterrupts ();
if (!systemError) { //systemError means there’s a big problem, so don’t bother waking back up
attachInterrupt (0, wake, CHANGE); // will be called when pin D2 goes low
}
// turn off brown-out enable in software
// BODS must be set to one and BODSE must be set to zero within four clock cycles
MCUCR = bit (BODS) | bit (BODSE);
// The BODS bit is automatically cleared after three clock cycles
MCUCR = bit (BODS);
// We are guaranteed that the sleep_cpu call will be done
// as the processor executes the next instruction after
// interrupts are turned on.
interrupts (); // one cycle
sleep_cpu (); // one cycle
delay(1000);
sleep_disable(); //wake up here

}

Did you resolve the problem?

No. I just assumed it has something to do with the fact the I’m waking the Atmega328 with a CHANGE interrupt. In Nick Gammon’s power saving article he said…
Oh wait- I think it’s been updated. It did say an interrupt detecting a LOW would wake it, but now it says a CHANGE will wake it. For whatever reason, mine acts strange. In my test sketch, if I have it go to sleep after 10 seconds, it will go to sleep after 10 seconds, then wake up, then go to sleep again after another 10 seconds, and not wake up until the mercury switch is toggled. It seems to do this regardless of whether the mercury switch is open or closed when it first goes to sleep. So to fix the problem I will just cut the time in half that I actually want it to before sleeping. Not a very good fix, but I don’t know what else to do. I don’t like it that I don’t know what’s wrong, but I don’t know what else to do. Again, here is the code, it’s fairly short and simple. I wonder if I have a coding problem, but I can’t find it.

Fireant_Feeder_Ver_2_0.ino (5.57 KB)

EEPROMAnything.h (501 Bytes)

    attachInterrupt (0, wake, CHANGE);  // will be called when pin D2 goes low

See: http://www.gammon.com.au/interrupts

Scroll down to where it says:

Something to be aware of is that these flags can be set before you attach the interrupt handler. For example, it is possible for a rising or falling level interrupt on pin D2 to be "flagged", and then as soon as you do an attachInterrupt the interrupt immediately fires, even if the event occurred an hour ago.

That will be why it is firing twice. The fix is on that page.

Thanks! I've read that page through a couple times and think I'm beginning to understand it. A little bit, anyway. I'll see if I can fix my double wake up issue.