7.9.17

Load balancing TP4056

I have a set of small, 6V solar panels.
Both are able to produce ~300mA in near-perfect conditions (600mA combined).
The problem is such output is available only in extremely positive conditions.
Majority of the time, the panels produce around 100-200mA.
And the problem is the settings of the TP4056 - it allows charging of the battery by up to 1A (consuming 1.1A at 5V in such conditions).

There is an Rprog resistor that sets the charging current.
When set too high, the load will cause the solar panel to severely decrease the power output. The voltage will drop close to 4V which makes the charger only "trickle" charge the battery. The result is slow but severe decline in battery power and even on sunny days almost no charging.
When set tool low, it works in majority of conditions, but when sunny, one is wasting a lot of energy - e.g. panels deliver 600mA, but you can only use 120mA out of it.

I wanted to do something similar to MPPT (maximum power point tracking).
To do so, I installed INA219 power sensor on the power line of the panel - by that I know how much power do I get to the system.

I de-soldered the 1.2k resistor and soldered a lead to PIN2 of the TP4056. The resistance is set against the ground.

I made simple measurements and discovered, that any resistor above 11k results in charging current of ~70mA. Good enough.
Lowering the resistance had direct impact on the current, the voltage was always 4.28V during the main charging cycle.
I decided to use 3 N-channel MOSFETs (BS170) to connect another 3 resistors in parallel. I used values of 22k, 12k and 6.8k. The resistance of BS170 is negligible (around 5 ohms as far as I remember).
Using these 4 resistors, I can modify the resistance in a range between 12k to 2.78k. The highest resistance results in 70mA charging current, the lowest results in approx. 460mA. Good enough.
I need 3 data lines from the ESP8266 to drive the MOSFETs. I used 2.2k resistor to drive the gates from the data pins.
I had insufficient pins available, so I used everything available (IO0, IO14 and IO15).
The only problem was that I was connecting the data lines to the resistors in the night and had no idea which one is which.

So, in the code I initially drive all the outputs low, therefore the resistance is 12k. This was enough to partially charge the battery, but despite very sunny day I wasted most of the energy.

I thought about opening the box again and looking at the connection, but I was lazy - so I came with a workaround.
Every 3 minutes the ESP does a "measuring exercise". It walks through all the possible resistor combinations, waits 1 second to stabilize the power output and then measures the power using the INA219 sensor.
It takes 8 seconds to do so, afterwards the code selects the best power combination and sets it as a resistance output for next 3 minutes.

I am testing it now for a first day - so far it's extremely cloudy comparing to yesterday, but the battery is charged better than yesterday. I can see in the logs that the resulting resistance is constantly adjusted. So far I am very happy with it.

Next step is to replace this "rough" solution with digital potentiometer with Up/Down or i2c protocol. This will allow me to change the resistance 1 step at a time and do better power approximations over time. It might be done constantly, not every 3 minutes, potentially grabbing even more solar energy. I already have MCP4018T-103E, but the SO-70 package make it useless for me - I have to order something through-hole or at least bigger than this.

Still, I am very happy with the setup and will continue to do comparative measurements.