- Blog entry posted in 'Electronics and Other Ramblings...', April 17, 2018.
- http://www.gammon.com.au/forum/id=11497
- https://github.com/tdicola/Low_Power_Wifi_Datalogger/blob/master/Example_2_Power_Down_Sleep/Example_2_Power_Down_Sleep.ino
- https://forums.adafruit.com/viewtopic.php?f=25&t=108808
A little while ago I decided to resurrect some wireless sensors and update them using Adafruit's Trinket platform (https://www.adafruit.com/product/1500). It has been a while since I used the Trinket platform so I had to relearn some of the details. My goal was to re-create a low power remote sensor which I could run for weeks or months on batteries. At the end I was able to get the Trinket power draw to about 40uA while not operating. What follows will be short and sweet, but should help anyone trying to lower power from a standard Trinket.
For the +3.3V Trinkets the initial power draw was around 9mA. After removing the power LED (R4 and/or PWR LED) the power dropped to around 5mA. Putting the device to sleep dropped the power consumption to roughly 270uA. Disabling the ADC got it down to 40uA. At this point there was nothing more I could remove or set which I did not need. The regulator datasheet shows that while in "sleep mode" its ground current is somewhere around 30-40uA. This shows that most of this additional consumption is on the regulator itself. If one wanted to get into single digits uA the regulator could be removed, but for my project 40uA is adequate, and I was pretty happy the numbers all matched up the expectations.
For this work I relied heavily on the following three resources to get the correct sleep sequence and the watchdog timer operation.:
Following are some additional tidbits that proved useful.
To enable the wake-up from sleep I configured the watchdog as follows:
void enableWatchdog() {
MCUSR = 0;
WDTCR = _BV(WDCE) | _BV(WDE);
WDTCR = _BV(WDIE) | SLEEP_8S;
wdt_reset();
}
To disable the ADC I configured the ADC power register as follows:
void disableAdc() {
ADC_SRA = ADCSRA;
ADCSRA = 0;
}
To go to sleep I used the following sequence:
void gotoSleep() {
enableWatchdog();
disableAdc();
power_all_disable();
// --- start timed sleep sequence (order of events matter) --- //
noInterrupts();
sleep_enable();
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_bod_disable();
interrupts();
sleep_mode();
// --- end timed sleep sequence (order of events matter) --- //
// - WAKEUP FROM SLEEP - //
wakeupFromSleep();
}
Includes needed:
#include <avr/sleep.h> // Needed for sleep_mode
#include <avr/wdt.h> // Needed to enable/disable watch dog timer
#include <avr/power.h> // Needed to enable/disable power modes
Cheers ...Comments