Battery-powered Arduino

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:

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

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.

In summary you will need two resistors R1 and R2 which are hooked up between your analog pin and Vcc and GND.

Depending on the value of the resistors you can measure different ranges of voltages, even high above the threshold your Arduino is capable of survice.

In this example A0 is used as analog PIN and two resistors with R1=1MΩ and R2=470kΩ. Those are good values to map up to 3.44V to your 1.1V reference. If you read 1023 from A0, 3.44V are attached and so on.

Since I drive my Arduinos with either 2 AA or 2 AAA batteries, the voltage will never reach more than 3V. If you need to use higher voltages, you should adjust the values accordingly.

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

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()
{
  ...
  int sensorValue = analogRead(BATTERY_SENSE_PIN);    // Read Analog Value
  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
}

Footnotes

Gallery

Related Posts