Arduino - Adjustable & Smart Battery Charger





Introduction: Arduino - Adjustable & Smart Battery Charger

After building a wireless controlled DCC garden train powered by 12volt battery packs of lead acid or NiMH or Li-Ion types, I required a battery charger that would charge them all in one go rather than individually. On finding an interesting article on the web for a design of a constant current source (thanks to Henry's Bench), I decided to adapt the design to create a battery charger.

This is an Arduino based, adjustable and smart battery charger, designed for 12 volt packs that can be adapted for single cells also. A LCD display gives the settings and charging values. A selector switch for set and run plus 3 potentiometers to set constant current, max charge voltage and charge time are included in the design.

Parts used: (all available on ebay unless indicated)
Arduino Pro Mini 5 Volt ATMEGA328 £3.00
MOS FET IRLB8743Pbf £1.25
5 Volt , 0.5 Amp Regulator - R-78C5.0-0.5 £4.46
Dual Op Amp (only one half used) - LM358 8 pin £0.36
3 Amp Current sense module - MAX471 £4.99
12 BitDigital to Analog Converter - MCP4725 £4.45
16 x 2 LCD module - HD44780 Backlit 1602 £3.19
Aluminium enclosure 192x112x61mm (RS) £13.78
3 off 10K potentiometers £4.92
1 off toggle switch SPDT £0.50
Strip board, connectors, wire and resistors £2.00

Step 1: Circuit Diagram

It is vital to know what you are doing when attempting to charge different types of batteries.

Over-charge or under-charge can damage certain types and can be dangerous.

Please read the website for details.

Here we have a flexible design to enable adjustment of max charge voltage, constant charge current and charge time.

For NiMH batteries, the timer is selected (> 5 minutes) the charger will deliver a preset constant current and the battery charge voltage is monitored for peak value before reducing by >50mv while charging 10 batteries in series (for a 12v supply). The timer should be set to about 4 hours as a back up to ensure no over charging

For lead acid and Li-Ion batteries , the timer is not set, the preset constant current will run until the preset max charge voltage is reached (lead acid typ 13.65v and Li-Ion typ 12.6v), after which it reduces the current by 10% each time the max is reached, thus giving a slow reduction in current during the saturation phase important to Lithium-Ion batteries.
This charger is not designed to charge Li-Poly batteries where each cell must be monitored and controlled separately.

When the maximum power across the MOSFET is reached (Wmax) the system shuts down.
Wmax value will depend on the heatsink attached to the MOSFET.
For example, a cast aluminium box with 500 sq cm surface area.
To achieve a maximum temperature increase above ambient of 45 deg C with a heat sink/box rated at 1.5 deg C per watt, Wmax, the max power dissipated by MOSFET = 45/1.5 = 30;

A LM358 controls the bias on a Mosfet until the current measured by the MAX471, matches what has been called for at pin 3 of the op amp.

A MCP4725 Digital to Analog Converter provides an input to pin three of the op amp.

The MAX471 will provide a 1 volt output for 1 Amp of current measured. Its measurement range is limited to 3 amps, this sketch limits the constant current to 2.5 amps Max.

Step 2: Arduino Sketch

#include "Wire.h"
#include "Adafruit_MCP4725.h"
#include "Adafruit_LiquidCrystal.h"

Get these library files from Github.

Adafruit_LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
These are the pins connected to the LCD display.

Values used in this circuit are:
Ardunio Vdd = 5.02 R1 = 22k, R2 = 4.7k, Voh = (analogRead(A2) x 5.02 /1023) * ((22+4.7)/4.7)
R1 and R2 are the resistors across the supply and another pair across the MOS FET
The value of each graduation on the analog inputs is,
mv = (float) 1000 * (Vdd/1023) * ((R1+R2)/R2) = = 27.87 mv

Voh = analogRead(A2) * mv
Power supply input, Vin = 16.2 rated at 3 Amps;

dac.begin(0x60); // The I2C Address: Run the I2C Scanner if you're not sure
uint32_t dac_value;
dac.setVoltage(Vdac, false); - sets the digital to analog output of the MCP4725
Vdac = 0; sets current to zero
To provide 1 Amp constant current -
dac.setVoltage(819, false);
Iset = 1.0;

A value of819 sets a current of1 Amp, therefore other values can be calculated
Iset = (float)Vdac / 819.00; // 819 = 1 Amp // 2046 max // 2046/819 = 2.5 Amp max

For NiMH batteries, we need to detect peak battery charge voltage, Vbat then detect a drop off by 50mv for 10 in series (5mv per cell) - only applies when timer is set.
Timer should be set to about 240 mins to ensure no over charging
The peak battery voltage is calculated from 10 readings of Vbat then an average value calculated Vbat_avg

For Lead Cell and Li-Ion batteries, charge limited to specified max charge volts - only applies when timer is not set. When the charge voltage Vbat, meets the pre-set value Vset, the current is reduced to 90%.
This continues to reduce each time Vset is reached until a minimum value of 10% of Iset is reached, then power is turned off. This routine allows the battery to go through a saturation phase, important ti Lithium batteries.

if (Vbat >= Vset && Tset < 5) // Detect Vbat reaches Vset, provided timer is off
Vdac = 0.9*Vdac; // reduce Vdac / Iset to 90%
if (Iact < (0.1 * Iset)){ // test to check actual current is below 10% of Iset
charged = true; // if true, switch of current
Vdac = 0;



  • Epilog Challenge 9

    Epilog Challenge 9
  • First Time Author Contest 2018

    First Time Author Contest 2018
  • Sew Warm Contest 2018

    Sew Warm Contest 2018

We have a be nice policy.
Please be positive and constructive.




what components would you recommend for a 48v system

Would this be a 48v lead acid cell battery? You would need to increase R1 and R4 to 87k, increased C3 voltage to >60v and replace the 5v regulator with one that can take at least 60 volt input. High transient voltage peaks may need to be considered in the design. Not sure if all this would work for you, but maybe worth a go.

thank you very much for your response. It is a 48V lithium pack for a golf cart. I have since decided that it would be much better to charge the cells in parallel in order increase the balancing of the cells.