# Battery-powered Arduino

Contents

Running an Arduino on battery power is only useful, if you know, when to change the battery. Here it is handy, to measure the current battery level and get notifications, if it drops below a certain threshold. Thankfully you can use the analog Pins to measure a voltage.

If you attach a voltage to e.g. A0, your Arduino will compare the input voltage with a reference voltage (by default VCC) and return a value between 0-1023 where 1023 means, that the input voltage is equal or higher than VCC. Afterwards you can calculate the actual voltage by simple math:

$$V_{analog}=\frac {V_{vcc}}{1023}\cdot A_{analog}$$

So for example if you measure 768 on the Pin, you can calculate the attached voltage:

$$V_{analog}=\frac {3.3 V}{1023}\cdot 768 = 2.47 V$$

This works fine as long as you know your VCC which is not true for battery powered Arduinos. Luckily the Ardunio has an internal Reference Voltage of 1.1V 1 that can be used for comparison.

Since you can only measure voltages below the reference voltage you need to apply some magic in form of a Voltage divicer to map the voltage to a range of 0 to 1.1V.

## Voltage divider

The lengthy wikipedia article 2 on voltage dividers gives a good introduction how this circuit works.

The following formula is used to calculate the 4 relevant values (Vin is equal to VCC):

$$V_{out}={\frac {R_{2}}{R_{1}+R_{2}}}\cdot V_{in}$$

Alternatively you can also use one of the many online calculators3.

## Code example

The following code example shows the usage of the internal reference voltage on a MySensors4 node, a complete Arduino Sketch is available on Github.

#define VMIN 1.9  // Battery Level 0%
#define VMAX 3.44  // Batter Level 100%
#define VBAT_PER_BITS 0.003362  // Volts per bit on the A0 pin, VMAX / 1023 = 3.44 / 1023 = 0.0033625

void setup()
{
...
analogReference(INTERNAL);
...
}

void loop()
{
...
float volt  = sensorValue * VBAT_PER_BITS;          // Calculate Voltage
int batteryPcnt = sensorValue / 10;                 // Calculate Battery Level (Percent)
send(voltMsg.set(volt, 2));                         // Send Voltage
sendBatteryLevel(batteryPcnt);                      // Send Battery Level
}