4-cell BMS: Difference between revisions

From openinverter.org wiki
Jump to navigation Jump to search
(Updated the BMS wiring diagram)
(Updated to reflect current system design)
Line 1: Line 1:
[[File:4-cell module.jpg|alt=4-cell module|thumb|4-cell module]]
[[File:4-cell module.jpg|alt=4-cell module|thumb|4-cell module]]
[[File:Isolator module.jpg|alt=Isolator module|thumb|Isolator module]]
The 4-cell BMS owes its name to the fact that every cell module can monitor and balance up to for Lithium cells. It can be used for LiFePO4 (3.3V) or NMC (3.7V)  cell chemistries.
The 4-cell BMS owes its name to the fact that every cell module can monitor and balance up to for Lithium cells. Depending on the populated resistors it can be used for LiFePO4 (3.3V) or NMC (3.7V)  cell chemistries.


Its features are:
Its features are:
Line 10: Line 9:
* 2mA balanced cell drain during operation
* 2mA balanced cell drain during operation
* 50µA balanced cell drain in sleep mode
* 50µA balanced cell drain in sleep mode
* 1-wire bit-length-encoded current mode communication
* 1-wire UART current mode communication, 10kbit/s
The communication is terminated/translated via an isolator module. It translates the "proprietary" 1-wire protocol to a standard protocol, currently RS485. Its output connects the the first cell-groups positive terminal via a 1k resistor (Pin 3 of the 4-cell module) and the communication input. Its input connects to the last cell groups positive terminal, also via 1k resistor and the communication output.
* Very low cost due to generic component use and low component count
[[File:BMS Master Unit.jpg|alt=BMS Master Unit|thumb|BMS Master Unit]]
The communication is terminated/translated via at the master module. Its output connects the the first cell-groups positive terminal via a 220 Ohm resistor (Pin 3 of the 4-cell module) and the communication input. Its input also connects to the last cell groups positive terminal and the communication output.


All communication that goes into the first module is forwarded in a daisy-chain manner out to the last module. Each cell module can see the communication stream of the modules BEFORE it but not the modules after it. Exception: address mode, discussed below.
All communication that goes into the first module is forwarded in a daisy-chain manner out to the last module. Each cell module can see the communication stream of the modules BEFORE it but not the modules after it. Exception: address mode, discussed below.
The master unit has two CAN busses that can be used for system integration. It continuously estimates vital parameters like SoC and SoH, calculates power limits etc. In electric vehicles it can control fuel gauges via a 2 channel analog output. Finally a relay can be used for basic charge or discharge control.


== Wiring Diagram ==
== Wiring Diagram ==
Line 31: Line 34:
In run mode the module accepts the following commands
In run mode the module accepts the following commands
* "Get Data X" : module X sends its 4 cell voltages and the temperature within the controller (cell group temperature)
* "Get Data X" : module X sends its 4 cell voltages and the temperature within the controller (cell group temperature)
* "Shunt X Y": module X sets its shunt target voltage to Y+3000 mV. Returns Y for plausibility checking
* "Shunt X Y": module X enables shunts Y (bitmask). Returns Y for plausibility checking
* "Get version X": module X sends its hardware and firmware version
* "Get version X": module X sends its hardware and firmware version
* "Reset address": All modules reset their address and enter address mode
* "Reset address": All modules reset their address and enter address mode
* "Calib X Y Z": module X adds Z to the the gain factor of channel Y. Returns the new gain factor. Z can be negative. Y can be
** 0-3: low resolution voltage channels gain
** 8-11: high resolution voltage channels gain
** 16: temp sensor offset
** 31: lock calibration to prevent unwanted changes during operation
* "Update": All modules change to firmware update mode
* "Update": All modules change to firmware update mode


=== Update mode ===
=== Update mode ===
This allows updating the modules firmware via the existing 1-wire communication bus. The current version with 4k of flash memory expects 56 pages of 64 bytes each, prepended with the page number and terminated with the pages CRC16. The protocol is implemented in a python script. If any module discovers a CRC error it sends a pulse onto the bus. The isolator then has to resend the page.
This allows updating the modules firmware via the existing 1-wire communication bus. The current version with 4k of flash memory expects 56 pages of 64 bytes each, prepended with the page number and terminated with the pages CRC16. The protocol is implemented in the master unit and the cell module firmware is embedded into the master units firmware. If any module discovers a CRC error it sends a pulse onto the bus. The master then has to resend the page.


As we are planning to switch to the Attiny84 this would have to be changes to 120 pages. (The boot loader takes up 8 pages).
As we are planning to switch to the Attiny84 this would have to be changes to 120 pages. (The boot loader takes up 8 pages).


