Question (TL;DR): what is the optimal method to deep sleep (to run an ATtiny45 or ATmega on batteries for 1+ year) but still be able to detect a button press? Is it possible to deep sleep until a button is pressed?
I'm using a classic "debounce" method to detect a button press:
int buttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
pinMode(2, INPUT);
}
void loop() {
int reading = digitalRead(2);
if (reading != lastButtonState) { lastDebounceTime = millis(); }
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
// Button pressed, do something here!
// In my actual code, it sends a packet via RF 433 Mhz
}
}
}
lastButtonState = reading;
// snore(20); // TinySnore here
}
My ATtiny45 should run during 1 year on 3 AA batteries, so I added a deep sleep using TinySnore. It works, and made the consumption go from more than 1mA to 0.2mA (@1 Mhz).
I know it's possible to go down to 5 µA if I snore(1000);
but then obviously it won't be able to detect a button press.
I tried various sleep values: snore(10);
, snore(20);
, snore(50);
, etc. but I didn't get consistent results.
Thus the question: how to deep sleep until a button is pressed?
I was thinking about using attachInterrupt()
but then what kind of sleep should we use? snore()
? delay()
?
#include <avr/sleep.h>
withsleep_cpu
and friends, woken up by an interrupt. Nick Gammon has a pretty extensive forum post on this: gammon.com.au/forum/?id=11497 (github.com/connornishijima/TinySnore/blob/master/src/… uses the same functions but only seems to be able to do timer-wakeups)attachInterrupt()
, the interrupt service routine (ISR) for the necessary vectors are hooked directly, e.g.ISR (PCINT0_vect) { .. }
. An example withattachInterrupt
is in the first post with the code labeledWaking from sleep with a signal
, which matches your button better. When an interrupt is configured for a pin, a change event will automatically wake the CPU from sleep. See datasheet (farnell.com/datasheets/1698186.pdf) section 7.1 "Sleep Modes", "INT0 and pin change"