On this Arduino Day 2014, I thought I would investigate very low power operation of the ATmega328P-PU.
With low power and low energy battery powered devices becoming the norm, the desire to run the microcontroller on low voltage, derived from a coin cell or single AA cell is becoming increasingly popular. Some microcontroller manufactures, including Atmel, Silicon Labs and Holtek have identified this need for "single cell operation" and have built a simple boost converter into their device. Others - particularly, EM Microelectronic, have a core, the EM6682 that will actually run at 0.9V.
So we are going to see a proliferation of low power microcontroller solutions, and as a preliminary investigation into what was to come, I thought I'd explore the performance of a very common micro, as used in all Arduino Unos - the ATmega328P-PU, one of Atmel's PicoPower range.
This post is inspired by Nathan Seidle's Spark Fun post of 2011 "Adventures in Low Power Land".
Nate wanted to get a ATmega328 to run at the lowest possible sleep current whilst used in a digital watch application.
Now typically, an ATmega328P running code at 16MHz will draw about 7mA at 3V3, and whilst asleep, with almost everything turned off, Nate's investigation showed that 1.0uA operation was feasible.
I wanted to explore the territory between these two extremes, and determine whether there were other "safe havens" of operation, which could be usefully be exploited for low power applications.
I wondered whether by a combination of low power techniques it would be possible to run the Arduino at a greatly reduced clock speed, and at a lower voltage, and still have the microcontroller running code and communicating via the UART.
Please note that this investigation is entirely experimental. Several of the ATmega peripherals will no longer function at low voltage and low clock speed - in particular the ADC. Also it should be remembered that just turning on an LED is going to consume many times more microwatts than just the microcontroller running code.
Getting Started
My initial experiments involved using the prescaler on the external 16MHz crystal oscillator. On the standard Arduino Duemillenove with ATmega328 16MHz, the brown out detector is set to 2.7V. With this setting, a supply of 2.8V and the prescaler set to give a 62500Hz clock, the current dropped to a more reasonable 750uA. This was a modest first effort, as even at less than 1mA, a coin cell is only going to last about a week.
I then decided that the 16MHz oscillator was always going to be power hungry, so I followed Nate's example and configured the device as an Arduino Pro 3V3 8MHz using the internal 8MHz oscillator. I also turned off the Brown Out Detector (BOD) because I soon realised that this would prevent the IC running at low voltages.
I divided the 8MHz internal clock oscillator using the maximum prescaler value of 256. This meant that the code was executing at 31250 Hz, or 1/512 of the usual execution speed.
By setting Serial.begin(76800), I was able to get 300 baud communications from the new divided clock frequency.
BOD Alert!
There have been a number of cautionary tales about disabling the BOD, which could lead to corruption of the flash memory, but as this was entirely an exercise in pushing the device to investigate it's lowest limit of supply voltage and current, I accepted that there may come a point where I could no longer guarantee code integrity.
So I disabled the BOD, and the current started to creep down, first to 450uA, then 300uA. I then remembered the post in Jeelabs, about how the MCP1702 regulators start to draw large amounts of current when the supply voltage falls below their minimum LDO point.
So after I removed the MCP1702 regulator and set up a 2.0 V supply, the current dropped massively, remaining close to 100uA. I then wondered if I could lower the supply to closer to 1.8V and see what current consumption would result.
I quickly learned that the CP2102 serial adaptor was supplying current to the application via the Rx line. The greater voltage on the Rx line leaks through the input protection diodes on the Rx input and contributes about 80uA - which caused the super capacitor to charge up! I disconnected the Rx line, to ensure that subsequent measurements were accurate.
A rather poor, unregulated supply made from a potential divider on the 5V supply from my CP2102 cable, allowed me to get a datapoint at 1.8V, where the average current was close to 60uA. The individual characters sent from the UART at 300 baud, were clearly visible in the current measurement.
Unfortunately, I didn't have access to a variable low voltage power supply, so I charged up a 0.22F super capacitor and ran the ATmega from this, monitoring the voltage and current drawn, via the voltage drop across a 1000 ohm resistor in the +ve supply lead, as the super capacitor slowly discharged. Here are some voltage and current way-points during the discharge - it really highlights how dropping the supply voltage reduces the power (microwatts) drastically:
Volts Current Power
3.30V 450uA 1485uW
2.50V 100uA 250uW
2.00V 70.5uA 141uW
1.95V 64.7uA
1.90V 62.5uA
1.85V 61.3uA
1.82V 60.0uA
1.80V 58.9uA 106uW
1.75V 57.6uA
1.70V 55.6uA
1.65V 53.9uA
1.60V 51.1uA
1.55V 48.2uA
1.50V 44.5uA 66.75uW
1.45V 39.8uA 57.71uW
1.44V 38.7uA - Dead!
Current consumption shoots up after 2.5V! |
Power / uW in red also increases dramatically |
Using this method I was able to show that code was still running at 1.71V supply and 55.8uA average consumption - printing serial to the terminal every second or so.
At 1.68V supply the CP2102 would no longer correctly receive characters - although the ATmega was still sending them - but at a much reduced amplitude.
So the ATmega328P-PU will still run code at 1.45V consuming about 58 microwatts of power.
Later in the evening, I realised that it was my CP2102 serial adaptor cable Rx input that was giving up at 1.7V, and failing to read the very low voltage signals from the UART. I continued to monitor the ATmega UART output with the scope running code right down to a supply voltage of 1.43V and 39.5uA of current. The ATmega328P-PU was actually running on 56.5 microwatts of power.
If you are concerned about disabling the BOD, then assume that the minimum safe supply voltage is stated as 1.8V in the datasheet, for clock frequencies below 4MHz. Set the BOD to this lower limit and accept that you can run the IC at between 60 and 100uA, depending on clockspeed and what peripherals you have enabled.
Applications
So why is this important? It means that we can have very low power consumption from Arduino based hardware, making it compatible with Bluetooth low energy. A simple interrupt from the BLE module can wake the '328 to whatever clock frequency is needed to handle the RF data.
Additionally, it allows new power sources to be developed, such as energy harvesting devices, or even a small 3" x 2" photovoltaic collector, illuminated by ambient lighting is sufficient to power the microcontroller.
Clearly their will be a compromise between fast and slow clocking, and a combination of spending long periods asleep, and waking up to run at high clock speed, may be more advantageous than plodding along at 31kHz. It's definitely a tortoise and hare situation, and the overall winner is likely to be highly application dependent.
Photos and more detail to follow.