Charge Batteries with an Arduino

By All About Circuits

Courtesy of All About Circuits

Rechargeable batteries are great for powering your portable electronics. They can save a lot of money and are much better for the environment when properly recycled. Your batteries need to be properly charged if you want to get the most out of them. This means that you’re going to need a good charger. You could buy a commercial charger for a lot of money, but it's way more fun to build one for yourself! Here’s how I made my Arduino-controlled battery charger.

It’s important to point out that there is no universal charging method that is appropriate for every type of rechargeable battery. Each kind of battery uses a different chemical process in order to recharge. We can’t cover all the battery types and charging methods in one article. So we’re going to focus on Nickel-Metal Hydride (NiMH) the most common type of AA rechargeable battery.


Parts List

Parts in order from left to right

How to Charge NiMH AA Batteries


Increasing the C-rate charges the battery faster, but also increases the risk of damaging it

There are a lot of different ways to charge a NiMH battery. The method that you use will depend mostly on how fast you’d like to charge your battery. The charge rate (or C-rate) is measured in relation to the capacity of the battery. If you charge a battery with a capacity of 2500mAh with current of 2500 mA, then you are charging it at a rate of 1C. If you charge the same battery with a current of 250mA, then your rate of charging is c/10.

If you’re charging your battery quickly (at a rate higher than C/10), you’ll need to monitor the battery’s voltage and temperature carefully to make sure that you don’t overcharge it. Overcharging can cause serious damage to your battery. If you charge your battery slowly (a rate of C/10 or less), your battery is much less likely to be damaged if you overcharge it. This is why slow charging methods are generally considered to be safer. This will help maximize battery life. I decided to use a charge rate of C/10 for my battery charger.

The Charging Circuit

This charger’s circuit design is a basic Arduino controlled power supply. Our circuit is powered by a 5 volt regulated voltage source like an AC adapter or an ATX computer power supply. Most USB ports won’t work for this charger because of their current limitations. The battery is charged by the 5V source through a power MOSFET and a 10 ohm power resistor. The MOSFET controls how much current is allowed to flow into the battery. The resistor is used to monitor the current. This is accomplished by connecting each terminal to the analog input pins on your Arduino and measuring each side’s voltage. The MOSFET is controlled by a PWM output (pulse width modulation) pin on the Arduino. A 1M resistor and a 1 µF capacitor smooth the PWM signal’s pulses into a steady voltage signal. This circuit allows your Arduino to monitor and control the current flowing into the battery.


The Temperature Sensor

Temperature  sensor

The temperature sensor will prevent the battery from overcharging and causing a safety hazard

I added a TMP36 temperature sensor to monitor the temperature of a battery as an extra precaution. The temperature sensor outputs a signal voltage that corresponds directly to the temperature. This means that it doesn’t require balancing or calibration like a thermistor does. We mount the sensor in place by drilling a hole in the back of the battery housing and gluing in the sensor so it sits against the side of the battery when installed. The sensor’s pins are then connected to 5V, GND, and an analog input pin on the Arduino.

Battery Holder

The AA battery holder before and after being placed on the breadboard

Battery attached to breadboard

The Code

Coding image

The code for this project is pretty straightforward. The variables at the top of the code allow you to customize your charger by inputting values for the battery capacity rating and the exact resistance for your power resistor. There are also variables for the charger’s safety thresholds. The maximum allowable voltage for our battery is set to 1.6 volts. The battery’s maximum temperature is set to 35 degrees Celsius. The battery’s maximum charge time is set to 13 hours. The charger will turn off if any of these safety thresholds is exceeded.

In the code’s body, you’ll see that the system constantly measures the voltages of the power resistor’s terminal. This is used to calculate the current flowing into the battery as well as the battery’s terminal voltage. This current is compared to the target current, which we set to C/10. If the calculated current differs from the target current by more than 10 mA, the system will automatically adjust the output to correct it.

The Arduino’s serial monitor tool is used to display all of the current data. If you’d like to monitor the performance of your charger, you can connect your Arduino to the USB port on your computer. This isn’t necessary, however, since the Arduino is powered by the charger’s 5V power supply.

The full version of the code is below:

Copy Code
int batteryCapacity = 2500;     //capacity rating of battery in mAh
float resistance = 10.0; //measured resistance of the power resistor
int cutoffVoltage = 1600; //maximum battery voltage (in mV) that should not be exceeded
float cutoffTemperatureC = 35; //maximum battery temperature that should not be exceeded (in degrees C)
//float cutoffTemperatureF = 95; //maximum battery temperature that should not be exceeded (in degrees F)
long cutoffTime = 46800000; //maximum charge time of 13 hours that should not be exceeded

