Reverse engineering the LEAF resolver offset writing

Nissan Leaf/e-NV200 drive stack topics
User avatar
Dala
Posts: 27
Joined: Tue Jul 06, 2021 9:12 pm

Reverse engineering the LEAF resolver offset writing

Post by Dala »

Hi,
I have managed to store the CAN-logs that the official Consult3+ tool uses to read and write resolver offsets to LEAF inverters. You know, this procedure:
Image

I've attached the .log file from my experiments, can be played back with CANrunner. Use the "WRITE-ID-86-00-14-00-55.log" and replace the numbers according to your motor.

I made a video on my 80->110kW project here:


Here's a peak on the decoding I did for the READ command;
Image

Hope this is helpful to someone! I am working with the creator of Leafspy Pro so that we can add the functionality there too!
Attachments
WRITE-ID-86-00-14-00-55.log
(843 Bytes) Downloaded 242 times
ResolverReadWrite.log
(5.47 MiB) Downloaded 225 times
earthman
Posts: 8
Joined: Tue Aug 03, 2021 7:07 pm
Location: Россия

Re: Reverse engineering the LEAF resolver offset writing

Post by earthman »

this file that you posted is a record from the CAN bus? I'm sorry I just don't understand English

I'm trying to do the same thing, only with the help of CAN Hacker. I don't have a data stream, but I have a motor and an inverter from zeo
User avatar
drprox
Posts: 28
Joined: Sat Mar 07, 2020 12:50 pm
Location: England

Re: Reverse engineering the LEAF resolver offset writing

Post by drprox »

I'm not having much luck with this so far.
It appears in your log that byte 02 is the address of the number it wants, and then it is also in byte 02 of the reply.

I get the first number (86), but then not the others, see below. Unfortunately, I don't know what the number should be because I don't have the motor it came from. Any ideas?

Code: Select all

Chn Identifier Flg   DLC  D0...1...2...3...4...5...6..D7       Time     Dir
 0    000007D2         8  02  3E  00  FF  FF  FF  FF  FF     663.798860 T
 0    00000784         8  02  10  C0  00  00  00  00  00     663.900670 T
 0    0000078C         8  02  50  C0  FF  FF  FF  FF  FF     663.911850 R
 0    00000784         8  02  21  01  00  00  00  00  00     663.999480 T
 0    0000078C         8  03  61  01  86  FF  FF  FF  FF     664.011860 R
 0    00000784         8  02  21  03  00  00  00  00  00     664.099580 T
 0    0000078C         8  03  7F  21  12  FF  FF  FF  FF     664.111870 R
 0    00000784         8  02  21  04  00  00  00  00  00     664.198570 T
 0    0000078C         8  03  7F  21  12  FF  FF  FF  FF     664.211790 R
User avatar
Dala
Posts: 27
Joined: Tue Jul 06, 2021 9:12 pm

Re: Reverse engineering the LEAF resolver offset writing

Post by Dala »

Also note that the car needs to be in ACC mode, not ON when doing the resolve writing! Known working "WRITE-ID-86-00-14-00-55.log" file uploaded to main post!
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: Reverse engineering the LEAF resolver offset writing

Post by bexander »

Was able to change resolver settings on my Leaf inverter with this information using a Atmega328p (Arduino pro mini) and a MCP2515/TJA1050 module.
Thanks for sharing, Dala!
schildere
Posts: 5
Joined: Sun Nov 28, 2021 11:11 am

Re: Reverse engineering the LEAF resolver offset writing

Post by schildere »

@bexander That's awesome. Is it possible to share your Arduino code?
collin80
Posts: 110
Joined: Sun Aug 30, 2020 3:28 pm
Location: United States, Michigan
Been thanked: 4 times
Contact:

Re: Reverse engineering the LEAF resolver offset writing

Post by collin80 »

For the curious - the Leaf speaks UDS when it is doing things like this. UDS, in the case of CAN, is transmitted using ISO-TP which is a protocol layer on top of raw CAN. ISO-TP uses the first byte for a variety of uses but one of them is to specify how many bytes follow. So, when you see 0x02 as the first byte that means that two bytes thereafter are important, the rest are filler. ISO-TP allow for multi-frame messages as well but it's not looking like they use any such long messages here. The next byte is the UDS command type. 0x10 is "diagnostic mode control" and lets the far side specify which sort of diagnostic mode it wants the ECU in. 0xC0 would be the requested diagnostic mode for instance. This is a non-standard mode. Usually it's mode 1, 2, or 3. Replies from the ECU come in with a command type + 0x40 to show success. So, you can see the ECU reply 0x50 which means "diagnostic mode success!" followed by the mode that was requested.

