Achieving Low Power on Adafruit Trinket 2018-05-12

The Adafruit Trinket platform (https://www.adafruit.com/product/1500) is a neat small, Arduino compatible, microcontroller platform. For close to \$5 you get an MCU in a board with pinouts, USB power, and Arduino support. Of course one can customize your own mini platform with better I/O and just the right functions. But at this price point it is hard to justify spending the time to do so unless one is trying to go into a high number of copies of the same design.

My goal on this article is to provide some simple guidelines on how to achieve low power with Adafruit's Trinket platform. My ultimate goal was to re-create a low power remote sensor I had made (using PIC MCU and my own board) which I could run for months on AAA batteries. I started with close to 9mA of power consumption initially and after all the reconfigurations ended with about 40uA while the Trinket was in sleep mode.

For my +3.3V Trinkets the initial power draw I found to be 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. While this was a worthy reduction in and of itself, the MCU datasheet shows that if I optimize things out I should achieve somewhere below 10uA for the MCU. The regulator used on the Trinket platform draws about 30-40uA (in sleep/standby). For me this meant that the Trinket platform should be able to achieve somewhere around 35-45uA power consumption in sleep mode, which was more than adequate for my needs. So the extra effort is really in how to "tweak" the Trinket platform as close to 40uA as possible.

Doing some research I found out the disabling the ADC was really key in improving the "sleep" consumption. After disabling the ADC the power consumption during sleep went down to 40uA, right at my goal. At this point there was really nothing more I could remove or set which I did not need (or that did not move me away from the Trinket platform and into my own custom build).

For this work I relied heavily on the following three resources to get the correct sleep sequence and the watchdog timer operation.:
Since for this project the journey is as important as the final result, the following is really the key findings from my journey:

Enabling wake-up from sleep
To enable wake-up from sleep the following configuration was used. This was needed to wake up the MCU on the same state it was before it went to sleep.
Code:
void enableWatchdog() {
MCUSR = 0;
WDTCR = _BV(WDCE) | _BV(WDE);
WDTCR = _BV(WDIE) | SLEEP_8S;
wdt_reset();
}

Disabling the ADC
To disable the ADC the following configuration was used. This was need to reduced the sleep power consumption to the lowest possible value.
Code:
void disableAdc() {
ADC_SRA = ADCSRA;
ADCSRA = 0;
}

Placing the Trinket to Sleep
The following sequence was required to place the Trinket to sleep. The sequence of the operations actually had an influence on how the device went to sleep and therefore is key in achieving the lowest power consumption.
Code:
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();
}

The following includes are necessary to use the guidelines above.
Code:
#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

As I said before, these modifications allowed me to bring the sleep power consumption on the Trinket platform from 270uA to 40uA which was right in line with the datasheet numbers for the MCU and the regulator. This was just enough for my needs. I hope this is useful to those reading this. Cheers.
picKEY
Author
languer
Views
10,134
First release
Last update
Rating
0 ratings