== Isolator Command line interface ==
== Isolator Command line interface - deprecated! ==
As already known from the inverter the isolator is controlled via a simple command line interface to carry out above operations. Since there can be more then 1 isolator on the RS485 bus each isolator is automatically assigned an address that has to be supplied to each command. This results in a hierarchical bus structure where the 1st module on the 1st isolator has address "1.1" and the yth module on the xth isolator has address "x.y".
As already known from the inverter the isolator is controlled via a simple command line interface to carry out above operations. Since there can be more then 1 isolator on the RS485 bus each isolator is automatically assigned an address that has to be supplied to each command. This results in a hierarchical bus structure where the 1st module on the 1st isolator has address "1.1" and the yth module on the xth isolator has address "x.y".
Com speed is 115200.
Com speed is 115200.
Line 70: Line 68:
Lock calibration data of cell module x.y
Lock calibration data of cell module x.y
  cmupdate
  cmupdate
All cell modules on all isolators enter update mode. Afterwards the isolators expect binary data on the console. 1 byte page number, 64 bytes page data, 2 bytes CRC16 xmodem over page num and page. After sending a page wait 170ms. If there is no response from any isolator continue with the next page. If there is, resend the page. After 56 pages the cell modules exit update mode and jump to the new firmware.
<syntaxhighlight lang="Python" line="line">
 
<syntaxhighlight lang="Python" line='line'>
import serial
import serial
import crc16
import crc16
Line 133: Line 129:
         page = page + 1
         page = page + 1
          
          
</syntaxhighlight>
</syntaxhighlight>All cell modules on all isolators enter update mode. Afterwards the isolators expect binary data on the console. 1 byte page number, 64 bytes page data, 2 bytes CRC16 xmodem over page num and page. After sending a page wait 170ms. If there is no response from any isolator continue with the next page. If there is, resend the page. After 56 pages the cell modules exit update mode and jump to the new firmware.
 
== Plans ==
To become compatible with Tom De Bree's "SimpBMS" a CAN isolator is planned. It would operate more autonomous spitting out voltages and temperatures continuously and accepting shunt commands. Both should mimic some already existing BMS CAN protocol. The specialized commands can be implemented in which ever fashion.

Revision as of 18:59, 3 March 2020

4-cell module
4-cell module

The 4-cell BMS owes its name to the fact that every cell module can monitor and balance up to for Lithium cells. It can be used for LiFePO4 (3.3V) or NMC (3.7V) cell chemistries.

Its features are:

  • High resolution (1mV) voltage measurement around the typical cell voltage 3.1-3.4 for LFP, 3.6-4V NMC
  • Low resolution (10mV) voltage measurement outside the typical cell voltage
  • Low resolution (+/- 5°C) cell group temperature (sensor embedded in controller)
  • 20mA balancing current via a 2.4V (LFP) or 3.3V(NMC) LED. This prevents full cell drain in case of faults in the balancing software or circuitry
  • 2mA balanced cell drain during operation
  • 50µA balanced cell drain in sleep mode
  • 1-wire UART current mode communication, 10kbit/s
  • Very low cost due to generic component use and low component count
BMS Master Unit
BMS Master Unit

The communication is terminated/translated via at the master module. Its output connects the the first cell-groups positive terminal via a 220 Ohm resistor (Pin 3 of the 4-cell module) and the communication input. Its input also connects to the last cell groups positive terminal and the communication output.

All communication that goes into the first module is forwarded in a daisy-chain manner out to the last module. Each cell module can see the communication stream of the modules BEFORE it but not the modules after it. Exception: address mode, discussed below.

The master unit has two CAN busses that can be used for system integration. It continuously estimates vital parameters like SoC and SoH, calculates power limits etc. In electric vehicles it can control fuel gauges via a 2 channel analog output. Finally a relay can be used for basic charge or discharge control.

Wiring Diagram

Wiring Diagram

Operation

When installed there are 4 modes of operation:

  • After power up, i.e. when the module is connected the first time to the cell terminals, it is in wait-address mode
  • When address is assigned, it changes to run-mode
  • When there is no communication for about 30s it changes to sleep mode
  • When an update command is received, it changes to firmware update mode

Address mode

When the 4-cell module is in address mode it disables forwarding of the communication stream to the next module. This makes it possible to only communicate with a single module, the first one. As soon as it receives a "set address X" command it assigns address "X" to itself, enables communication forwarding and sends a "set address X+1" command to the next module. This continues for the entire chain until the isolator receives the address of the last module + 1. Thereby it knows how many modules there are.

Run mode

