GregH wrote:So with a little help from TickTock and a friend at Nissan, we've been able to replicate some of the specific CAN messages used by the technician's scan-tool to read data from the Leaf battery management system.
First of course I should say that SENDING CAN messages to your Leaf (as compared to passively listening) could cause problems although most of the harmful writable data is usually protected with additional check-sums.
Anyway.. Proceed at your own risk..
What we're doing here is sending specific request messages asking for groups of data from the HV battery subsystem.
As best we can tell all of the requests from the scan-tool regarding the HV battery are sent on the 0x79b CAN ID with responses on 0x7bb. All packets are 8 bytes although sometimes not all 8 are utilized.
We've found 5 different groups of data...
Group 1 has 6 lines of data (not sure what it is yet)
Group 2 has 29 lines of data and contains all 96 of the cell voltages.
Group 3 has 5 lines and contains the Vmin and Vmax as well as a few other things we haven't figured out yet.
Group 4 has 3 lines of data and contains the 4 pack temperatures.
Group 5 has 11 lines and again, not sure what it is yet..
In order to read a group of data, first send the initial request command on ID 0x79b:
0x02 0x21 group 0xff 0xff 0xff 0xff 0xff (those last 5 bytes can be 0xff or 0x00, doesn't seem to matter, and yeah I tried group 0 and 6.. didn't see anything)
For example to request pack temperatures you'd start with
0x79b: 0x02 0x21 0x04 0 0 0 0 0
Which returns something like:
0x7bb: 0x10 0x10 0x61 0x04 0x01 0xfb 0x15 0x01
The first byte is an index (incremented on subsequent lines), the 2nd byte is a sort of group size, the 3rd byte is 0x61 (responding to the 0x21) and the 4th byte is the group number. The actual data starts on the 5th byte.
In this example the first temperature is a 3 byte value (16bit raw A/D and 8bit temp) 0x01fb 0x15 meaning 21 degrees C with the raw 10 bit A/D NTC thermistor value 0x1fb or 507 decimal. The start of the 2nd temperature is the last byte of the message.
To ask for additional lines of data, they must be requested within about a second of the initial request. In my software I ask for the 2nd line immediately after receiving the first and then ask for subsequent lines every 16ms or so.
The request additional lines command is
0x79b: 0x30 0x01 0x00 0xff 0xff 0xff 0xff 0xff
All subsequent lines will have an index in the first byte with 2 as the MS nibble and the lower nibble (4 bits) as the index.. The remaining 7 bytes are all data.
0x7bb: 0x21 0xf8 0x15 0x02 0x06 0x13 0x02 0x0d
(ie the other 2/3rds of temp2, all of temp3 and the first 2/3rds of temp4)
In order to receive the last line, another 0x30 0x01 0x00 request is sent and for this example the response looks like:
0x7bb: 0x22 0x13 0x13 0x00 0xff 0xff 0xff 0xff
(giving the last byte of temp4.. not sure what if anything the extra 0x13 and 0x00 mean... maybe some check-sum)
On a side note, I'm trying to recreate the thermistor circuit so that we might be able to get more precise temperatures calculated from the raw A/D value as compared to the car's 1 degree C reading. As temps go up, the A/D value goes down and it's nonlinear.. It's kinda noisy though so better than 1/4 degree C isn't likely.
In larger groups (cell voltages in group 2) the index byte continues 0x23, 0x24, 0x25 etc wrapping from 0x2f back to 0x20.
The cell voltages in Group 2 start with the 5th byte in the first line (just like the temps) with the first two cell voltages then subsequent lines contain another 3 and a half cell voltages on each.
0x7bb: 10 C6 61 02 0F D8 0F D4
0x7bb: 21 0F D0 0F D9 0F D0 0F
0x7bb: 22 CC 0F D3 0F D0 0F D0
If you ask for more than the above mentioned lines for each group (including the first line from the initial request), you won't get a response.
In early experiments (before figuring out how to ask for successive lines) I was toggling between asking for the first line of group 2 and the first line of group 3 at a 1250ms interval (about the max it would let me) and I could hear an odd clicking sound coming from the OBD2 port. Now that we're getting all the data, the clicking seems to have gone away as well as the 1.1 second max sample rate.
I've tried sampling group 3 (which has the Vmin and Vmax) at 4Hz (intermediate lines at 16ms) with no trouble. I tried intermediate line requests at 8ms and that seemed to work but there were a few glitches. Even at 16ms I'm not 100% certain I'm getting ALL the data ALL the time, but mostly it's working great. These 0x7xx messages are the lowest priority on the bus but it's still probably not a good idea to overload it..
We're still trying to decode additional data in group 3 as well as groups 1 and 5, so it'll be fun to see what kind of data the other folks out there are getting on their systems...
garygid wrote:Great work, and thanks a bunch for sharing.
What interface are you using to query the EV bus?
Have you experimented with making any Requests on
the CAR-CAN bus or the AV-CAN bus?
Now, I have a good reason to perfect some code for the
AVR-CAN (and Mbed) to send Requests, and actively
receive messages (the Replies).
To get it done, the CAN interface chip needs to be in
Transmit-Enabled mode both for sending the requests,
AND for actively Receiving messages. However, if one
wants to continue passively listening to other messages
(not being the active "recipient") one needs to be very careful
to only write the ACK bit to the "response" messages.
Again, thanks for sharing.
My first goal will be to add the 4 Battery Pack temperatures
to the GID-Meter, probably only done once a minute, or so.
TickTock wrote:Way to go, Greg! Finally, the holy grail! This will answer a lot of questions. I added your findings to the consolidated Leaf canbus doc (bottom of the EVCan tab).
TickTock wrote:Thanks again Greg! Just finished coding it up. Here's the money-shot.
garygid wrote:The 170/281 = 60.5% GIDs
I usually display %GIDs to make the comparison
with the "Real SOC" percentage easier.