int outputPin = 9; // Output signal wire connected to digital pin 9
int outputValue = 150; //value of PWM output signal

int analogPinOne = 0; //first voltage probe connected to analog pin 1
float valueProbeOne = 0; //variable to store the value of analogPinOne
float voltageProbeOne = 0; //calculated voltage at analogPinOne

int analogPinTwo = 1; //second voltage probe connected to analog pin 2
float valueProbeTwo = 0; //variable to store the value of analogPinTwo
float voltageProbeTwo = 0; //calculated voltage at analogPinTwo

int analogPinThree = 2; //third voltage probe connected to analog pin 2
float valueProbeThree = 0; //variable to store the value of analogPinThree
float tmp36Voltage = 0; //calculated voltage at analogPinThree
float temperatureC = 0; //calculated temperature of probe in degrees C
//float temperatureF = 0; //calculated temperature of probe in degrees F

float voltageDifference = 0; //difference in voltage between analogPinOne and analogPinTwo
float batteryVoltage = 0; //calculated voltage of battery
float current = 0; //calculated current through the load (in mA)
float targetCurrent = batteryCapacity / 10; //target output current (in mA) set at C/10 or 1/10 of the battery capacity per hour
float currentError = 0; //difference between target current and actual current (in mA)

void setup()
Serial.begin(9600); // setup serial
pinMode(outputPin, OUTPUT); // sets the pin as output

void loop()

analogWrite(outputPin, outputValue); //Write output value to output pin

Serial.print("Output: "); //display output values for monitoring with a computer

valueProbeOne = analogRead(analogPinOne); // read the input value at probe one
voltageProbeOne = (valueProbeOne*5000)/1023; //calculate voltage at probe one in milliVolts
Serial.print("Voltage Probe One (mV): "); //display voltage at probe one

valueProbeTwo = analogRead(analogPinTwo); // read the input value at probe two
voltageProbeTwo = (valueProbeTwo*5000)/1023; //calculate voltage at probe two in milliVolts
Serial.print("Voltage Probe Two (mV): "); //display voltage at probe two

batteryVoltage = 5000 - voltageProbeTwo; //calculate battery voltage
Serial.print("Battery Voltage (mV): "); //display battery voltage

current = (voltageProbeTwo - voltageProbeOne) / resistance; //calculate charge current
Serial.print("Target Current (mA): "); //display target current
Serial.print("Battery Current (mA): "); //display actual current

currentError = targetCurrent - current; //difference between target current and measured current
Serial.print("Current Error (mA): "); //display current error

valueProbeThree = analogRead(analogPinThree); // read the input value at probe three
tmp36Voltage = valueProbeThree * 5.0; // converting that reading to voltage
tmp36Voltage /= 1024.0;
temperatureC = (tmp36Voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset to degrees ((voltage - 500mV) times 100)
Serial.print("Temperature (degrees C) "); //display the temperature in degrees C
temperatureF = (temperatureC * 9.0 / 5.0) 32.0; //convert to Fahrenheit
Serial.print("Temperature (degrees F) ");
Serial.println(); //extra spaces to make debugging data easier to read

if(abs(currentError) > 10) //if output error is large enough, adjust output
outputValue = outputValue currentError / 10;

if(outputValue < 1) //output can never go below 0
outputValue = 0;

if(outputValue > 254) //output can never go above 255
outputValue = 255;

analogWrite(outputPin, outputValue); //write the new output value
if(temperatureC > cutoffTemperatureC) //stop charging if the battery temperature exceeds the safety threshold
outputValue = 0;
Serial.print("Max Temperature Exceeded");

if(temperatureF > cutoffTemperatureF) //stop charging if the battery temperature exceeds the safety threshold
outputValue = 0;

if(batteryVoltage > cutoffVoltage) //stop charging if the battery voltage exceeds the safety threshold
outputValue = 0;
Serial.print("Max Voltage Exceeded");
if(millis() > cutoffTime) //stop charging if the charge time threshold
outputValue = 0;
Serial.print("Max Charge Time Exceeded");

delay(10000); //delay 10 seconds before next iteration

You now have the knowledge to get started on a charger of your own! Be sure to monitor your charge rate and use safety protocols. Excessively charging a battery can be dangerous.

Key Parts and Components

Add all Digi-Key Parts to Cart
  • PPC5W10.0TB-ND
  • 732-8851-3-ND
  • IRF510PBF-ND
  • 1050-1024-ND