Skip to main content
Firmware Stable

How to Perform Motor Identification Using CAN Bus

Prerequisites:

  • An ESCx controller that is powered ON
  • CAN bus is functioning properly
  • Controller address is set to 0
note
  • All payloads use big-endian byte order

Step 1: Compose the CAN Frame

CAN IDDLC
0x0C73 to 8
Byte 0Byte 1Byte 2Byte 3 (optional)Bytes 4 - 7 (optional)
Receiver address
0x0
Perform task
0x4
Task IDArgument count (argcnt)Argument data
How to Calculate CAN ID

SID is 24, sender address is 7 -> (24 << 3) + 7 = 192 + 7 = 199 (DEC) = 0xC7

New in driver 5.2

Task arguments (argcnt and the argument bytes) are supported starting from driver firmware 5.2. Earlier driver versions ignore them and the task always runs with its default parameters. Send DLC = 3 (no argcnt) to stay backward-compatible.

Task ID List

Task IDDescription
1Driver reinit
2Execute identlin
3Execute identrun
128Save parameters
129Load parameters from flash
255Request task result
OtherUnsupported command (can be used as heartbeat)

Argument Encoding

The meaning of bytes 4 - 7 depends on argcnt:

argcntLayout of bytes 4 - 7
0 (or omitted)No arguments — task uses defaults
11 × uint32 (big-endian) in bytes 4 - 7
22 × uint16 (big-endian): u16[0] in bytes 4 - 5, u16[1] in bytes 6 - 7
33 × uint8 in bytes 4 - 6
44 × uint8 in bytes 4 - 7

Per-task Arguments

Task 1 — Driver reinit

argcntArgumentMeaning
0Reinit and start with current preset
1i32New /driver/prest value — selected before driver start
-1 to deinitialize

Task 2 — identlin

argcntBytes 4 - 7Meaning
0Defaults: flags = NLIN | PID, cycles = 10000, currthr = iref / 2
1u32cycles = u32 (raw)
2u16, u16cycles = u16[0] (raw); currthr = iref × u16[1] / 10000 (0.01 % of iref)
3 or 4u8 flags, u8 cyc, u8 cur [, u8 flags_hi]flags = arg0 ; cycles = arg1 × 20000 ; currthr = iref × arg2 / 100 ; argcnt = 4: flags |= arg3 << 8

Task 3 — identrun

argcntBytes 4 - 7Meaning
0Defaults: acc = 200, cycles = 80000, currthr = iref / 4
1u32cycles = u32 (raw)
2u16, u16cycles = u16[0] (raw); currthr = iref × u16[1] / 10000 (0.01 % of iref)
3 or 4u8 acc, u8 cyc, u8 cur [, u8 unused]acc = arg0 × 100 ; cycles = arg1 × 20000 ; currthr = iref × arg2 / 100

Tasks 128 / 129 — Save / Load parameters

No arguments. Send argcnt = 0 or omit byte 3 entirely.

Step 2: Receive Response

CAN IDDLC
0x0C03
Byte 0Byte 1Byte 2
Receiver address
0x7
Perform task - response
0x44
Task ID
How to Calculate CAN ID

SID is 24, sender address is 0 -> (24 << 3) + 0 = 192 (DEC) = 0xC0

note
  • DLC = 7 with Byte 3 - Byte 7 containing value -1 indicates unsupported task
  • If a task is unfinished, the response includes the ID of the unfinished task

Step 3: Request Task Result

CAN IDDLC
0x0C78
Byte 0Byte 1Byte 2Byte 3 - Byte 7
Receiver address
0x0
Perform task
0x4
Request result
0xFF
0x0

Task is Still Running

Response when a task is in progress:

CAN IDDLC
0x0C03
Byte 0Byte 1Byte 2
Receiver address
0x7
Perform task - response
0x44
Running task ID

Task Finished

Response containing the latest task result:

CAN IDDLC
0x0C07
Byte 0Byte 1Byte 2Bytes 3 - 6
Receiver address
0x7
Perform task - response
0x44
Running task IDTask result (uint32, big-endian)

A result of 0 typically indicates success, while any other value indicates failure.

Example: Run identrun Without Arguments

This is the minimum sequence to start an identrun (Task ID = 3) and read its result, using the controller defaults (acc = 200, cycles = 80000, currthr = iref / 4).

1. Start the task

CAN IDDLCBytes
0x0C7300 04 03
Byte 0Byte 1Byte 2
Receiver address
0x0
Perform task
0x4
Task ID
0x3

The controller acknowledges that the task has started:

CAN IDDLCBytes
0x0C0307 44 03

2. Poll for the result

While the task is running, request the result:

CAN IDDLCBytes
0x0C7300 04 FF

While the task is still running, the response stays at DLC = 3 with Task ID = 3:

CAN IDDLCBytes
0x0C0307 44 03

Once the task has finished, the response is DLC = 7 with the return value:

CAN IDDLCBytes
0x0C0707 44 03 00 00 00 00

Bytes 3 - 6 = 00 00 00 00 → result = 0 (success).