0x21 is read by local ID" so the read is first for 1 then 3 then 4. Read of ID1 returns only one byte while reads to 3 and 4 return two bytes each. You'll note that the replies here are 0x61 which is 0x40 higher, just like it should be.

In the write log they use 0x3B which normally decodes as GMLAN write DID. Apparently Nissan uses it to write values too.

At any rate, the whole thing is UDS and so large portions of it are more or less standard, just with Nissan quirks thrown in. I find it interesting that you can write to the resolver offset without any security mode stuff. Apparently you just pass a non-standard diagnostic mode and you're golden!
User avatar
EV_Builder
Posts: 1199
Joined: Tue Apr 28, 2020 3:50 pm
Location: The Netherlands
Has thanked: 16 times
Been thanked: 33 times
Contact:

Re: Reverse engineering the LEAF resolver offset writing

Post by EV_Builder »

Do we need to login? Which level? And which password?
UDS I'm talking about. Normally it's part of the sequence.
Converting an Porsche Panamera
see http://www.wdrautomatisering.nl for bespoke BMS modules.
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: Reverse engineering the LEAF resolver offset writing

Post by bexander »

schildere wrote: Sun Nov 28, 2021 11:31 am @bexander That's awesome. Is it possible to share your Arduino code?
Sorry, didn't see your request until now.
Here is the code I used.
ResolverSetting.zip
(1.63 KiB) Downloaded 229 times
schildere
Posts: 5
Joined: Sun Nov 28, 2021 11:11 am

Re: Reverse engineering the LEAF resolver offset writing

Post by schildere »

Thx!!!
bexander wrote: Thu Dec 09, 2021 6:50 pm
schildere wrote: Sun Nov 28, 2021 11:31 am @bexander That's awesome. Is it possible to share your Arduino code?
Sorry, didn't see your request until now.
Here is the code I used.
ResolverSetting.zip
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

bexander wrote: Tue Nov 16, 2021 6:13 pm Was able to change resolver settings on my Leaf inverter with this information using a Atmega328p (Arduino pro mini) and a MCP2515/TJA1050 module.
Thanks for sharing, Dala!
Hi bexander,
Im trying to reset my resolver # using the Arduino pro mini and mcp2515/tja1050. to transmit your code do you only need one Arduino set-up? Can you share a schematic and explain how you connected with the inverter with CAN HI and LO and what file you used with the inverter numbers. Thanks for your help. Thanks a lot. Steve
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: Reverse engineering the LEAF resolver offset writing

Post by bexander »

sglassmann wrote: Fri Feb 25, 2022 4:12 pm Hi bexander,
Im trying to reset my resolver # using the Arduino pro mini and mcp2515/tja1050. to transmit your code do you only need one Arduino set-up? Can you share a schematic and explain how you connected with the inverter with CAN HI and LO and what file you used with the inverter numbers. Thanks for your help. Thanks a lot. Steve
Yes, one Arduino setup is what is needed and termination resistors in both ends of the CAN-bus.
I connected as per this: http://productions.8dromeda.net/c55-lea ... tocol.html

My motor data:
7C 00 88
00 5C

In the function writeResolverDataCAN() in my code these lines corespond to the resolver motor parameters.
counter == 2, msg[3] = 0x7C
counter == 3, msg[3] = 0x00
counter == 3, msg[4] = 0x88
counter == 4, msg[3] = 0x00
counter == 4, msg[4] = 0x5C

Code: Select all

