Hi,
sorry for any "inappropriate" language... this is my first post.
I'm working on a new project and I'm trying to put the Arrduino Uno in sleep mode and wake it using using pin interrupt through a single button on pin A0, thus push once go to sleep, push again wake up. The reason I'm not using the canonical interrupt is that they are already used for different purposes.
I tested the basic logic using messages on the console, and it worked fine, but when I enable the sleep mode it doesn't wake up, it looks like Arduino is not going in the interrupt function, why ?? What am I doing wrong ?
The code is the following:
when you pressed the sleep button, the Arduino goes to Sleep. The moment you release the button (thereby pulling the signal high), the Arduino wakes up because that would qualify a PIN change (from LOW to HIGH)
Also, there's this thing called "bounce" where any physical button will register multiple UPs-and-DOWNs before settling, and since the Arduino samples the state at millions of times per second, there's a good chance that it will register this multiple states in between
Here's some article online about button debouncing
when you pressed the sleep button, the Arduino goes to Sleep. The moment you release the button (thereby pulling the signal high), the Arduino wakes up because that would qualify a PIN change (from LOW to HIGH)
Also, there's this thing called "bounce" where any physical button will register multiple UPs-and-DOWNs before settling, and since the Arduino samples the state at millions of times per second, there's a good chance that it will register this multiple states in between
Here's some article online about button debouncing
Well if the interrupt is fired on the low to high then the Arduino should go in sleep mode and immediately wake up, the issue is that it goes in sleep mode but it doesn't wake up anymore.
I'm aware of the bouncing issue but also this should not be the reason why the board doesn't wake up, since Arduino should go in sleep mode (and indeed it goes in sleep mode) as soon as the button is pressed and the loop execute the code in the if block for the first time.
I don't understand how it can be going into sleep mode. It appears you never actually tell it to go to sleep. Try changing line 44 from sleep_mode() to sleep_cpu().
Also, be aware that the flag bit is cleared by writing a one to it. So you would OR the existing value with 2 to clear it. Or just write a 7 to the PCIFR
You'll have to add code to make sure the switch has been released and stays high for, say, 1/4 second, then clear the flag bit, before you do anything with it after it has been pressed. I would also clear the flag bit in the ISR after you disable the interrupt.
Here's a function that would wait for the button to be released and remain high for 0.1 second, then clear the flag bit. It would be called before you enable the interrupt, and after you wake up.
void waitforrelease() {
unsigned long oldMilli = millis();
int countdown = 100;
while (countdown) {
unsigned long newMilli = millis();
if (newMilli != oldMilli) {
oldMilli = newMilli;
countdown--;
if (digitalRead(sleepbtn) == LOW) countdown = 100;
}
}
PCIFR = 2;
}