In run mode the module accepts the following commands

  • "Get Data X" : module X sends its 4 cell voltages and the temperature within the controller (cell group temperature)
  • "Shunt X Y": module X enables shunts Y (bitmask). Returns Y for plausibility checking
  • "Get version X": module X sends its hardware and firmware version
  • "Reset address": All modules reset their address and enter address mode
  • "Update": All modules change to firmware update mode

Update mode

This allows updating the modules firmware via the existing 1-wire communication bus. The current version with 4k of flash memory expects 56 pages of 64 bytes each, prepended with the page number and terminated with the pages CRC16. The protocol is implemented in the master unit and the cell module firmware is embedded into the master units firmware. If any module discovers a CRC error it sends a pulse onto the bus. The master then has to resend the page.

As we are planning to switch to the Attiny84 this would have to be changes to 120 pages. (The boot loader takes up 8 pages).

Isolator Command line interface - deprecated!

As already known from the inverter the isolator is controlled via a simple command line interface to carry out above operations. Since there can be more then 1 isolator on the RS485 bus each isolator is automatically assigned an address that has to be supplied to each command. This results in a hierarchical bus structure where the 1st module on the 1st isolator has address "1.1" and the yth module on the xth isolator has address "x.y". Com speed is 115200.

get x.y

Instruct isolator x to send the "Get Data y" command in order to obtain measurements from cell module y. The values are NOT printed out to allow get commands to all existing isolators without bus collision. The values are printed with:

print x

Print the values obtained by the last get command. Looks like this:

val x.y:U1,U2,U3,U4,T,CRC16

U1 to U4 are mV, T is °C. CRC16 is the X-Modem CRC of the string up until the last ",". (_crc_xmodem_update() from avrlib)

shunt x.y z

Sets shunt threshold of module x.y to z mV. z can be from 3000 to 5000mV. 3000mV is considered "no shunting". The shunt command times out (not sure how long it takes, say 1 minute) and has to be resent in order to continue shunting. When the module enters sleep mode shunting is also stopped.

mmuver x

Print firmware version of isolator X (used to be called module management unit)

cmuver x.y

Print firmware version of cell modules x.y

setadr x

Isolator x sends "set address 1" command to the first attached module

resetadr x

All cell modules on isolator x enter wait-address mode

calib x.y chan delta

Add delta to calibration channel chan of cell module x.y. Prints out the new calibration value (calib x.y: val) or "Calib command failed" on invalid response from cell module.

calib x.y 31 0

Lock calibration data of cell module x.y

cmupdate
import serial
import crc16
import time

PAGE_SIZE_BYTES=64
MAX_PAGES=56

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.01)
ser.flushInput()
ser.flushOutput()
updateFile = open("bms-tiny.bin", "rb")
data = bytearray(updateFile.read())
updateFile.close()

numBytes = min(len(data), PAGE_SIZE_BYTES * MAX_PAGES)
numPages = (numBytes + PAGE_SIZE_BYTES - 1) / PAGE_SIZE_BYTES

#Pad unused space with 0xff
while len(data) < (PAGE_SIZE_BYTES * MAX_PAGES):
    data.append(0xff)

print ("File length is %d bytes/%d pages" % (numBytes, numPages))
print ("Entering update mode...")

ser.write("\ncmupdate\n")
time.sleep(1)
page = 0

def sendPage(ser, data, page):
    binData = bytearray(PAGE_SIZE_BYTES + 3)
    binData[0] = page
    
    crc = crc16.crc16xmodem(chr(binData[0]))
    
    for i in range(0, PAGE_SIZE_BYTES):
        binData[i+1] = data[page * PAGE_SIZE_BYTES + i]
        crc = crc16.crc16xmodem(chr(binData[i+1]), crc)
    
    binData[1 + PAGE_SIZE_BYTES] = crc & 0xff
    binData[2 + PAGE_SIZE_BYTES] = (crc >> 8)

    print ("Sending page %d, crc %x" % (page, crc))
    
    for i in range(0, PAGE_SIZE_BYTES + 3):
        ser.write(chr(binData[i]))
        
    return crc

while page < MAX_PAGES:
    crc = sendPage(ser, data, page)
    
    # Allow 110ms for the page to be sent to the CMUs, 40ms
    # for the page to be written to flash and 20ms for the MMU replies
    time.sleep(0.17)
    response = ser.read(100)
    print response
    
    if response == "":
        page = page + 1

All cell modules on all isolators enter update mode. Afterwards the isolators expect binary data on the console. 1 byte page number, 64 bytes page data, 2 bytes CRC16 xmodem over page num and page. After sending a page wait 170ms. If there is no response from any isolator continue with the next page. If there is, resend the page. After 56 pages the cell modules exit update mode and jump to the new firmware.