void writeResolverDataCAN()
{
	if(write)
	{
		return;
	}
	
	Serial.println("w");
	static uint8_t counter = 0;
	static uint32_t startTime = millis(); // Set start time
	uint16_t txId;
	uint8_t msg[8];
	
	if(counter == 0)
	{
		txId = 0x784;
		msg[0] = 0x02;
		msg[1] = 0x3E;
		msg[2] = 0x01;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
  
  if(counter == 1)
	{
		txId = 0x745;
		msg[0] = 0x02;
		msg[1] = 0x10;
		msg[2] = 0xAA;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 2)
	{
		txId = 0x784;
		msg[0] = 0x03;
		msg[1] = 0x3B;
		msg[2] = 0x01;
		msg[3] = 0x7C;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 3)
	{
		txId = 0x784;
		msg[0] = 0x04;
		msg[1] = 0x3B;
		msg[2] = 0x03;
		msg[3] = 0x00;
		msg[4] = 0x88;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 4)
	{
		txId = 0x784;
		msg[0] = 0x04;
		msg[1] = 0x3B;
		msg[2] = 0x04;
		msg[3] = 0x00;
		msg[4] = 0x5C;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
  
  if(counter == 5)
	{
		txId = 0x784;
		msg[0] = 0x02;
		msg[1] = 0x21;
		msg[2] = 0x01;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
  
  if(counter == 6)
	{
		txId = 0x784;
		msg[0] = 0x02;
		msg[1] = 0x21;
		msg[2] = 0x03;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 7)
	{
		txId = 0x784;
		msg[0] = 0x02;
		msg[1] = 0x21;
		msg[2] = 0x04;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 8)
	{
		txId = 0x784;
		msg[0] = 0x02;
		msg[1] = 0x10;
		msg[2] = 0x81;
		msg[3] = 0x00;
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0x00;
	}
	
	if(counter == 9)
	{
		txId = 0x7D2;
		msg[0] = 0x02;
		msg[1] = 0x3E;
		msg[2] = 0x00;
		msg[3] = 0xFF;
		msg[4] = 0xFF;
		msg[5] = 0xFF;
		msg[6] = 0xFF;
		msg[7] = 0xFF;
	}
  
  CAN.sendMsgBuf(txId, 0, 8, msg);
  
  Serial.print(millis() - startTime);
	Serial.print(" ");
  Serial.print(txId, HEX);
  Serial.print(" ");
  for(int i=0; i<8; i++)
  {
    Serial.print(msg[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
  
  if(counter > 9)
  {
		write = true;
		counter = 0;
	}
	else
	{
		counter++;
	}
}
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

Hey Thanks for the helpful reply about the resolver code.

Im having a hard time finding the mcp_can.h file in the library. any assistance or a copy of that file would be great. thanks a bunch
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

Hi bexander,
Im trying to reset my resolver # using the Arduino pro mini and mcp2515/tja1050. to transmit your code do you only need one Arduino set-up? Can you share a schematic and explain how you connected with the inverter with CAN HI and LO and what file you used with the inverter numbers. Thanks for your help. Thanks a lot. Steve
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: Reverse engineering the LEAF resolver offset writing

Post by bexander »

sglassmann wrote: Thu Mar 03, 2022 1:32 am HI bexander. THanks for your help so far. I am having a hard time finding the mcp_can file for can communication in the library.
any ideas where to find file or can you send me a copy? thanks a lot and have a great day, steve
This is the one I use:
MCP_CAN_lib-master.zip
(35.92 KiB) Downloaded 134 times
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: Reverse engineering the LEAF resolver offset writing

Post by johu »

Hi and welcome sglassmann! Please do not blindly quote big chunks, but pick the exact sentences you want to reply to. The thread becomes hard to read otherwise.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

johu wrote: Thu Mar 03, 2022 10:09 am Hi and welcome sglassmann! Please do not blindly quote big chunks, but pick the exact sentences you want to reply to. The thread becomes hard to read otherwise.
Im sorry, I had a hard time replying to just the member I was communicating with. If you need to delete the big chunk response to clean up the thread, please do. sorry
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

bexander wrote: Thu Mar 03, 2022 5:08 am
sglassmann wrote: Thu Mar 03, 2022 1:32 am HI bexander. THanks for your help so far. I am having a hard time finding the mcp_can file for can communication in the library.
any ideas where to find file or can you send me a copy? thanks a lot and have a great day, steve
This is the one I use:
MCP_CAN_lib-master.zip
Awesome Thanks
skylitdriven
Posts: 2
Joined: Fri Mar 04, 2022 1:49 am

Re: Reverse engineering the LEAF resolver offset writing

Post by skylitdriven »

bexander wrote: Sat Feb 26, 2022 6:18 am Yes, one Arduino setup is what is needed and termination resistors in both ends of the CAN-bus.
I connected as per this: http://productions.8dromeda.net/c55-lea ... tocol.html
Hey bexander, I'm looking into doing the inverter swap and it seems like I will need to write the resolver code for it to work, but I am completely clueless when it comes to CAN coding and have never touched an Arduino before. I was hoping you'd be able to lend a hand with the process of how it'd work.

I understand that I will have to modify the code values based on my motor data. Would the Arduino setup be connected to the inverter (with termination resistors) outside of the vehicle before it is installed, power up the inverter, then power up the Arduino and it will run the code automatically?

Thanks in advance.
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: Reverse engineering the LEAF resolver offset writing

Post by bexander »

Yes, probably a good idea to do the programming with the inverter on the bench. Can be done in the vehicle as well but safer to do it on the bench.
Power up the inverter with 12V. The arduino is usually powered via the USB or serial programmer used. If you want to catch all messages comming from the Inverter you need to power up the arduino first and then the Inverter.

There should be a termination resistor (120ohm) in each end of the CAN-bus. Usually the CAN-module or shield contains the possibility to set this via jumper or similar. In the inverter end you will need to be more creative. However it is not absolutely necessary so you might get away with only one resistor for programming but I strongly recommend having the terminations resistors correct when using the inverter in the car.

When running the code, you will need to open the "Serial Monitor" in the Arduino IDE and set it to a baud rate of 115200. When everything is powered up you should see CAN-messages from the inverter beeing printed in the "Serial Monitor".
If you want to save the data stored in the Inverter, type "r" and hit enter in "Serial Monitor". That should result in some extra messages containing the stored data but this have to be filtered out manually.
To program, modify the code as per: viewtopic.php?p=37224#p37224
Now, when everything is powered, type "w" and hit enter in "Serial Monitor", to write the data. You should be able to see the extra CAN-messages as a confirmation and you can also do a "r", enter, to confirm the new values are stored in the Inverter.
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

bexander wrote: Sat Mar 05, 2022 6:13 am Yes, probably a good idea to do the programming with the inverter on the bench. Can be done in the vehicle as well but safer to do it on the bench.
THis worked great. Cost about $25 and with the help of my brother, a programmer, and your file and directions, my motor is running alot smoother.

Thanks so much and you take care. Steve
sglassmann
Posts: 7
Joined: Fri Feb 11, 2022 1:25 am

Re: Reverse engineering the LEAF resolver offset writing

Post by sglassmann »

skylitdriven wrote: Fri Mar 04, 2022 1:53 am
bexander wrote: Sat Feb 26, 2022 6:18 am Yes, one Arduino setup is what is needed and termination resistors in both ends of the CAN-bus.
I connected as per this: http://productions.8dromeda.net/c55-lea ... tocol.html
Hey bexander, I'm looking into doing the inverter swap and it seems like I will need to write the resolver code for it to work, but I am completely clueless when it comes to CAN coding and have never touched an Arduino before. I was hoping you'd be able to lend a hand with the process of how it'd work.

I understand that I will have to modify the code values based on my motor data. Would the Arduino setup be connected to the inverter (with termination resistors) outside of the vehicle before it is installed, power up the inverter, then power up the Arduino and it will run the code automatically?

Thanks in advance.
let me know if you need any help while its fresh in my mind.
skylitdriven
Posts: 2
Joined: Fri Mar 04, 2022 1:49 am

Re: Reverse engineering the LEAF resolver offset writing

Post by skylitdriven »

bexander wrote: Sat Mar 05, 2022 6:13 am Yes, probably a good idea to do the programming with the inverter on the bench. Can be done in the vehicle as well but safer to do it on the bench.
Power up the inverter with 12V. The arduino is usually powered via the USB or serial programmer used. If you want to catch all messages comming from the Inverter you need to power up the arduino first and then the Inverter.
Thank you so much for the advice!
sglassmann wrote: Mon Mar 07, 2022 2:56 am let me know if you need any help while its fresh in my mind.
At the moment I'm still waiting to actually source an inverter, hopefully from within the country, so just getting an idea of the programming process that would actually be required so I can be familiar with it before diving in.
User avatar
Cees67
Posts: 5
Joined: Wed Oct 07, 2020 11:13 pm
Location: NZ

Re: Reverse engineering the LEAF resolver offset writing

Post by Cees67 »

Well done Dala.
I'm not sure if this is the right topic: I'm looking for a way to translate the offset code (in hex I presume) to degrees (angle). I'm using a non-Leaf inverter with a Leaf motor and I need to enter the offset as an angle.
Has anyone cracked that one?
Cheers,
Cees.
User avatar
Dala
Posts: 27
Joined: Tue Jul 06, 2021 9:12 pm

Re: Reverse engineering the LEAF resolver offset writing

Post by Dala »

No clue unfortunately Cees67...

On some positive news, Leafspy integration is soon done, will make a video on it when it is available!
Post Reply