## Anybody mess with the CAN Commanded Torque Message ID 0x1D4?

weber
Posts: 6
Joined: Mon Aug 04, 2014 7:33 pm
Delivery Date: 04 Sep 2013

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

In case anyone still cares about the 8-bit CRC in the Leaf's ID 0x1D4 CAN packets, my colleague Coulomb and I have reverse-engineered it. We used the excellent method described in New Zealander Greg Ewing's awesome paper, "Reverse-Engineering a CRC Algorithm".
http://www.cosc.canterbury.ac.nz/greg.e ... ering.html

The polynomial is 0x85 using left shifts. It takes the bytes in little-endian order [Edit: in the order transmitted] and the initial value and final XOR are both zero. The only place that I can find that this polynomial has been used before is in a Nintendo game controller.

We'd be very interested to know if anyone has any evidence that this actually contains a torque command from VCM to TMI. It looks to us like telemetry going the other way. We'd also be interested if anyone has any theories about what ID packet does contain the torque command.
Last edited by weber on Sat Oct 25, 2014 3:11 pm, edited 1 time in total.

JeremyW
Posts: 1555
Joined: Sun Nov 13, 2011 12:53 am
Delivery Date: 23 Jun 2012
Leaf Number: 19136
Location: San Gabriel, CA

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

weber wrote:In case anyone still cares about the 8-bit CRC in the Leaf's ID 0x1D4 CAN packets, my colleague Coulomb and I have reverse-engineered it. We used the excellent method described in New Zealander Greg Ewing's awesome paper, "Reverse-Engineering a CRC Algorithm".
http://www.cosc.canterbury.ac.nz/greg.e ... ering.html

The polynomial is 0x85 using left shifts. It takes the bytes in little-endian order and the initial value and final XOR are both zero. The only place that I can find that this polynomial has been used before is in a Nintendo game controller.

We'd be very interested to know if anyone has any evidence that this actually contains a torque command from VCM to TMI. It looks to us like telemetry going the other way. We'd also be interested if anyone has any theories about what ID packet does contain the torque command.
Thank you so much for this. Seriously. I'm going to use it to "tune" my leaf. Oh yes. Former 2012 SL leasee 6/23/12 - 9/23/15
Former Fit EV leasee.
Now driving Spark EV and Model 3.

Flashman
Posts: 68
Joined: Wed Oct 23, 2013 7:26 am
Delivery Date: 30 Sep 2013
Location: Central Florida

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

I don't know about the rest of you guys but....
Please let this discovery and or research lead to DIY performance changes. Tinted 2013 Silver SV 6kwChg, Hella Horns, All-SuperBrightLED's, Switchable VSP Relay Cutout, LeafDD
Self installed BOSCH Power Max Level 2 Charging Station.

JeremyW
Posts: 1555
Joined: Sun Nov 13, 2011 12:53 am
Delivery Date: 23 Jun 2012
Leaf Number: 19136
Location: San Gabriel, CA

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

Flashman wrote:I don't know about the rest of you guys but....
Please let this discovery and or research lead to DIY performance changes. I'm on it! http://www.mynissanleaf.com/viewtopic.php?f=44&t=18120
Former 2012 SL leasee 6/23/12 - 9/23/15
Former Fit EV leasee.
Now driving Spark EV and Model 3.

camasleaf
Posts: 662
Joined: Sun Sep 26, 2010 5:20 am
Delivery Date: 17 Jun 2011
Location: Camas, WA

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

If we have enough information to make an inverter go to regen mode, then one could buy a used Leaf motor and inverter drive it with an ICE engine to quick charge at up to 30kW. I have seen motor/inverter for around \$1500, with small ICE engine at \$500 it would possible to have emegency/portable quick charge for under \$3000. A connection to the HV lines will be needed on that Leaf, plus a way to trick the Leaf into believing it is OK to regen.
2011 SLe 06/17/11 Over 92000 miles 59%SOH
2018 Honda Clarity PHEV
2014 Model S P85 87000 miles 250 miles range
5.7kW DC Solar System

TickTock
Posts: 1701
Joined: Sat Jun 04, 2011 10:30 pm
Delivery Date: 31 May 2011
Leaf Number: 3626
Location: Queen Creek, Arizona
Contact: Website

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

JeremyW wrote:
weber wrote:In case anyone still cares about the 8-bit CRC in the Leaf's ID 0x1D4 CAN packets, my colleague Coulomb and I have reverse-engineered it. We used the excellent method described in New Zealander Greg Ewing's awesome paper, "Reverse-Engineering a CRC Algorithm".
http://www.cosc.canterbury.ac.nz/greg.e ... ering.html

