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
- All payloads use big-endian byte order
Step 1: Compose the CAN Frame
| CAN ID | DLC |
|---|---|
| 0x0C7 | 3 to 8 |
| Byte 0 | Byte 1 | Byte 2 | Byte 3 (optional) | Bytes 4 - 7 (optional) |
|---|---|---|---|---|
| Receiver address 0x0 | Perform task 0x4 | Task ID | Argument count (argcnt) | Argument data |
SID is 24, sender address is 7 -> (24 << 3) + 7 = 192 + 7 = 199 (DEC) = 0xC7
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 ID | Description |
|---|---|
| 1 | Driver reinit |
| 2 | Execute identlin |
| 3 | Execute identrun |
| 128 | Save parameters |
| 129 | Load parameters from flash |
| 255 | Request task result |
| Other | Unsupported command (can be used as heartbeat) |
Argument Encoding
The meaning of bytes 4 - 7 depends on argcnt:
argcnt | Layout of bytes 4 - 7 |
|---|---|
| 0 (or omitted) | No arguments — task uses defaults |
| 1 | 1 × uint32 (big-endian) in bytes 4 - 7 |
| 2 | 2 × uint16 (big-endian): u16[0] in bytes 4 - 5, u16[1] in bytes 6 - 7 |
| 3 | 3 × uint8 in bytes 4 - 6 |
| 4 | 4 × uint8 in bytes 4 - 7 |
Per-task Arguments
Task 1 — Driver reinit
argcnt | Argument | Meaning |
|---|---|---|
| 0 | — | Reinit and start with current preset |
| 1 | i32 | New /driver/prest value — selected before driver start -1 to deinitialize |
Task 2 — identlin
argcnt | Bytes 4 - 7 | Meaning |
|---|---|---|
| 0 | — | Defaults: flags = NLIN | PID, cycles = 10000, currthr = iref / 2 |
| 1 | u32 | cycles = u32 (raw) |
| 2 | u16, u16 | cycles = u16[0] (raw); currthr = iref × u16[1] / 10000 (0.01 % of iref) |
| 3 or 4 | u8 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
argcnt | Bytes 4 - 7 | Meaning |
|---|---|---|
| 0 | — | Defaults: acc = 200, cycles = 80000, currthr = iref / 4 |
| 1 | u32 | cycles = u32 (raw) |
| 2 | u16, u16 | cycles = u16[0] (raw); currthr = iref × u16[1] / 10000 (0.01 % of iref) |
| 3 or 4 | u8 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 ID | DLC |
|---|---|
| 0x0C0 | 3 |
| Byte 0 | Byte 1 | Byte 2 |
|---|---|---|
| Receiver address 0x7 | Perform task - response 0x44 | Task ID |
SID is 24, sender address is 0 -> (24 << 3) + 0 = 192 (DEC) = 0xC0
- 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 ID | DLC |
|---|---|
| 0x0C7 | 8 |
| Byte 0 | Byte 1 | Byte 2 | Byte 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 ID | DLC |
|---|---|
| 0x0C0 | 3 |
| Byte 0 | Byte 1 | Byte 2 |
|---|---|---|
| Receiver address 0x7 | Perform task - response 0x44 | Running task ID |
Task Finished
Response containing the latest task result:
| CAN ID | DLC |
|---|---|
| 0x0C0 | 7 |
| Byte 0 | Byte 1 | Byte 2 | Bytes 3 - 6 |
|---|---|---|---|
| Receiver address 0x7 | Perform task - response 0x44 | Running task ID | Task 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 ID | DLC | Bytes |
|---|---|---|
| 0x0C7 | 3 | 00 04 03 |
| Byte 0 | Byte 1 | Byte 2 |
|---|---|---|
| Receiver address 0x0 | Perform task 0x4 | Task ID 0x3 |
The controller acknowledges that the task has started:
| CAN ID | DLC | Bytes |
|---|---|---|
| 0x0C0 | 3 | 07 44 03 |
2. Poll for the result
While the task is running, request the result:
| CAN ID | DLC | Bytes |
|---|---|---|
| 0x0C7 | 3 | 00 04 FF |
While the task is still running, the response stays at DLC = 3 with Task ID = 3:
| CAN ID | DLC | Bytes |
|---|---|---|
| 0x0C0 | 3 | 07 44 03 |
Once the task has finished, the response is DLC = 7 with the return value:
| CAN ID | DLC | Bytes |
|---|---|---|
| 0x0C0 | 7 | 07 44 03 00 00 00 00 |
Bytes 3 - 6 = 00 00 00 00 → result = 0 (success).