Controlling the gen2 Nissan Leaf inverter [c55-leaf-inverter-protocol-v3]

Author: Perttu "celeron55" Ahola

This took a whole bunch of effort to figure out. If you find this useful, you
can send me a tip via PayPal to <celeron55@gmail.com>. (paypal.me/celeron55)

This information is published for personal, non-commercial use. If you'd like to
use it for a commercial purpose, please contact me at <celeron55@iki.fi>.

2017-12-24: First version
2019-01-29: v2: Added general specifications, details about messages sent by the
                inverter and details about messages received by the inverter
2020-07-03: v3: Changed precharge requirement to 180V, as that looks to be more
                accurate than the 140V that I had figured out previously

General specifications of the Leaf system
Power: 80 kW (limited by inverter software)
Torque: 250 Nm (limited by inverter software)
Voltage: 96 series Li-ion (performs almost 100% with 72S)


The main power connector has two terminals. The one closer to the edge is the
positive terminal. They are not marked.

                  [-] [+]
                   |   |
  | O <- cooling port     |
  |                       |
  | motor gearbox end |

The inverter has a single actual connector, with the pinout:

  +-----------------------------------+  +------------+
  | 47   46   21 20 19 18 17  x 15 14 |  |       x  x |
  |            x  x 27  x  x  x  x  x |  | x  x  x  x |
  | 49   48    x  x  x  x  x  x  x  x |  | x  x  x  x |
  |           45 44  x 42  x  x  x  x |  |    x  x  x |
  +-----------------------------------+  +------------+

These are left as-is:
	17,18: Motor resolver S2-S4
	19,27: Motor resolver R1-R2
	20,21: Motor resolver S1-S3
	44,45: Motor temperature sensor

These are used for power and control:
	14: CAN-H
	15: CAN-L
	42: 12V switch-on signal
	46,48: 12V power
	47,49: Ground

Connect 47 and 49 to ground.

Use a CAN interface of some sort, for example MCP2515 + MCP2551, and connect it
to CAN-H and CAN-L.

Use proper CAN wiring and termination - the inverter makes a considerable amount
of electrical noise.

Connect 12V power through a switch or a software-controlled relay to 42, 46 and

The inverter takes about 1 Amp of 12V power, using it to run all the logic and
the IGBT drivers.

Operation: Getting the inverter to turn the motor

1. Switch on 12V power
2. Start sending CAN messages within 2s, preferably instantly
3. Finish precharging to at least 180V within 10s of switching the power on.
4. Continue sending CAN messages to control motor torque.
5. To shut down the inverter, make sure it has received the torque command 0 and
   then just switch off the power supply.

CAN protocol to inverter

500kbps with standard 11-bit CAN-IDs. You have to send three messages at certain
intervals, otherwise the inverter will switch off.

- 11A:
	- Interval: 10ms
	- Data: 4e 40 00 aa c0 00 XX YY
	- XX: Counter counting from 0 to 3, incrementing in each message
	- YY: Nissan CRC of the message data

- 1D4:
	- Interval: 10ms
	- Data: 6e 6e XX XX YY 44 01 ZZ
	- XXXX: Torque command, signed 16-bit value, MSB first
	- YY: 0x07 | (counter << 6)  // Counter counts from 0 to 3
	- ZZ: Nissan CRC of the message data

- 50B:
	- Interval: 100ms
	- Data: 00 00 06 c0 00 00 00

The torque command:

- A torque command of around 128 minimum will start the motor.

- At speeds under 480rpm, a torque command of 0 will coast the motor to stop.

- At speeds above 480rpm, torque=0 means constant speed if there is no load.
  Command negative torque to make the motor slow down when spinning freely. When
  installed in a vehicle, the vehicle will naturally slow the motor down.

- The scaling of the torque command regarding to motor current is 1 A per
  increment of 32. The maximum is 1120 = 560 A = about 250 Nm.

- The inverter limits power and torque roughly to the limits specified for the
  Leaf, which is something like 250 Nm and 80kW.

- In the Leaf, the lowest nibble is always sent as 00, making this effectively a
  12 bit value.

Nissan CRC:
	static void nissan_crc(uint8_t *data) {
		data[7] = 0;
		uint8_t crc = 0;
		for (int b=0; b<8; b++) {
			for (int i=7; i>=0; i--) {
				uint8_t bit = ((data[b] &(1 << i)) > 0) ? 1 : 0;
				if(crc >= 0x80) crc = (byte)(((crc << 1) + bit) ^ 0x85);
				else            crc = (byte)((crc << 1) + bit);
		data[7] = crc;
	NOTE: Not used in message 50B

What is message 50B?
- It makes the inverter think the Leaf's Vehicle Control Module is awake.

How to implement the counters?
- You can use the same counter in both messages.

CAN protocol from inverter

You need to have your CAN interface set to respond with CAN ACKs to these.

You don't need to respond to these otherwise, but they are quite useful.

- 1DA:
	- B0, B1:
		Voltage, 2 increments per volt
	- B4, B5:
		Speed, 2 increments per RPM
	- B2 low nibble, B3:
		Current, 1 increment per A
	- B6 & 0xb0:
		If non-zero, the inverter is in an error state and requires a restart.

- 55A:
	- B1: Motor temperature in fahrenheit
	- B2: Inverter temperature in fahrenheit

Basic EV stuff - don't just connect the inverter to your battery pack or power
supply right away, it's a short circuit until the capacitors have charged up.
Use a 100-1000 ohm 10W resistor or an incandescent light bulb or similar to charge it
up, and once it's charged up, only then close your power relay or contactor.

As long as you switch off all 12V power, all errors are disregarded on the next
power-up. In a pinch, you can read DTCs using the ISO 15765 protocol, but you
really don't need to.

Tested so far
- celeron55's setup: a 2016 inverter and motor, from the same Leaf, installed in
  a 1992 Toyota Previa. As of 2019-01-29, this setup has been driven more than
- With my permission this information is used by one commercial solution
  available since 2018

More information and comments: http://www.mynissanleaf.com/viewtopic.php?f=44&t=25027