Anth's Computer Cave

Build a dual-battery monitor for Arduino, Part One

Today we'll build a device to monitor two batteries. I'll then show you how to access that battery data from within other programs.

I built this unit for the AAIMI project to monitor the batteries in the AAIMIv2 robot, but you could use it in many situations. Solar projects seem like an obvious example.

AAIMIv2 runs from two 12V batteries; one for the computer and micro-controllers, and one for the drive motors.

One immediate reason the robot needs power monitoring is to avoid hard shutdowns resulting from the computer battery running low. With this system I can program the robot to cleanly shut down before the battery falls below a predetermined level.

A more compelling benefit will be the long-term data this device generates. Over time AAIMI can analyze power-use data and fluidly predict whether it has enough battery-life to perform specific tasks.

Build you own

This monitor is really simple to build. You just need a PCB board, some header pins and two resistors for each battery you wish to monitor.

First you need to think about your requirements. The device I have built suits my requirements, but you may need to adapt it to your project.

For instance, do you need to monitor two batteries? You can build a single-battery device if you wish.

What voltage are you working with? This device uses voltage-dividers to reduce voltage to a safe level for the Arduino.

You must tailor the resistors in the device to your maximum-intended monitoring voltage. There is an example of a 12V to 5V voltage divider below.

A voltage divider configured to reduce 12V down to 5V. Diagram created by Anthony Hartup using CircuitDraw.

In my case, I had 12.2V for both batteries. I used an 825 Ohm resistor for R1 and a 560 Ohm resistor for R2 to bring that 12.2V down to exactly 5V, which is the maximum analogue input voltage the Arduino micro-controller can handle.

You will need to calculate your resistor values to bring your maximum battery voltage to 5V. Make sure the batteries are fully charged to read the maximum levels. Test the circuit on a breadboard before you connect the device to your Arduino, because anything more than 5V will fry it.

I am building a calculator into the site to help you create voltage-dividers, but for now you can find one here. You simply enter an input voltage (your battery) and a value in Ohms for R1, then enter an output voltage (5V). Click Compute and the calculator will give you a value in Ohms for R2.

Note: You should start with a resistor of at least 825 Ohms for R1. Any lower and you risk excessive current overheating the resistors.

If you have two batteries of different voltages you will need different resistors for each voltage-divider.

The complete circuit

A diagram of the system to monitor two batteries.
A complete system to monitor two batteries with a maximum of 12V. Diagram created by Anthony Hartup using CircuitDraw.

In the image above you can see that each of the ground cables from the batteries connects to the bottom of its own voltage divider. Both batteries are also connected to GND on the Arduino. The positive cable from each battery connects to the top of its own voltage-divider. The cables from the center of the voltage-dividers connect to the first two analogue-to-digital pins on the Arduino, A0 and A1.

That is our connections sorted, let's write some Arduino code.

Arduino code

You can either copy and paste the following code into your Arduino IDE or download the full setup folder from here.

//AAIMI Dual-Battery Monitor
//Part of the AAIMI Project
//aaimi.anthscomputercave.com
//By Anthony Hartup

int power1Pin = A0;  
int power2Pin = A1;
float Power1 = 0.0; 
float Power2 = 0.0;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }
  Serial.println("Serial Connected");
}
  //Read the first battery voltage once
  void readOne() {
  int sensorValueOne = analogRead(power1Pin);
  //Change 12.00 to suit your battery voltage
  Power1 = sensorValueOne * (12.00 / 1023.0);
  Serial.println(Power1);
  }
  //Read the second battery voltage once
  void readTwo() {
  int sensorValueOne = analogRead(power2Pin);
  //Change 12.00 to suit your battery voltage
  Power2 = sensorValueOne * (12.0 / 1023.0);
  Serial.println(Power2);
  }
  //Read the first battery voltage at one-second intervals
  //for one minute.
  void intervalOne() {
    int var = 0;
    while(var < 60){
      readOne();
      delay(1000); 
      var++;
} 
}

  //Read the second battery voltage at one-second intervals
  //for one minute.
  void intervalTwo() {
    int var = 0;
    while(var < 60){
      readTwo();
      delay(1000); 
      var++;
} 
}
void loop() {

  if (Serial.available()) {
     char order = Serial.read();
     
     if (order == 'a') {
       readOne();
       
      }    
     else if (order == 'b') {
       readTwo();
      }   
     else if (order == 'c') {
       intervalOne();
      }
     else if (order == 'd') {
       intervalTwo();
      }      
  }
}	
	

The Arduino sketch above checks voltages on demand, so it won't poll the voltage sensor until you, or another program, ask it to. This frees resources on the Arduino if you wish it to perform other tasks as well as battery monitoring.

Testing

To test your device, open the serial monitor in your Arduino IDE.

You should soon see "Serial Connected" printed to the screen.

To poll the first sensor once, enter "a". To poll the second sensor once, enter "b".

Press Enter.

The voltage will display on the screen. You can then compare this to a reading from a reliable multimeter. If the readings do not match, you can adjust the following section of code to calibrate the system. On line 21 either increase or decrease the value (12.00) slightly to suit your readings.

  //Read the first battery voltage once
  void readOne() {
  int sensorValueOne = analogRead(power1Pin);
  //Change 12.00 to suit your battery voltage
  Power1 = sensorValueOne * (12.00 / 1023.0);
  Serial.println(Power1);
  }	
	

As an example, if the first sensor on the Arduino is reading 11.8V and the multimeter reads 12V, try adjusting the value on line 21 to 12.25. With trial and error from there you should be able to achieve the desired Arduino reading.

To adjust the second sensor reading you would change the value (12.00) on line 29 instead.

As another example let's say you are monitoring a battery that reads 5V on a multimeter.

But reads 4.90 on the Arduino.

Open your Arduino sketch.

On line 21 I change the 5.00 to 5.10.

Save the sketch, upload it to your Arduino and open the serial monitor again.

And now I get exactly 5V

Continuous polling

You may wish for the Arduino to poll continually for voltage readings to check real-time readings.

To poll the sensor every second for one minute, enter "c". To poll the second sensor every second for one minute, enter "d".

It will print the voltage each time it polls, giving you a list of readings to check stability.

Next

We now have a working battery monitor, but that's only half the mission. Next we need to build functionality into our existing programs to access the readings.

In the next article I will show you how to run this system as part of a larger project.

Cheers

Anth

Next: Part Two


Leave a comment on this article