AI-generated text still pending human review/editing.
ISO-TP transport ↗

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).

10987
function code
6543210
node-ID (1–127)

node = id & 0x7F  ·  fc = (id >> 7) & 0xF

This fixed assignment is the predefined connection set:

COB-IDMessageDirection
0x000NMT node controlmaster → all (broadcast)
0x080SYNCbroadcast
0x080 + nodeEMCY (emergency)node →
0x100TIME stampbroadcast
0x180 / 0x280 / 0x380 / 0x480 + nodeTPDO 1–4 (transmit process data)node →
0x200 / 0x300 / 0x400 / 0x500 + nodeRPDO 1–4 (receive process data)→ node
0x580 + nodeSDO response (server → client)node →
0x600 + nodeSDO request (client → server)→ node
0x700 + nodeHeartbeat / NMT error controlnode →

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).

NMT - master → all (0x000)
01Start
05node 5
CmdEffect
0x01Start → Operational (PDOs flow)
0x02Stop → Stopped (only NMT + heartbeat)
0x80Enter Pre-Operational (SDO yes, PDO no)
0x81Reset Node
0x82Reset 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:

EMCY - node → (0x080 + node)
30 81error code (LE)
11error register
00 00 00 00 00manufacturer-specific

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.

Read request - client → server (0x600 + node)
40upload req
00 10index 0x1000
00sub
00 00 00 00-
Read response (expedited) - server → client (0x580 + node)
434 data bytes
00 10index
00sub
91 01 02 00value (LE)

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

1 node boots → heartbeat Boot-up → 2 Pre-Op (configure via SDO) → 3 NMT Start → 4 Operational - PDOs + SYNC flow → 5 EMCY on fault

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.