Wednesday, 25 April 2018

7S Lipo balancing with relays

I'm not an electrician so this isn't a how-to, and if you follow it you do so at your own risk, rather it's documentation of how I've gone about building a system to balance my 7S home made powerwall.

This is a work in progress.

The main components I've used are a 16 Channel Relay (5V) and a Raspberry Pi Zero W



I use all 16 of the relays for wiring, though the most relays that are ever powered is 14.  This means that the most current that needs to be supplied to the relays is just less than 1A at 5V.

Ideally this should be done with switches that break the positive and negative at the same time - with this arrangement it cannot be guaranteed, so other precautions are wise.  I use 2 relays to break both the + and -  output connections (top left in picture).  The relays operate in pairs using the following protocol.


All relays disconnected

Output +ve disconnected
Output -ve disconnected

Cell 1 +ve goes to Relay 1 NC
Cell 1 -ve goes to Relay 2 NC

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 1 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 2 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised
Relay 3 energised
Relay 4 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 3 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised
Relay 3 energised
Relay 4 energised
Relay 5 energised
Relay 6 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 4 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised
Relay 3 energised
Relay 4 energised
Relay 5 energised
Relay 6 energised
Relay 7 energised
Relay 8 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 5 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised
Relay 3 energised
Relay 4 energised
Relay 5 energised
Relay 6 energised
Relay 7 energised
Relay 8 energised
Relay 9 energised
Relay 10 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 6 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 energised
Relay 2 energised
Relay 3 energised
Relay 4 energised
Relay 5 energised
Relay 6 energised
Relay 7 energised
Relay 8 energised
Relay 9 energised
Relay 10 energised
Relay 11 energised
Relay 12 energised

Output +ve connected (Relay 16 energised)
Output -ve connected (Relay 15 energised)

[Cell 7 now connected to output]

Output +ve disconnected (Relay 16 NO POWER)
Output -ve disconnected (Relay 15 NO POWER)

Relay 1 NO POWER
Relay 2 NO POWER
Relay 3 NO POWER
Relay 4 NO POWER
Relay 5 NO POWER
Relay 6 NO POWER
Relay 7 NO POWER
Relay 8 NO POWER
Relay 9 NO POWER
Relay 10 NO POWER
Relay 11 NO POWER
Relay 12 NO POWER

So by using the relays, we have been able to switch the output so that each of 7 cells can be accessed in turn.

If there were an 8th cell (balancing cell) on the output connection, then each of the cells would have been connected to it in turn, and if a number of cycles were carried out, then the cells would all be balanced.

Precautions
Each of the connections to the 7 cells is made with a fused connector.
In the event of the failure of one of the relays, it may be possible for more than one cell to be connected to the output. To guard against that I have fuses and a separate voltage monitor controlling a relay.  If at any time the output of the the 16 channel relay board is above 4.2V the balancing cell is disconnected from the output.



Wiring Diagram






Wiring of the Pi Zero W



GPIO 1 (3.3V) went to 16 Channel relay header +5V
GPIO 2 went to 16 Channel relay header 1
GPIO 3 went to 16 Channel relay header 2
GPIO 4 went to 16 Channel relay header 3
GPIO 17 went to 16 Channel relay header 4
GPIO 27 went to 16 Channel relay header 5
GPIO 22 went to 16 Channel relay header 6
GPIO 10 went to 16 Channel relay header 7
GPIO 9 went to 16 Channel relay header 8
GPIO 11 went to 16 Channel relay header 9
GPIO 5 went to 16 Channel relay header 10
GPIO 6 went to 16 Channel relay header 11
GPIO 13 went to 16 Channel relay header 12
GPIO 19 went to 16 Channel relay header 13 (not used)
GPIO 26 went to 16 Channel relay header 14 (not used)
GPIO 21 went to 16 Channel relay header 15
GPIO 20 went to 16 Channel relay header 16

I DID NOT CONNECT GROUND from the RPi Zero W to the 16 Channel relay header pins
(think it may short/damage if you do this)

A 5V  power source was connected to the DC power input connector on the 16 Channel relay board


Pi Software
I installed the latest version of Raspian (Stretch) and made sure python was installed.

I wrote a shell script to implement the switching protocol mentioned above.  I hardly ever write in python so I used the work of skiwithpete as inspiration/help

The code for the protocol above is given below.

Using your favourite editor make a file bbalance.py containing the following


#!/usr/bin/python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

pinList = [2, 3, 4, 17, 27, 22, 10, 9, 11, 5, 6, 13]

for i in pinList:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.HIGH)


GPIO.setup(20, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)


SleepTimeL = 60
SleepTimeS = 1


time.sleep(SleepTimeL)
for i in range(0,11,2):
        GPIO.output(20, GPIO.HIGH)
        GPIO.output(21, GPIO.HIGH)
        time.sleep(SleepTimeS)
        GPIO.output(pinList[i], GPIO.LOW)
        GPIO.output(pinList[(i+1)], GPIO.LOW)
        time.sleep(SleepTimeS)
        GPIO.output(20, GPIO.LOW)
        GPIO.output(21, GPIO.LOW)
        time.sleep(SleepTimeL)

GPIO.output(20, GPIO.HIGH)
GPIO.output(21, GPIO.HIGH)
time.sleep(SleepTimeS)
for i in range(0,12):
  GPIO.output(pinList[i], GPIO.HIGH)
time.sleep(SleepTimeL)




Make the script executable with the command

chmod 755 ./bbalance.py


I set time intervals for balancing of 1 minute (SleepTimeL), this means with 7 cells it should take  approx 7 minutes to go through a balancing cycle.

I then set up a cron job to run the script every 10 minutes - I don't know how many times it will take to balance cells, so this cron job will run between the hours of say 2am and 5am, then shutting the pi down until rebooted next day (to save power).  I'll see how effective this is at balancing my cells over time and will tweak as required.  I will disconnect power to the pi remotely at 6am, and power it up remotely at 1:45am

using Crontab to make a cron job to automate the running of bbalance.py

crontab -e

then append the line to run it every 10 minutes - adjust start time and duration as necessary

*/10 * * * * /usr/bin/python /home/pi/bbalance.py




Known issues
Some of the connecting wires are longer than others, may make a slight difference to balancing, but probably not significant.  Similarly some cells are connected through more relays than others, so this may cause some resistance - time will tell if this causes issues balancing.

A relay failure could result in more than one cell being connected to the balancing cell - hence the fuses are one mitigation, but I also use a second independent wimos D1 mini that measures the voltage, and only connects the balancing cell if the voltage is acceptable - I plan to make this log the voltages to my MQTT server too.

More details in my next post.