Solectria E10 Lithium-Ion Upgrade

July 14th 2015, I won an auction for a used 2013 Nissan Leaf battery pack. The pack was pulled from a wrecked Leaf. $2959.33 including shipping.

The Nissan Leaf battery pack is made of 192 Lithium-Ion (LiMnO2) cells, in a 96s2p configuration.
Each cell is 32.5Ah @ 3.75V nominal, (3.2V - 4.2V). Four cells per module in a 2s2p configuration. 
And with 48 modules in the pack,
this results in a 65Ah @ 360V.

Since my Solectria E10 runs at 144V nominal, I can't use the battery pack as is...
So I am going to reconfigure the pack: 2 parallel stacks of 20 modules in series, 40s4p configuration.
Resulting in 130Ah @ 150V nominal (With 8 modules left over to be used in other projects).

This should get me a 60ish mile range... However, this leaves room in the battery boxes for potentially another 2 Leaf battery packs, for a total range of 180ish miles.
And this will still be about 200 pounds lighter than my current lead acid gel cell pack.

I plan on reusing the almost everything in the battery pack, including the contactors, current sense, temperature sensors and most importantly the Battery Management System (BMS).

When I reconfigure the pack for my truck, I will only have 20 balancing chips... This will cause the BMS microcontroller to get really unhappy... Since it will fault out on the missing chips.

So I plan on figuring out how the BMS microcontroller talks to the balancing chips, so I can insert my microcontroller and use all the existing BMS hardware.
Kind of like a brain transplant. 

A more elegant solution would be to read out the flash and decompile the BMS microcontroller, then modify the firmware such that it has 20 balancing chips... But I am not sure what, if any protections they have against this. Reverse engineering the serial protocol seems easier to me then reverse engineering byte code assembly.  

The majority of the time on this project will be spent on reverse engineering the BMS, specifically how the microcontroller commands and reads the 24 balancer chips.
So it can be reconfigured for
2 parallel stacks of 20 modules in series.

July 27th 2015, The battery pack arrived via heavy freight. I cleaned out the "motor cycle" parking spot in the garage, and the pack found its new home... on top of a few furniture dollies for easy maneuvering:

There was a little bit of damage visible on the exterior. The main power connector and part of the outer casing got crunched in the wreck.


Overview and Plan for the Nissan Leaf Battery Pack:

August 1st 2015, Since I did not know the state of the pack, I wanted to turn on the internal contactors to measure the total pack voltage...
However, the user manual I had did not match the connector type and pinout on the pack.


Reverse engineering the connector pinout on a 2013 Nissan Leaf battery pack:

Using an ohm meter I was able to track down which pins went to the coils of the contactors, the pre-charge relay and the CAN termination resistor.
Using this data I was able to reverse engineer the pinout of the connector.

The battery pack was missing the main disconnect... So I made one out of a 5 amp fuse and some meter leads. They fit perfectly into the holes.


With the volt meter on the output connector, I applied 12V to both the high side and low side contactors... They "thunked" and the meter showed 385.0V
With 96 cells in series, this results in 4.010V per cell. Almost fully charged!

Turning on the pre-charge and negative contactors to measure the pack voltage:

Using a spare DMOC Adapter I wrote some code so it could talk over CAN (Controller Area Network) bus to the BMS (Battery Management System) in the Leaf pack.


Getting the DMOC Adapter to talk to the Nissan Leaf battery pack and sniffing the CAN packets:

August 9th 2015, Decoded some of the packets, and reading back all the individual cell voltages:

January 30th 2016. Finally got some free time to work on the battery pack...

After sitting for 6 months I checked that I could still communicate with the pack:

During this time the battery had self discharged to around 4.004V per cell.

Removal of the 6 bolts around the safety disconnect:


Removal of the 10 bolts around the perimeter of the battery pack:


Using a modified scraping blade (I removed the bend in it, so it was long enough) and an oscillating tool to cut through the gasket sealing the cover on the battery pack:


After about 30ish minutes the cover came off. Assorted pictures of the battery pack:


I particularly like the last picture of the warning sticker: "DO NOT ATTEMPT TO DISASSEMBLE OR REPAIR".

Inside the 2013 Nissan leaf battery pack:

The next day, I took out the Battery Management System (BMS)...

And then opened it up.

Overview of the battery management system:

Soldering wires on the TX (Pin 25) and RX (Pin 26) lines on the microcontroller...

