The first test showed that there is a lot of power reduction potential in having the controller sleep when it doesn’t have to do something. Now it’s time to look in detail to the possibilities of saving power both while the controller is running and during sleep. With simple test sketches measurements are done with different configurations to see the effects and to find out how low power consumption can be.
Reducing power while computing
The following tests are done with an ATmega328P and a supply voltage of 5V. Supply current is measured. The chip runs at 8MHz on the internal clock source. First floating inputs are avoided and then hardware inside the controller is successivley shut down using the <avr/power.h> library.
- around 12.4mA in standard mode. Nothing is changed after reset. The sketch contains only setup() and loop(). The digital and analog pins of the controller are unconnected.
- 8.72mA (!!) with digital pins 0 to 13 unconnected but set as output and state Low.
- 6.93mA (!) with analog pins 0 to 5 connected to GND.
- 6.99mA with SPI shut down.
- 6.68mA with SPI and timer0 shut down.
- 6.64mA with SPI, timer0 and timer1 shut down.
- 6.55mA with SPI, timer0, timer1 and timer2 shut down.
- 6.23mA with SPI, timer0, timer1, timer2 and TWI shut down.
- 6.18mA with SPI, timer0, timer1, timer2, TWI and Uart0 shut down.
- 6.02mA with SPI, timer0, timer1, timer2, TWI, Uart0 and ADC shut down.
Now surprisingly or not, we see that the highest reduction is achieved by avoiding floating inputs. Setting all digital pins to output and low and connecting all analog inputs to GND saves 44% of power! This is much more than the reduction by switching off unused hardware. So for maximum reduction of power consumption we do both 🙂
Reducing power while sleeping
The ATmega328P knows different sleep modes. The one with the lowest power consumption is SLEEP_MODE_PWR_DOWN. All other sleep modes consume more power but have more possibilites for wakeup. Even in SLEEP_MODE_PWR_DOWN the supply current depends on what parts of the hardware are shut off. So let’s do some measuring with VCC = 5V. All these measurements are done in SLEEP_MODE_PWR_DOWN:
- 148µA “standard”. All digital and analog I/Os not connected, Brown-out detection enabled, Watchdog timer disabled.
- 142µA with all digital I/Os set to output and low and all analog inputs connected to GND, Brown-out detection enabled, Watchdog timer disabled.
- 28.4µA with all digital I/Os set to output and low, all analog inputs connected to GND, ADC shut down (ADCSRA = 0), Brown-out detection enabled and Watchdog timer enabled.
- 22.1µA with all digital I/Os set to output and low, all analog inputs connected to GND, ADC shut down (ADCSRA = 0), Brown-out detection enabled and Watchdog timer disabled.
- 6.4µA with all digital I/Os set to output and low, all analog inputs connected to GND, ADC shut down (ADCSRA = 0), Brown-out detection disabled and Watchdog timer enabled.
- 0.3µA with all digital I/Os set to output and low, all analog inputs connected to GND, ADC shut down (ADCSRA = 0) and Brown-out detection disabled and Watchdog timer disabled.
So here we are: below 1µA. Can’t tell if it’s really 0.3µA. With both of my instruments (old Fluke 45 and Benning MM2) I read 0.3µA respectively 0.1µA. But this is both at the lower end of the instruments’ range.
During several tests I had some problems to wake up the ADC and get reliable results at the beginning. ADC is shut down by setting the control register ADCSRA to zero. I found out an easy way to recover: Save ADCSRA to a variable before shut down. After wakup write back the content of the variable to ADCSRA.
About Brown-out Detection
The task of Brown-out Detection (BOD) is to reset the controller when supply voltage is too low for safe operation. BOD can be set to several levels or shut off. The BOD levels are 4.3V, 2.7V and 1.8V. The standard is 2.7V which is good when you have some 3.3V devices connected. In our tests the controller can also work with a lower voltage. During the first tests BOD was completely shut off to get to the lowest possible supply voltage. Also power consumption during sleep is reduced by 22µA when BOD is inactive. Both increases uptime. It turned out (as expected) that writing to EEPROM with a supply voltage below 1.8V is unsafe.
For our system we want to have both: BOD active but no power consumption by BOD while sleeping. The solution is to turn on BOD to 1.8V setting the appropriate fuse and then disabling BOD while in sleep mode. BOD is then automatically re-enabled at wakeup. So we get a safe operating system but could reduce supply current in sleep mode.
In the next post we will do a “reality check” to see how long our uptime can be…
Your measurements correspond well with my own findings.
Thanks for your comment! It is good to know that somebody else has found the same values 🙂 I’m planning to come up with some other things…
Thank you for these awesome articles! I have been looking into power consumption on MCU’s and trying to find ways to reduce it. You have given me A LOT of new information about the subject! Thank you, and keep up the good work!
Thanks for your comment. Good to see that my work is useful for others 🙂
Hi, thanks for your nice clear tests. I’m just wondering how you are going about tying your analog pins to GND? Cheers.
Thanks. Awesome information for a low power Arduino. Looking into what is required to do a real low power system that will work off energy collected from various free sources. Gives me an idea of what is possible. Now just need to understand how the different modes can be used in my device.
Most likely, there is just a direct connection to ground from each of the pins. I was wondering, “Why?” It turns out that in a floating input that is near the threshold voltage, the constant switching wastes power. This makes total sense, and is generally speaking, the same reason to lower the clock frequency.
Details explained in this TI paper: http://www.ti.com/lit/an/scba004c/scba004c.pdf
Pingback: Arduino - Sleep etc | Pearltrees
Im new to the arduino. Im just wondering how can u get all the measurement of current consume by each different case? Is that just simply use the multimeter to measure the current or need to set up something else special to obtain all that value?
I simply did it with a Fluke 45 bench multemeter.