Paste a CAN trace. Each line becomes a decoded message: the COB-ID split into function code and node ID, then the service behind it read out field by field.
It takes candump output, PCAN text, or plain identifier data lines. Several lines at once, in order, so a whole startup sequence decodes in one pass.
A PDO carries raw bytes. Nothing in the message says how they are split. Type the mapped bit lengths from the device EDS — 16,16,32 for two integers and a long — and the payload is cut up and read out. Leave it empty to see the bytes in every common word size.
The identifier is half the message
In CANopen the 11-bit identifier is not an address. It is two fields.
The top four bits are the function code — what kind of message this is. The bottom seven bits are the node ID, 1 to 127. That is why a node’s transmit PDO 1 is at 0x180 plus its node ID, and why node 3 answers SDO requests on 0x583.
| COB-ID | Function | Direction |
|---|---|---|
| 0x000 | NMT node control | master to every node |
| 0x080 | SYNC | master to every node |
| 0x080 + node | Emergency | node to everyone |
| 0x100 | TIME stamp | master to every node |
| 0x180 + node | TPDO 1 | node to master |
| 0x200 + node | RPDO 1 | master to node |
| 0x280 / 0x300 + node | TPDO 2 / RPDO 2 | |
| 0x380 / 0x400 + node | TPDO 3 / RPDO 3 | |
| 0x480 / 0x500 + node | TPDO 4 / RPDO 4 | |
| 0x580 + node | SDO, server to client | node to master |
| 0x600 + node | SDO, client to server | master to node |
| 0x700 + node | Heartbeat or node guarding | node to master |
| 0x7E4 / 0x7E5 | LSS | slave to master / master to slave |
This is the pre-defined connection set. A device can be told to use different identifiers, and many do once PDOs are remapped. Anything the decoder does not recognise is reported as a raw function code rather than forced into the table.
Work backwards when you are hunting a node: 0x184 is 0x180 plus 4, so it is TPDO 1 from node 4. The decoder does that arithmetic on every line.
Reading an SDO exchange
SDO is the request and response protocol for the object dictionary. Every message is eight octets: a command byte, a two-octet index, a sub-index, then four octets of data.
A read of the device type object looks like this:
601#40 00 10 00 00 00 00 00 master asks node 1 for object 1000h sub 0
581#43 00 10 00 92 01 02 00 node 1 answers 0x00020192
The command byte carries the work. 0x40 is initiate upload, which is CANopen’s word for read. 0x43 is the answer: initiate upload response, expedited, four octets of data. 0x2B is a write of two octets. 0x60 is a plain write acknowledgement.
Expedited means the value fits in the four data octets and the whole transfer is two messages. Anything longer than four octets becomes a segmented transfer, and you will see the segments walking through with a toggle bit. The decoder names the transfer type on every SDO message so you know which one you are watching.
The index gets named too. 1017h is producer heartbeat time, 1400h to 15FFh are the receive PDO communication parameters, 2000h to 5FFFh is the manufacturer area. That saves a trip to the object dictionary for the common ones.
Abort codes, and what they usually mean
When an SDO fails, the server answers with command 0x80 and a four-octet abort code. These are the ones you will actually meet.
| Code | Meaning | Usual cause |
|---|---|---|
| 0x06020000 | Object does not exist | Wrong index, or a feature the device does not have |
| 0x06090011 | Sub-index does not exist | Right object, wrong sub-index. Sub 0 is usually the count |
| 0x06010002 | Attempt to write a read only object | Trying to set a value the device only reports |
| 0x06010001 | Attempt to read a write only object | Rare, mostly command objects |
| 0x06070010 | Data type or length does not match | Writing four octets to a 16-bit object |
| 0x06090030 | Invalid value for parameter | In range for the data type, outside the device limits |
| 0x06090031 / 32 | Value too high / too low | The device is telling you its limits |
| 0x08000022 | Not possible in the present device state | Almost always: the node is operational and the object is only writable in pre-operational |
| 0x05040000 | SDO protocol timed out | The node stopped answering mid transfer |
| 0x08000020 | Cannot be transferred to the application | The stack accepted it, the application refused |
The state one catches people out constantly. Mapping parameters, PDO communication parameters and most configuration objects can only be written while the node is in pre-operational. Send NMT 0x80 first, write, then start the node again.
PDOs, and why the decoder needs your help
A PDO carries process data with no description at all. Eight octets, no index, no type, no length markers. The meaning lives in the mapping parameters inside the device, and the EDS file on your laptop.
So the tool gives you two ways to read one.
With no mapping entered, it shows the payload as every common word size at every offset: unsigned and signed 16-bit, 32-bit, float. One of those columns usually jumps out as the real value.
Better, type the mapped bit lengths into the mapping field. 16,16,8,8 splits eight octets into two integers and two bytes, and each mapped entry comes back with its bit offset, its unsigned and signed value, and its raw octets. Read the lengths off objects 1600h or 1A00h in the EDS, or off the device’s PDO mapping page, and the trace becomes readable.
CANopen packs mapped values little endian, starting at bit 0 of octet 0, which is what the decoder assumes. If your values come out scrambled but the byte count is right, the mapping order is wrong rather than the data.
Emergency messages
Eight octets: a two-octet error code, the error register from object 1001h, and five manufacturer octets.
The error code has a class in the high byte. 0x3000 is voltage, 0x4000 is temperature, 0x8100 is communication, 0x8110 is a CAN overrun with objects lost. A code the standard does not list is shown with its class, because the class alone often tells you where to look.
The error register is decoded bit by bit: generic, current, voltage, temperature, communication, device profile, manufacturer. Those bits should agree with the code. When a code is set and the register is zero, the device’s error handling is inconsistent, and the decoder says so.
Error code 0x0000 is not a fault. It means the node has cleared its errors, and it is the message you want to see after a fault goes away.
Startup, as it appears on the bus
A healthy node coming up looks like this:
000#81 00 NMT reset node, all nodes
701#00 node 1 boot-up, now pre-operational
000#01 00 NMT start, all nodes
701#05 node 1 heartbeat, operational
183#F4 01 .. node 3 starts sending TPDO 1
The heartbeat byte is the state: 0 boot-up, 127 pre-operational, 5 operational, 4 stopped. A node that keeps sending 0x00 is rebooting in a loop, usually power or watchdog. A node stuck at 127 never got its start command, or refused it. A node that goes quiet is the one your heartbeat consumer will report.
FAQ
What input formats does it take? 601#40 00 10 00 00 00 00 00, candump output including timestamps and interface names, PCAN text with the length between identifier and data, or a plain 701 05. Data can be spaced or run together.
Does it need an EDS file? No, and it does not read one. Common object dictionary indexes are named from the communication profile, and PDO contents are decoded from the mapping you type in.
Why does my PDO decode as nonsense? Either the mapping is wrong, or the PDO has been remapped to a different COB-ID than the pre-defined one and it is not the PDO you think it is. Read 1800h and 1A00h from the node over SDO and check both.
Can it decode CANopen FD? Not yet. Classic CAN frames carry at most eight octets, and the decoder treats anything longer as an error. CANopen FD uses a different service layer, so it needs its own handling rather than a length change.
What about J1939 or DeviceNet? Different higher-layer protocols on the same physical bus. J1939 uses 29-bit identifiers with a PGN structure, and nothing here applies. The decoder flags a 29-bit identifier rather than pretending.
Node guarding or heartbeat? Both use 0x700 plus the node ID. Heartbeat is one octet with the toggle bit always zero, sent by the node on a timer. Node guarding is a remote frame from the master answered by the node, with the toggle bit alternating on every reply. If the toggle bit is flipping, you are looking at node guarding.
Is the trace uploaded anywhere? No. Everything runs in the page. Paste a plant trace with no concerns.
