CANopen - a device network on top of CAN
CANopen (standardised as CiA 301) turns a raw CAN bus into a plug-and-play network of up to 127 nodes: motor drives, I/O blocks, sensors, controllers. It defines what the 11-bit CAN identifiers mean, an object dictionary in every device, and a handful of services (NMT, SYNC, EMCY, PDO, SDO, heartbeat). The sloppyCAN CANopen tab decodes all of these and can actively read/write a node.
The COB-ID
CANopen just partitions the 11-bit CAN ID. The top 4 bits are a function code (what kind of message), the low 7 bits are the node-ID (1-127, or 0 for broadcast). Together they're called the COB-ID (Communication Object Identifier).
node = id & 0x7F · fc = (id >> 7) & 0xF
This fixed assignment is the predefined connection set:
| COB-ID | Message | Direction |
|---|---|---|
| 0x000 | NMT node control | master → all (broadcast) |
| 0x080 | SYNC | broadcast |
| 0x080 + node | EMCY (emergency) | node → |
| 0x100 | TIME stamp | broadcast |
| 0x180 / 0x280 / 0x380 / 0x480 + node | TPDO 1–4 (transmit process data) | node → |
| 0x200 / 0x300 / 0x400 / 0x500 + node | RPDO 1–4 (receive process data) | → node |
| 0x580 + node | SDO response (server → client) | node → |
| 0x600 + node | SDO request (client → server) | → node |
| 0x700 + node | Heartbeat / NMT error control | node → |
Classification is pure arithmetic, no payload inspection needed. The one
wrinkle: 0x080 is SYNC when the node bits are zero, and an EMCY from
node otherwise.
NMT - the network state machine
Every node is in one of a few states. The NMT master flips them with a 2-byte broadcast on
0x000: byte0 = command, byte1 = target node
(0 = all nodes).
| Cmd | Effect |
|---|---|
| 0x01 | Start → Operational (PDOs flow) |
| 0x02 | Stop → Stopped (only NMT + heartbeat) |
| 0x80 | Enter Pre-Operational (SDO yes, PDO no) |
| 0x81 | Reset Node |
| 0x82 | Reset Communication |
Each node announces its current state in its heartbeat (0x700+node,
1 byte): 0x00 Boot-up, 0x04 Stopped, 0x05 Operational,
0x7F Pre-Operational. The tab's node map colours the chip from this byte.
EMCY - emergency messages
When a device faults it broadcasts an 8-byte EMCY on 0x080+node:
- Error code (bytes 0-1, little-endian): the high byte is a class:
0x10xxgeneric,0x20xxcurrent,0x30xxvoltage,0x40xxtemperature,0x81xxcommunication. Some full codes are named:0x8110CAN overrun,0x8130heartbeat error,0x8140recovered from bus-off. - Error register (byte 2, object
0x1001): a bitfield, bit 0 generic, 1 current, 2 voltage, 3 temperature, 4 communication, 5 device-profile, 7 manufacturer.
SDO - the read/write channel
The Service Data Object protocol reads and writes any entry in a node's object dictionary. Every SDO frame is 8 bytes: a command specifier, the 16-bit index (LE), an 8-bit sub-index, then data.
Expedited transfers carry ≤ 4 data bytes in that single response frame. The
command byte encodes the size: 0x43 = 4 bytes, 0x47 = 3,
0x4B = 2, 0x4F = 1. A write mirrors this:
0x2n request (0x23/0x27/0x2B/0x2F) → 0x60 confirm.
Segmented transfers
Longer values (a device name, say) don't fit in one frame. The server answers the read
request with an initiate (0x41) carrying the total size, then the
client pulls 7 bytes at a time with segment requests (0x60/0x70,
a toggling bit), until a segment arrives with the last flag set. The tab
reassembles the pieces and shows the value as text + hex.
Aborts
If a request can't be served, the server replies with 0x80 and a 4-byte
abort code (LE). Common ones: 0x06020000 object doesn't exist,
0x06010002 attempt to write a read-only object, 0x06090011 sub-index
doesn't exist, 0x06070010 type/length mismatch, 0x08000000 general.
Active SDO is not read-only. A download (write) changes the node's object dictionary, and an NMT Stop halts its PDOs. The tab gates every transmit on a live bus, the listen-only checkbox being off, and a one-time session confirm; writes add their own confirm. Point it only at a bench network you control. One SDO transaction is in flight at a time per node, segmented transfers must not interleave.
PDO - process data
TPDO/RPDO carry the actual application data, motor speed, I/O states, with
no protocol header at all. Which bytes mean what is defined by the device's
PDO mapping objects (0x1600/0x1A00...) in its object
dictionary. Without that mapping (which lives in the device's EDS file, not on the wire) a
sniffer can only show which PDO of which node plus the raw
bytes. That's what the tab does; user-supplied mappings are future work.
A session, end to end
Try it with no hardware: turn on Demo mode and
open the CANopen tab. Two simulated nodes emit heartbeats and a TPDO; the SDO client can read
0x1000 (device type, expedited) and 0x1008 (device name, segmented),
and NMT buttons flip a node's state live in the node map.