So I could sniff the serial (19.2k baud, 8 bit, no parity, 1 stop bit) communications between the micro and the balancer chips: 

Recording serial communications between the microcontroller and balancing chips... Attempting to decode the protocol:

February 6th 2016, I determined that the last byte in the packet is the check sum, or as it turned out a cyclic redundancy check (CRC8, polynomial 0x85).
Since eventually I will replace the microcontroller in the BMS with my own, I need to know the CRC check or the balancer chips will ignore my serial communications.

These are the reverse engineering steps I took to determine the polynomial:

February 7th 2016, I had acquired another BMS... 
But unfortunately it was an earlier model with different connectors, which where keyed differently. 
Note the gray and black connectors on the 2013 BMS, and the all white connectors on the older BMS:

The balancer chips are different too:
"D15120" on the 2013 BMS
"D15110" on the older BMS

The pinouts are identical between the two and thus, they should work... except for the pesky connector keying...
But keys can be changed... or in this case removed:

Soldered another set of wires on the TX (Pin 25) and RX (Pin 26) lines on the microcontroller... and placed the older BMS into the battery pack.

Testing the older BMS on the battery pack:

Unfortunately the older BMS uses a different serial protocol than the 2013 BMS.

2013 BMS serial stream:


Older BMS serial stream:


February 13-14th 2016, Since the battery cells voltages are stable and don't change much... 
I did not have enough data to figure out how the serial data encoded the voltage of the cells.
So I built a Lithium-Ion battery cell simulator (2.0V - 4.6V adjustable power supply):

Time lapse video of the Lithium-Ion battery cell simulator being built:

When I purchased the older BMS it also came with a wiring harness. 
Modifying this spare harness, I was able to substitute cells 93, 94, 95 and 96 with the voltages from the 4 adjustable power supplies. 
These cells where chosen because they are at the lowest voltage potential of the pack (one side of cell 96 is ground).

Lithium-Ion battery cell simulator hooked up to the BMS, battery pack, and DMOC Adapter.

Overview of Lithium-Ion battery cell simulator, and how it is connected to the Nissan Leaf battery pack:

February 20-21st 2016, Had some trouble using the UART on the DMOC Adapter to read the serial data...

Ended up having to use an interrupt, and two one shot timers to get it to work:

Then wrote some code to send the serial data over WiFi to the browser for decoding:

February 27-29th 2016, Using the battery cell simulator, I was able to change the voltages on cells 93, 94, 95, and 96 on balancer chip 24. 
Using this info I was able to correlate the values in read over the CAN bus to the values I was reading over the serial bus.


Note: Both packets above encode the same cell voltage data.

Byte 14 in the packet toggles between 0x40 and 0x80, using this as a flag I printed every other packet. 
This resulted in the same cell voltage, but encoded in two different serial packets.

Focusing on the the data in the 0x80 packet, I could see the bytes changing as I changed the voltages on each of the simulated cells.

First I slowly turned up the voltage on cell 93, until the value read over the CAN bus pegged at 4.545V. I then turned cells 94, 95 and 96 all to 4.545V.
I was reading all 0xFF in bytes 6,7,8, 9 and 10 which store the cell voltage data.

I then turned cell 93 slowly down watching which byte 6 count down until 3.408V, where it wrapped from 0x00 back to 0xFF, and byte 7 went from 0xFD to 0xFC.
I continued to turn cell 93 slowly down watching which byte 6 count down until 2.270V, where it wrapped from 0x00 back to 0xFF, and byte 7 went from 0xFC to 0xFF.

This puzzled me until I realized that it is a signed value. Cell voltages are packed signed 10 bit, 2's complement.

This made the data in the 0x40 packet make sense, since it became positive at this time.

The balancing chips must contain a fully differential front end. 
The 0x80 samples are + - and 0x40 samples are - + with respect to the cell.
It looks like the Microcontroller alternates between the two and takes the average between the samples to remove any front end bias (leakage current).

Decoding of packets between the balance ICs and the microcontroller:

March 10th 2016, Sniffing more data.

Bytes 11 and 12 contain a "fifth cell" voltage data. This appears to measure the balancer chips internal linear regulator. The linear regulator takes the combined 4 cell stack voltages down to 4.12-ish volts to power its self.

