An arduino-based PWM open-hardware solar charge controller.
PWM charge controller schematic.

A crude schematic. Most of the components are pre-built modules, readily available.

This is a design for a 12V PWM solar charge controller. It is not the simplest of controllers. This honor could arguably be claimed by Julian Ilett's PWM5 design or by his alternate even smaller design. An open-hardware charge controller does have some advantages.

Note that the shunt does not need to be at all precise. In my prototype I used a shunt of too low a resistance for accurate measurement, and fixed this by simply drilling a hole in it. You can easily calibrate via software - you need only hook up a sizable load in series with an ammeter, note the shunt voltage reading and apply Ohm's law.

The PWM function itsself is almost identical to (and inspired by) Ilett's approach, though different in implementation. Both use an N-channel MOSFET, but we differ in our approach to driving it. Ilett's approach is to switch the panel on the high side, requiring the use of a charge pump to provide the required gate voltage, while I instead used a MOSFET on the low side driven via a PC817 optocoupler (a 300Ω or 330Ω resistor is suitable for current limiting, a 6k as a pull-down). This alternative design has a slightly lower component count. Note that this is a PWM-only design, not MPPT, but I intend to experiment with designing a seperate 'power optimiser' project for MPPT.

Only battery current is monitored - there is no provision to monitor solar panel or output current, as this data is of no importance when monitoring battery charging or condition. If this function is desired it would be trivial to add via either hall-effect current sensor or additional INA219 modules. They are I2C devices, and addressible.

Lead-acid charge cycle example.

Readings from the prototype when connected to a lead-acid battery bank with appropriate charge programmed. The battery is drained overnight by my garden lighting. The following morning the charge controller maintains (erratic cloud coverage permitting) a voltage of 14.4V on the battery until such time as the battery requires less than one amp to maintain this voltage, then switches to a lower-voltage 13.6V float mode. As well as showing the charge cycle, these readings also measure a voltage drop on the batteries when drawing even three amps that indicates an internal resistance many times greater than specification, excessive recovery times and a capacity many times less than rated. As these batteries had been sitting unmaintained for close to a decade and occasionally abused to power science projects demanding multi-hundred-amp surge currents, such poor condition is unsurprising and the batteries should be recycled.

Prototype.
The above readings came from this prototype. This is a cut-down version without a low-voltage load disconnect.

The current software includes only support for lead-acid batteries. Lead-acid battery charging is managed using a constant-voltage system - current limiting could be done entirely in software, but as the test-setup panel I used is only 100W there was no need for this. The target voltage is determined by a three-state machine:
- The 'init' state is entered when the controller powers up, and simply waits for one minute before transitioning to the 'top-up' state.
- The 'top-up' state maintains a voltage of 14.2V (sun permitting). It transitions to the 'float' when the current required to maintain this voltage falls below one amp, subject to some filtering to prevent unwanted transitions due to clouds blocking sunlight.
- The 'float' state maintains a voltage of 13.9V. It transitions to 'top-up' if the battery voltage drops below 12V, or after one week has passed (An occasional full charge being important to prevent sulfation).
- Both of these voltages are default for flooded lead-acid batteries, and should be lowered when using SLAs.

Other battery chemistries could be used with firmware alterations alone, no hardware modification required. There is no limit on the current the design can handle so long as sufficient MOSFETs are installed to share the load, but the voltage at the battery cannot be allowed to exceed 26V or the INA219 will no longer measure correctly. This is a serious and fundamental limitation, as it means the controller is not suitable for 24V or higher lead-acid systems unless the INA219 is replaced with an alternate form of current sensor.

The low part count is achieved in part by performing noise removal filtering in software - this eliminates the need for hardware low-pass filtering to remove noise from the PWM charging process or from the load devices when measuring battery voltage and current.

There are a few practical things to remember during construction:

Source is available.