The polynomial is 0x85 using left shifts. It takes the bytes in little-endian order and the initial value and final XOR are both zero. The only place that I can find that this polynomial has been used before is in a Nintendo game controller.

We'd be very interested to know if anyone has any evidence that this actually contains a torque command from VCM to TMI. It looks to us like telemetry going the other way. We'd also be interested if anyone has any theories about what ID packet does contain the torque command.
Thank you so much for this. Seriously. I'm going to use it to "tune" my leaf. Oh yes. Sweet! Nice job!

ernieskaggs
Posts: 1
Joined: Tue Oct 07, 2014 6:54 am
Delivery Date: 07 Oct 2014

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

I can't get the the checksum to match using polynomial 0x85. I programmed the rutine to check it myself so there could be a problem but it really seems like it is working correctly.

When you say little endian do you mean that the data should be check in this order D6 D5 D4 D3 D2 D1 D0:
For example, when I use the data posted here where:
D0:F7 D1:07 D2:00 D3:00 D4:07 D5:44 D6:30 CRC:70

My algorethem gives me a CRC of 0x6B

Let me post my code in case there is some sort of glaring problem:

X=0;

matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;
matrix[X+0]=((TEST.m_sWhichBit.m_aucData & 0x80) >> 7);
matrix[X+1]=((TEST.m_sWhichBit.m_aucData & 0x40) >> 6);
matrix[X+2]=((TEST.m_sWhichBit.m_aucData & 0x20) >> 5);
matrix[X+3]=((TEST.m_sWhichBit.m_aucData & 0x10) >> 4);
matrix[X+4]=((TEST.m_sWhichBit.m_aucData & 0x08) >> 3);
matrix[X+5]=((TEST.m_sWhichBit.m_aucData & 0x04) >> 2);
matrix[X+6]=((TEST.m_sWhichBit.m_aucData & 0x02) >> 1);
matrix[X+7]=((TEST.m_sWhichBit.m_aucData & 0x01) >> 0);
X=X+8;

matrix[X]=0;
matrix[X+1]=0;
matrix[X+2]=0;
matrix[X+3]=0;
matrix[X+4]=0;
matrix[X+5]=0;
matrix[X+6]=0;
matrix[X+7]=0;

Workingvalue= ((matrix<<7) | (matrix<<6) | (matrix<<5) | (matrix<<4) | (matrix<<3) | (matrix<<2) | (matrix<<1) | (matrix));
X=8;
while (X<=63){

while (((Workingvalue & 0x80)==0) && X<=63){
Workingvalue=(Workingvalue<<1)|matrix[X];
X++;}
Workingvalue=Workingvalue ^ (0x85);
Trace("%x", Workingvalue);
}

Trace("%x", Workingvalue);

weber
Posts: 6
Joined: Mon Aug 04, 2014 7:33 pm
Delivery Date: 04 Sep 2013

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

ernieskaggs wrote:When you say little endian do you mean that the data should be check in this order D6 D5 D4 D3 D2 D1 D0:
Sorry, Ernie. I may have used the wrong terminology, but I actually meant to process them in the order they are transmitted D0 D1 D2 D3 D4 D5 D6, where D7 is the CRC.

JeremyW
Posts: 1555
Joined: Sun Nov 13, 2011 12:53 am
Delivery Date: 23 Jun 2012
Leaf Number: 19136
Location: San Gabriel, CA

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

Weber and all, you might wanna take a look at EV can messages 1DB, 1DC, and 55B to see if 0x85 works for those too. The last byte looks like a CRC (values all over the place).

CRC stuff isn't clicking for me yet. I'll have to read that paper for like the 3rd or 4th time. Former 2012 SL leasee 6/23/12 - 9/23/15
Former Fit EV leasee.
Now driving Spark EV and Model 3.

coulomb
Posts: 105
Joined: Thu Oct 09, 2014 5:08 pm
Delivery Date: 07 Mar 2015
Leaf Number: 200445
Location: Brisbane, Australia

### Re: Anybody mess with the CAN Commanded Torque Message ID 0x

ernieskaggs,

I don't fully understand your code, so please ignore me if I've got this wrong. But it looks to me that you're using the 0x85 as an XOR value, but it's a generator polynomial (I hope I got that term right, see http://en.wikipedia.org/wiki/Cyclic_redundancy_check" onclick="window.open(this.href);return false; ). The value 0x85 determines which taps are present in a standard CRC algorithm; in this case, since 0x85 has three ones, there are three taps.

So it seems to me that your code needs rewriting from scratch. See if you can find some example code on the web, as we did. We tested algorithms in a spreadsheet, and I think I tried some C code, but Weber seemed to be getting more progress with the spreadsheet.
2012 Leaf with new battery May 2019. New to me June 2019.