The reference voltage is packed 11 bit, 2's complement signed, but is only ever positive, thus full scale is 1023 = 4.545V. This is different from the individual cells... but it does not appear that the reference voltage is sampled differentially. So this might be correct.

The remaining bits in Byte 12 and byte 13 might contain a battery "health" type value or "balanced" value (still working on this, might be missing a bit or 2), The value seems to act like a bell curve with respect to the 4 cell stack voltage. 

If the cell voltages are above 4.2V, the value is low.
If the cell voltages are in the 3.2V - 4.2V, the value is higher.
If the cell voltages are lower than 3.2V, the value is low.

March 12-14th 2016, I modified the battery cell simulator, (and schematic) adding a header so I could open and short the "cell" with a jumper. 

Using the perturb and observe method, I gained some more info:

Bytes 13 and 14 contain a "sixth cell" voltage data. This appears to measure the balancer chips internal ground connection. Typically returns 0... but every once in a while there is a 1 bit change. Still not sure, but I think it is 11 bit, 2's complement signed, like the reference voltage measurement.

Byte 16 upper 2 bits normally counts 0, 1, 2, 3, 0, 1, etc... but, when the , but not sure what they mean.

Byte 16 remaining 6 bits and byte 15 make up a 14 bit time stamp.

Bytes 4 and 5 are also cell status:
Byte 5 upper nibble is cell under volt status.
Byte 5 lower nibble is cell over volt status.
Byte 4 upper nibble is cell fault status.
Byte 4 lower nibble is cell shunt status.

Byte 3 upper 2 bits also encode chip status... I have seen 0xF2 become 0xFA if the cell voltages get too low, such that it has problems powering its self.

I also updated the serial decoder page with this new info, and also laid out the for better read ability.


The most interesting thing is that the LEAF BMS balances all the time.
Once cells are out of range, (not sure of the %) the balance shunts start tuning on. 
Each shunt is a 430 ohm resistor, (1206 size, marked "431" at the bottom of this pic), so under 10mA of balance current.

Because the BMS is always balancing, I was able to turn up a few cells and see what happened:

With cells 93 and 94 set higher than the rest of the pack (4.124V), and cells 95 and 96 set to the same as the rest of the pack (4.0ish volts).
Cells 93 and 94 balance shunts are on:

Removing the jumper on cell 93 causes it to drop to 0 volts, resulting in a cell 93 under volt flag:

Removing the jumper on cell 94 also causes a cell 94 under volt flag:

With the jumpers back in, turning cell 93 up to 4.515V causes a cell 93 over volt flag, and a converter fault:

Most importantly I was able to see the balance shunt enable/disable control packet:
0x55 0x99 0xXX 0xFY 0xZZ

Such that:
0xXX = 0x21 - 0x38 = chip address
0xFY = lower nibble is which shunt should be enabled.
0xZZ = CRC8 check sum.

There are a few other control packets that I don't know what they do yet... 
I warmed up the three temperature sensors and spoofed the current sense with a clip leaded potentiometer, but it had no effect on the control packets.

The remaining control packets look like they toggle between two values, these are probably what tells the converters to sample differentially.

I am working on a final ICD (Interface Control Document), that I will publish here with all the findings and notes (and update it as I learn more).

Video showing adjusting cell voltages to cause balance shunts to turn on/off, under volt flags on/off, over volt flags on/off, and measuring the balance current:



March 19-31st 2016, Using the continuity check on my volt meter, I was able to map out the functions of all 100 pins on the BMS microcontroller. 

Next I designed a schematic which maps all the functions from the PD70F3236 microcontroller to my dsPIC33EV256GM106 microcontroller.
Including some extra inputs and outputs, that are not populated on the BMS (I can populate the missing parts, if I need more I/O).

Then I designed a circuit board that will get soldered in place of the 100 pin TQFP PD70F3236 microcontroller.
This PCB takes care of the mapping from the 100 pin footprint to the 64 pin QFN dsPIC33EV256GM106 microcontroller.

The white connector hanging off the side of the board is the programming / debugging connector for the ICD3 "hockey puck".

Video overview of the board, and an 0402 resistor sitting on a penny for a sense of scale:

April 1st 2016, I unsoldered the PD70F3236 microcontroller using the de-soldering station at work, (during my lunch hour). 

Video of the de-soldering process, (I kept turning up the heat until the microcontroller came off):

After I removed microcontroller, I sent the files off to the board house.

More EV Projects