I recently undertook a project that had the requirement of very low power usage. The board itself consisted of an Atmel ATtiny88, an MCP9808 temperature sensor, a KXCJ9 accelerometer, and a number of LEDs. The board is designed to spend most of its time asleep not using power, but when the temperature is within a certain range, and when it has recently been handled, it needs to wake up and turn on the LEDs. Because the solution needs to be small it is powered by a CR2032 coin cell battery with a roughly 240 mAh capacity at 3v. Thus, the sleep mode of the device must be highly efficient, or I will end up swapping the battery far more than I’d like.
There’s a few obvious ways to reduce power consumption, and these are mostly identified in the ATtiny datasheet:
- Turn off unused microcontroller systems such as the Brown out Detection (BoD), Analogue to Digital Converter (ADC), and unused timers
- Operate at a lower voltage (ie 1.8V or 3V instead of 5V)
- Reduce the clock frequency by setting a clock prescaler or switching to an alternate source
- Use microcontroller sleep modes such as
By doing all of these things I was able to reduce the power consumption of the MCU significantly, but with 240 mAh’s of battery I took a look at the other components on the board and realized that although the MCU had the potential to use up most of this capacity, in the sleep modes which are easily configured it was by far less than the rest of the electronics on the PCB. So here are a few things I did.
Clocking Down the MCU
A really cool feature of the ATtiny48/88 that I discovered is that they have the ability to change the clock pre-scaler on the fly. This allows you to change the operating speed of the MCU at any point in operation. I did the math and this was not actually applicable in my application (the device spends most of it’s time in a deep-sleep mode that doesn’t depend on clock speed) if you are constantly running in active mode you would want to strongly consider what the slowest clock speed you can operate at is, and use it. As you can see in the charts below this is a good way to reduce power consumption.
After looking at the power consumption of all the ICs on the board I realized that I was skipping over some obvious power wasters: resistors! In total the board had 5 pull up resistors: three 10k ohm resistors pulling up the I2C lines and the
RESET line, and two 40k ohm internal pullups from the ATtiny pulling up some inputs from the peripherals.
All tolled, that’s an astonishing 1.05 mA of constant waste, compared to the used by the ATtiny in deep sleep! But what can you do about these lines? Well I realized a couple of things about my project:
- The ATtiny88 has a RSTDISBL fuse that can be set to disable the reset functionality on that pin, so it doesn’t require a pullup at all (although enabling this fuse stops it from being programmed with ISP and instead requires HVPP.)
- My I2C setup has only a single master (the mcu) so it can control when I2C is available.
- Pull-ups are only required when the MCU is on, and should be turned off in sleep.
Based off of these realizations I was able to completely eliminate power consumption from pull-ups by doing these things:
Set the RSTDISBL Fuse
Setting the RSTDISBL fuse enables the external reset functionality of the MCU, so that it no longer requires a resistor/capacitor on this line to eliminate spurious resets – so I simply removed them from the board. This of course has the caveat that the device may no longer be programmed with the convenient 6-pin ISP typically used, but instead requires the much larger High Voltage Parallel Programming (HVPP) algorithm, so be warned! I chose to simply wait to program the fuse until I was completely done coding the board.
Disable Internal Pullups on Sleep
By default the MCU will leave internal pullups enabled when it goes to sleep – so they will continue to waste energy. By manually disabling them immediately before going to sleep and re-enabling them afterwards you can cut down on alot of power consumption.
Place Other Pullups and Peripherals on an MCU Output Pin
Lastly, in order to stop the power waste from the pull-ups on the TWI lines, I connected them to an output on the MCU instead of directly to . This allows me to completely disable the TWI bus before putting the MCU to sleep by disabling that output.
Since the TWI lines were going to be disabled when the MCU is sleeping I figured I might as well place the voltage input to the temperature sensor and the accelerometer on MCU inputs as well (they draw ‘s of power, even in full power mode.) This allows me to completely disable these devices on shutdown, instead of placing them in shutdown mode, which still draws current.
Use External Device Shutdown Modes
Many external devices, such as my accelerometer and temperature sensor, have shutdown modes they can be placed in. This allows I2C communication while reducing power by not continuously measuring. When the device is in its operating mode (not sleeping) I place the devices into their shutdown modes in between readings, otherwise they continuously measure temperature and acceleration, and therefore waste power.
My takeaway from this all is this: always ask what systems on your PCB need to be enabled at any time. If you don’t need a component all the time consider placing it on an additional power circuit that you can completely turn off when not in use (instead of having it draw it’s shutdown current, which will be much higher than whatever the cost of the leakage current imposed by the shutdown circuitry.) In the same vein of thought, always consider which components of your MCU you require, what the lowest voltage you can operate at is, and whether you can afford to clock down the MCU at any step in the process.
Have any other unique, interesting ways to reduce power consumption on embedded projects? Let me know in a comment below or using the contact form!