Introduction: DIY Solar Charge Controller for Li-Ion, Li-po, LiFePo or NiCd Batteries

About: I like to share good ideas.

This article describes the design and construction of a (Dual) Solar Charge Controller. The design consists of a battery charger circuit using op-amps for measurement of analogue inputs and FET for PWM control. A micro-controller is used for charge control and the 4 line LCD is used for configuration and display of information. The software is provided open source. (Open Source Licence agreement). The circuit and PCB are designed using Eagle. The PCB is designed with most tracks running in one (x-x) direction and most components running in opposite (y-y) direction so the PCB required is a piece of veroboard and a few links. The project has been under test for a few weeks and evidence of operation charging li-ion batteries in varying weather conditions is given in System Testing. Finally construction details are provided so that the project can be built by a person with "intermediate level" electronics knowledge (not recommended for beginner).

Step 1: Features

  1. Management of two batteries (one micro-board controls two charger boards).
  2. Battery types: NiCd, NiMh, Li-ion (nickel-mang-cobalt), Li-Po or "User" defined.
  3. Up to 4 cell (14.8V nominal) Li-ion/Li-po battery packs.
  4. Up to 4 cells LiFePo (12.8V nominal, 14V absorption/float) (not tested yet)

  5. Up to 12 cell (14.4V) Ni-Cd/MH battery packs.

  6. For on-load or off-load charging.
  7. Cell capacity nominally 1.000Ah.
  8. Current range may be configured by sense resistor values.
  9. High side current sensing. This means that the batteries, loads and solar panel have one common ground (0V).
  10. Charge Controller uses 10-bit PWM hardware which is controlled by software.
  11. Uses lithium CC/CV algorithm specified in datasheets for Nanjing TP4056, Linear LTC4056 and Texas BQ2057 chips (with some corrections/improvements).
  12. Discharge protection by emulation of Fortune DW01 chip.
  13. Fuel gauge calculations
  14. Uses 4 line by 20 character LCD display for configuration and monitoring of results.
  15. Relatively simple construction using veroboard as IC packages are all PDIP.
  16. Low power consumption, about 10mA for charger and 10mA for micro controller.
  17. Industrial temperature range of micro-controller.

In order to simplify the design, these features are not provided

  1. Not tested on LiFePo4 yet (should not be a problem- just a matter of settings)
  2. USB, Wi-fi, surface mount,
  3. Bucking regulators
  4. Maximum Power Point Tracking (MPPT)
  5. Cell balancing.

MPPT greatly increases complexity. This design is "not looking for mountains to climb". And at low power, is eficiency really that important when sunlight is free anyway? For cell balancing, it would be prudent to manually check individual cells using a multimeter and replace faulty ones.

Step 2: Comparison of Designs

There are some other good solar designs on Instructables like Open Green Energy. This design is similar to Open Green but is targeted at lower power setups. It uses the more traditional "resistive" current sensing which gives high sensitivity and is accurate for low currents (< 2 Amp ?). The Open Green design uses Hall Effect sensing which is probably a better solution for higher power/high current applications. The 100 mV/A output sensitivity of the ACS712 would suggest this is more suitable at higher current (about 10 Amp).

If you just want a battery charger then something like a CN3791 board selling for about £3 on ebay will save you a lot of effort. But the CN3791 is designed to charge a single li-ion cell, has no extra features like LCD display and will not work correctly if connected to a load while charging.

This project is NOT a battery charger. It is a solar charge controller in the sense that it is permanently connected to the PV panel, battery AND load. This project measures both PV (input) current and load (output) current so that on-load charging works correctly by compensating for load current. For example charge termination occurs when the input current (Iin) < (Iout+Itrk).

Step 3: Charger Scheme and Terminology

Battery University specify the recommended CV/CC charging scheme for different cells and manufacturers have developed chargers and chips based on this information. Look at datasheets for chips like Nanjing TP4056, Linear LTC4056, Texas BQ2057 and Fortune DW01. These are three similar charger chips and one protection chip. This design uses the charging algorithm specified by Texas BQ2057 datasheet in Figure 2 - flowchart. Hence it will give the charging profile for a typical lithium cell, see Texas BQ2057 datasheet Figure 3. There are slight variations in terminology used by manufacturers so this is the definition of terminology used in this article.

