I have a application that generates PWM to lit a LED.
to maximize the battery life, I would like the CPU to sleep instead of a busy-loop (delay()) to delay.
this is my current setup:
#include <avr/sleep.h>
#include <avr/wdt.h>
ISR(WDT_vect)
{
wdt_disable();
sleep_disable();
}
void sleep(uint8_t mode, uint8_t wdto)
{
// set WDCE, allows update for 4 clock cycles
WDTCSR |= _BV(WDCE) | _BV(WDE);
// set WDT timeout and enable interrupt
WDTCSR = (wdto << WDP0) | _BV(WDIE);
// set the sleep mode
set_sleep_mode(mode);
sleep_enable();
// go to sleep
sleep_mode();
}
void setup()
{
pinMode(13, OUTPUT);
}
uint8_t xxx = 0;
void loop()
{
analogWrite(13, xxx);
sleep(SLEEP_MODE_IDLE, WDTO_30MS);
++xxx;
}
It seems like the code is functioning correctly, at least my LEDs are changing brightness.
but does my CPU actually really sleeps?
I suspect it should work like this:
- Active: sets the PWM duty and WDT timeout, then go to SLEEP_MODE_IDLE.
- Idle: …
- Active: woken up by timer interrupt, update output, then goto 2.
- Active: woken up by watchdog interrupt, goto 1
I have no instrument to really measure the power consumption, but will my code work as what I thought?
or when the CPU is woken up by the timer ISR, it’s just gonna stay active after the ISR is served?