Progress Bar

Skip to main content

Jaycar
...

Arduino Power Saving and Battery Night Light

Arduino Power Saving and Battery Night Light

Difficulty

Summary

The Arduino IDE and boards make it very easy to design and prototype a circuit, and even build a circuit to do something useful. But what if you've got a circuit you need to run off batteries? It turns out that part of the Arduino's flexibility also means it uses more power than a dedicated circuit might. In this article, we've give you a few ideas about how you can tweak your 'duino to use less power, and hopefully run longer. For most of the things we're going to show you, we're going to use the Uno running an 'empty' sketch, so you can easily try these experiments out for yourself on a bare Uno board. Of course an Arduino that does nothing isn't much use, but some of the software power reduction options will disable some functions- it's about what's going to work with your application.

If you want to estimate how long your project would last, you need to know the capacity of your batteries in mAh (milliamp-hours), and how many milliamps of current your project uses. For example, a project that uses 50mA running from a 2000mAh battery (typical for some NiMH rechargeables), it would be expected to run for 2000/50 or 40 hours. This is only an estimate, as all batteries and all circuits tend to vary slightly. If it's a critical application, it's probably worth testing.

The first place to look for power saving is in the hardware itself. Most Arduino boards have more features than you would usually use (at the same time). There's a few ways to work around this- either using the Arduino board differently, or building your own Arduino-compatible circuit.

You might remember from our Powering Your Arduino article, that there are four ways to power you're an Uno. There's the VIN pin, DC jack, 5V pin and USB. If you're using batteries, you probably won't be using USB, and the VIN pin and DC jack are essentially the same as far as the Arduino is concerned. I did the following comparison of power supplies:

Input

Power Source

Current

DC jack

7.5V - 5xAA batteries

47mA

5V

4.5V - 3xAA batteries

37mA

We've used 5xAA batteries for the DC jack because the onboard regulator needs at least 7 volts, while the 5V pin is actually happy with anywhere between 4 and 5.5 volts. The 10mA difference is due to the fact that the voltage regulator needs to constantly use about 10mA to maintain its output. So just by using the 5V pin, we can approximately halve the number of batteries we'd need to use.


There's actually a few options for power-saving that can be activated in software by running commands inside the sketch itself. By default, the ATMega 328P IC runs at 16MHz. If you have a sketch that doesn't need to spend all its time processing data, you might be able to run the processor slower, so it's not working as hard and using as much power. We do this by changing the prescaler, and the prescaler settings can be changed at any time, so even if you need spend some time processing data and some time waiting, you can change as necessary. These were the current usages we measured for a sketch that does nothing:

Clock Prescaler

Current

1(default)

37mA

16

30mA

256(slowest)

29mA

The multiplier can be changed to any power of two between 1 and 256, and the code we used is below:

#define CLOCK_PRESCALER_1   (0x0)
#define CLOCK_PRESCALER_2   (0x1)
#define CLOCK_PRESCALER_4   (0x2)
#define CLOCK_PRESCALER_8   (0x3)
#define CLOCK_PRESCALER_16  (0x4)
#define CLOCK_PRESCALER_32  (0x5)
#define CLOCK_PRESCALER_64  (0x6)
#define CLOCK_PRESCALER_128 (0x7)
#define CLOCK_PRESCALER_256 (0x8)

void setup() {
    uint8_t oldSREG = SREG;
    cli();
    CLKPR = _BV(CLKPCE);
    CLKPR = CLOCK_PRESCALER_256;
    SREG = oldSREG;
}

void loop() {
}

The #defines at the start are just to give the settings more useful names, and the code inside the setup() function is what sets the prescaler ratio. The value highlighted in yellow is what is changed to give different speeds- if you think of the prescaler as a divider, you can work out the actual processor speed, so with a prescaler of 16, the processor runs at 1MHz, and with a prescaler of 256, the processor runs at 62.5kHz.

Of course, with any saving comes a compromise, and as you might expect, things that depend on timing are the ones that are affected. Things like the serial port, timers and delay functions don't know that the speed has been changed and will operate slower than expected. The easiest way around this is to multiply the baud rate or divide the delay by the prescaler. For example, if you are using the serial port at 9600 baud with a prescaler of 1, that will appear the same as 38400 baud with a prescaler of 4. Or if you want to delay 1000ms while the prescaler is 8, you need to use delay(125).

Another issue that might occur is that if you are using ISP to program your Arduino is that it might not respond to the programmer if the prescaler is set too high. The easiest way to avoid this is to allow the Arduino to run at full processor speed (prescaler = 1) for a few seconds after reset, so that it can be manually reset if necessary to be at full speed for the upload. You can do this by simply adding delay(2000) to the start of your setup() routine.

We found we weren't able to squeeze much more out of the Uno here, and the reason is that there are still a few things on the board that draw power. Even after bypassing the 5V regulator, the USB-serial converter, 3.3V regulator, and power LED are still running. If you're game, and don't think that you'll need them, you could remove them by desoldering (of course you won't be able to use them after this).

The alternative is to build an Arduino board up from scratch, only adding the things you need. The following breadboard circuit using a ZZ8727 ATMega 328P IC and 16MHz Crystal and a 10kOhm resistor is a good starting point:

sample.png

You’ll also find instructions on programming the above board on the 
ZZ8727 page, but you will need either an ISP Programmer or a USB-Serial converter. Emulating the prescaler experiments from the last page, we were able to achieve the following:

Clock Prescaler

Current

1(default)

14mA

16

8mA

256(slowest)

7mA

Note that we've saved about 22mA just by ditching the unused accessories on the Uno main board. Now that we have minimal hardware, we can look at software changes that will take power consumption even further.

The software is what makes our Arduino do what we want, so you may not be able to apply all the following changes without disabling some function that you need. A bit more experimenting might be necessary.

Fortunately, the Arduino IDE comes with a library called <avr/power.h> that includes some easy ways to turn off some of the modules you may not be using. The following results use our blank sketch with a prescaler of 4, with various modules turned off:

Modules

Current

All enabled(default)

9.7mA

ADC disabled

9.4mA

SPI disabled

9.3mA

UART disabled

9.4mA

Timer0 disabled

9.6mA

Timer1 disabled

9.6mA

Timer2 disabled

9.6mA

TWI disabled

9.6mA

All disabled

9.1mA

To implement the above, include the power library by putting the following line at the very top of your sketch:

#include <avr/power.h>

And put the following code in your setup (or wherever you'd like to disable modules):

  power_adc_disable(); // ADC
  power_spi_disable(); // SPI
  power_usart0_disable();// Serial
  power_timer0_disable();// Timer0
  power_timer1_disable();// Timer1
  power_timer2_disable();// Timer2
  power_twi_disable(); // TWI

Similar projects you may be interested in