For more information about the charger scheme and terminology see here.

Step 4: Menu and LCD Display

The 4 line/20 character LCD display and 4 menu buttons are used for configuration of settings and display of information/results. Using the menu (left and right) buttons, 9 screen formats are provided, and most formats are repeated for battery 1 and battery 2.

Menu option 1 – Input Format (b = battery 1 or 2 )

BATb Inputs hh:mm:ss

Vpv =20.00 BAT=12.00V

Iin=0.500 Out=0.500A

nTYP MOD OUT PWM=255

Displays input values to micro-controller; PV and battery Voltage, input and output current. The "+" and "–" keys perform no function. The status line shows n = number of cells,

Type = Ni-Cd, Li-Ion, Li-po, LiFePo or User Type (e.g. 10Ni, 03Li, 03Lp, 04LF or 44UT),

Charger State (MOD) = Hot (temp alarm), ON, PRE, CC, CV, STB or end of charge (EOC).

Load State =ON or OFF , PWM = OFF or value from 0 to 255.

Menu option 2 - Fuel Gauge (b = battery 1 or 2 )

BATb Fuel_G hh:mm:ss

Σpv=5.000 ΣC=0.000Ah

Cap=1.000 ΣD=0.000Ah

nTYP CHG OUT PWM=255

Displays results of fuel gauge calculations. Σpv , ΣC, ΣD are value of solar panel, battery charge and discharge (see calculations). Pressing the "+" or "-" button increases/decreases battery capacity in 0.1Ah increments.

Menu option 3 – Power Format (b = battery 1 or 2 )

BATb Power hh.mm.ss

CPU= 90% PRE=00.00 V

press +on or -standby

nTYP CHG OUT PWM=255

This display indicates CPU speed. The number is really a count of the number of times the main loop is executed in a period of two second, i.e. a value of 100% would indicate that the controller is executed at 50Hz. Also shown is the precharge voltage (for which there was no space on cells display). Buttons are provided mainly for just software testing. Press "+" to reset CC, CV, EOC, STB, switch PWM on, load on, and set QC=50%Cap. This is useful after EOC has occured should you wish to recommence charging without waiting for voltage to drop to recharge threshold. Press "-" for standby which switches PWM and load off.

Menu option 4 – Charge Format (b = battery 1 or 2 )

BATb Charge hh:mm:ss

Iset = 0.100 Amp

Itrk = 0.012 Amp

nTYP CHG OUT PWM=255

Displays the charging set and trickle current.Pressing the "+" or "-" button increases/decreases set current in 50mA increments. The trickle current is set to one eighth the Set current. The set current should be below the recommended value of Capacity/charge time, (e.g. for 1.0Ah battery, Iset < 1.0Ah/2hour < 0.5 Amp)

Menu Option 5 – Cells Format (b = battery 1 or 2 )

BATb Cells hh:mm:ss

RCG=00.00 FLT=12.00V

Odp=00.00 Odr=12.00V

nTYP MOD OUT PWM=255

Shows the settings for the battery stored in EEDATA. The settings are recharge(rcg), Float, output protection (odp), output release (odr) voltages. Pressing the "+" or "-" button increments/ decrements number of cells n. Values of RCG,FLT, odp,odr are adjusted accordingly. For "User Type" battery the "+" and "–" button allow adjustment of voltage in steps of approx 0.3V. For example user type "44UT" has a float voltage of 12.0 V, so suitable for 3 Li cells with 3.6V nominal voltage.

Menu option 6 - Cell Type Format

BATb Typehh.mm.ss

!Warning! press +/-

to change cell TYPE

nTYP CHG OUT PWM=255

Displays a warning message, pressing + or – changes the cell type and sets number of cells to 1. Voltages are adjusted accordingly for a 1 cell battery. After this, you can use the settings option to adjust number of cells. It would be unwise to change cell type while a battery is connected, so disconnect first.

Menu 7 – Temperature

Temperaturehh:mm:ss

Tmp1=00.0 lim=40.0°C

Tmp2=00.0 rel=35.0°C

Shows current temperature and limits. Temp2 is only available with PIC16F887 device. Press "+" and "-" keys to adjust limits.

Menu 8 - Time Display

Time_ hh:mm:ss [x]

press +/- to adjust

then [x[ to exit

Press + or - to adjust time. The cursor moves to line 1, then use menu left and right keys to move the cursor and "+" and "-" keys to adjust each digit. Finally click "+" on [x] to exit.

Menu 9 - Remote / Logging

Remote hh:mm:ss

press + to connect

press –to empty log

Log=nn


Log=nn is the number of times data has been logged at 15 min intervals, the maximum value 22 represents 5.5 hours of data. Press "–" to empty logged data in EEPROM. Press "+" to open a serial connection, which also puts controller in standby. Then connect the serial port to COM1 of PC computer configured for 9600 baud, 8 bits, no parity. Run a terminal program like Putty, RealTerm, HyperTerminal (WinXP). Press "?" to see commands. The "L" command downloads logged data in "comma separated" format that can be copied into a text file which is then read by spreadsheet like exel. The values sent are the 8 analog inputs which have been logged at 15 minute intervals, "AN0,AN1,AN2,AN3,AN4,AN5,AN6,AN7". Values are in range 0-5V. Finally "Q" to disconnect, and resume control. AN7 may be used to estimate temperature using:

temp = 125 – 40*AN7 Celsius (Equation 9)

Step 5: Connection Diagram

The connection diagram (see .pdf file below) shows how the project is split into four circuits, two chargers, a temperature board, and micro-controller board. The boards may be joined on one vero-board PCB. The left hand side shows how up to two batteries and up to two PV panels may be connected to two charger boards. When one PV is shared, R201 and R202 are recommended to improve load sharing. In periods of low sunlight the PV has insufficient output to meet full current demand and when this happens the battery with the lowest voltage tends to pull the PV voltage down and “steal” all available current.

Step 6: Battery Charger Board

The charger circuit senses the inputs; PV voltage, battery voltage, input and output current. These are low pass-filtered and "scaled" to a suitable range (0 to 5V) for measurement by ADC. The circuit also contains the two FETs for charge current (PWM) control and output discharge protection. Most of the circuit is concerned with voltage/current measurement, so it shares a lot of circuit design ideas with the AVO meter project.

  1. Two attenuators reduce the PV and battery voltage from 0 to 20V range to 0 to 5V range.
  2. Two high side current sense circuits measure the input current (from PV) and output current (to load). This circuit is built using general purpose TL084 op-amp and two general purpose pnp transistors. Since building the circuit I have found two ICs, the ST micro TSC101 and Linear LTC6101 which do the same thing. Using these would reduce the amount of construction and testing required.
  3. The FET switch controls the charge current from PV to battery. The period is 128 micro sec, and the duty cycle is controlled by software.
  4. The output FET connects the load to the battery, except when the battery is below the protection voltage.

For the specification and full description of charger board see here.

Refer to the schematic diagram (.pdf file) below.

Step 7: Temperature Sensor Board

This little board was added as an after thought when I realised that a micro-controller with 8 analogue inputs is insufficient to read two temperatures. The circuit checks two batteries to see if temperature is above the limit of about 40 deg C. IC1 is LM393 dual comparitor connected as standard Schmitt trigger. It uses the temperature sensor normally found in the battery pack, which is usually an NTC thermistor of nominal resistance 10k.

See the schematic diagram for temperature sensor board below:

Step 8: Micro-Controller Board

By keeping the design relatively simple, one micro-controller controls two battery charger circuits. A micro with 10 bit ADC, 8 analogue inputs (preferably 10) and two 10 bit PWM outputs is required for this purpose.

The software was initially written to run on a PIC16F877A although an Atmega or Arduino Uno should also be suitable. Perhaps this would be a future project for somebody to transfer the software to a different platform. The advantage of the PIC is that it uses 40 pin PDIP package of which 7 pins are reserved leaving 33 pins for user I/O. That is plenty of I/O and it has a "rich mixture” of peripheral devices, ADC, timers, serial port, EEPROM, watchdog ... Another feature of PIC is that each instructions is stored in just one 14-bit flash location, which means that exactly 8192 instructions fit into its 8K program memory. That gives compact program storage and fast execution as one instruction is executed in each program fetch-execute cycle. But the downside is the rather reduced "RISK" instruction set, compare the 35 different instructions of PIC to the ?? different instructions of Atmega. It is a bit challenging to overcome the limitations of this instruction set, but on the other hand there are always work-around solutions.

The 8 analogue inputs of 16F877 are not quite enough read two temperature sensors. An interim solution was for temperature check to be done in hardware by LM339 dual comparator. A better solution is to use the newer 16F887 which is an upgraded 877, with a nice bridge-motor controller (unfortunately of no use here) and a really massive 12 analogue inputs. The latest software runs on either 877 or 887, the latter being preferable as there are plenty analogue inputs, and other nice features.

For the specification and full description of micro-controller, see here.

Step 9: Software Description

The software performs the following management functions for two batteries:

  1. Stores the settings in EEPROM
  2. PWM charge control at intervals of about 20ms.
  3. Discharge protection at 1 second intervals
  4. Temperature check at 2 sec intervals,
  5. Fuel gauge calculations at 14 sec intervals,
  6. Logging and write to EEDATA at 15 min intervals,
  7. Reading keypad and updating LCD at 0.6 second or on menu-key demand.

This runs as an application program in the upper 4k (pages 2 and 3) of program memory, relying on PICBIOS in lower pages 0 and 1 for device I/O and handling interrupts.

For further details of software see here.

Step 10: Construction Details

The project can either be built on four separate PCBs, or on one larger PCB measuring 6 inch by 10 inch (150mm by 250mm) as shown above. For this use 57 track vero-board.

Print out the PCB layouts for two chargers, one micro and one temperature board (Eagle Files). Literally cut and paste onto the PCB then poke a pin through the paper to mark where each component will fit. Solder all components. Then poke a hole through paper between nodes which are not connected, and use a track cutter to break the track on reverse. Do continuity testing between all soldered connections. Do continuity test between nodes where the track should be broken. From experience it is easy to male mistakes at this point which will cost a lot of time later in fault finding.

You will need to print out the following PCB layouts (.PDF files)

Step 11: Charger Board Construction and Testing

After building each charger board, test as follows.

  1. Connect Vpv = 12V, and check output AN3=3V, adjust potentiometer R12 as required.
  2. Connect PWM=5V to switch the FET on, and check gate voltage Vgs about 5V.
  3. check AN1 = 3V, adjust potentiometer R15 as required.
  4. Check op-amp is powered, and Clamp=4.7V.
  5. Connect DIS=5V to switch output FET on, check gate voltage Vgs about 5V
  6. Connect Load resistor 120 ohm to OUT so 12V/120 =100mA flows through R1 and R2.
  7. Check TP1 = 12-0.7 = 11.3V, AN0=1V and AN2 = 1V.

Step 12: Temp Sensor Board Construction and Test

Step 13: Micro-controller Board Construction and Test

The 8MHz oscillator is not required for the 16f887 micro which has its own built in one. After building the micro-board, test steps 1 to 5 before inserting a PIC into the 40-pin socket.

  1. Do a careful continuity test
  2. Connect 12V to Vcc, and check VDD =5V, MCLR = 4.5V and VEE = about 0.5V.
  3. Connect 5V to serial port DTR and check the LED illuminates.
  4. Connect 5V to serial port TXD and check T1 is on and RC7(RX) = low (0V).
  5. Apply 0V to RC6 (TX) and check driver Q1 on and serial port RXD = high (5V).
  6. Switch off, insert a blank 16F887 into 40-pin socket and connect LCD module.
  7. Switch Vcc on and check supply current, Icc = 7mA about.
  8. Download the single executable file SOLAR_887.HEX
  9. Connect a programmer and program this file into device memory.
  10. Just hope you get “successfully programmed “ message.
  11. Restart and the software should display “PICBIOS” message on the LCD.
  12. Adjust the LCD potentiometer for best contrast.
  13. Run the solar charger application, test that the menu buttons work.

Step 14: Putting It All Together

After the circuits are individually tested, connect outputs of charger and temperature boards to inputs of micro board according to the interconnection diagram.

Get two batteries. I have used a Dyson DC16 battery pack, marked 1000mAh, which has 6 Li-ion cells and one thermistor. I think this had a former life in a vacuum cleaner before I found it and broke it into two individual 3-cell batteries, see photo. Connect up the PV panel, batteries, thermistors, LCD and switches and proceed to system testing.

Step 15: System Testing

It took about one weekend to get the basic structure of the software written. Then it took longer to build the hardware, as soldering is more of a fiddle than typing. The actual circuit worked fine because it was all checked before using LTSPICE. But the software is a different matter altogether, system testing has taken weeks while the software kept changing. Some changes are just simple bugs, others are improvements, and finally because the “TP4056 algorithm” does not quite work with a solar panel. For example, according to algorithm, the EOC condition is triggered when Ichg < Itrk. But for how long ? With a PWM switch, Ichg = 0 for up to 125 us (the PWM period) so in theory it does not work at all!

The system has been under test for a few weeks using a low power system consisting of 30W PV panel and two “pre-used” Li-ion cells marked 1060mAh. The software was configured to Cap=1Ah, Iset = Cap/5 hour=200mA. The batteries have been cycled between recharge (=11.4V) and float (=12.6V). The software is now considered “stable”, and the following are examples of test data generated.

The log for 16 September is shown above. This was a good sunny day with intermittent
cloud. The log is typical and shows what happens over a 10 hour period. At the start the batteries not fully charged and at 11.5Volt.

intervals 1 to 6 – the PV voltage rises until it reaches battery voltage.

intervals 7 to 16 – charging commences but PV cannot supply enough current to meet demand, so PV voltage is pulled down.

interval 17 to 21– there is bright sunlight and PV voltage shoots up to 17V. CC mode, and current limiting occurs.

interval 23 to 27 - bright sun and intermittent cloud, charge current jerking about all over.

interval 30 to 36 – CV mode, regulating float voltage as the batteries accept less current.

interval 36-37 end of charge condition occurs, current less than Threshold.

More information on system testing is given here.

Step 16: Conclusions

The software and hardware work, and the project is in operation powering low current devices (transistor radios, LED lighting etc.) day and night. Here are some observations on the circuit as it is.

  1. My intention is to migrate to a bit more power at some future time, something like 100 watt PV panel, 5Ah batteries, and charge current 2A for each battery. The hardware description explains the necessary changes.
  2. Since building the circuit I have found some high side current monitor chips like ST micro TSC101, Linear LTC6101 and Supertex HV7801, Maxim 80??. They use the same circuit technique as here - just in IC form. Using a pair of these chips would replace Q1, Q2, IC1b, IC1c and several resistors thus reducing the amount of construction. Unfortunately they are surface mount. So it looks as if a version 2 PCB is due already.
  3. Richtec provide a lot more information about coulomb counting.
  4. Cell type 03Li gives a float voltatge of 12.6V and is intended for giving a full charge just like operation of the TP4056 - but for 3 cell batteries.
  5. User type 44 (44UT) is intended for on-load charge operation. The battery constantly cycles between float (12.0V) and recharge threshold (11.4V) which according to web sites gives longer battery life as it is never stressed by charging to 12.6V.
  6. During charge, the PV provides current to charger and load.
  7. During EOC state, the battery provides current to the load, and the PV provides nothing. This is a consequence of the algorithm, a continuous trickle charge is not allowed.
  8. If the system is well designed and the load is predominantly at night (i.e. lighting), observation 7 is not a problem. The batteries will charge in day time and reach EOC by evening. The loads come on at night when there is no sunlight in any case and discharge the batteries down to recharge threshold for charging to start the next day.
  9. If the load is continuous (24 hour), the controller enters standby on EOC and the load may discharge the batteries in daytime. When the batteries discharge down to recharge voltage, the charger switches back on, starts recharging and PV provides power to load. This may happen repeatedly so at the end of day, the battery will be above Vrch, but may not be fully charged.
  10. If the load is predominantly on during the day (cooling, water pump) then why use a battery at all? Just connect PV directly to load. Or another suggestion would be to fit a bypass FET across charger to power the load directly from the PV while the battery is charged off-line (like a backup system). This is added complexity so not considered here.
  11. Or a simple solution to 7 would be to constantly trickle charge at a lower float voltage, in the same way that lead-acid chargers work. But is this allowed for Lithium?

I may continue developing the project, or maybe somebody else would like to do so. Otherwise the project is ready for others to build. Let me know if you spot any mistakes, wish to suggest improvements, and let me know about your success if you build it.