CANopen protocol

CANopen is the internationally standardized (EN 50325-4) CAN-based higher-layer protocol for embedded control system, as developed and maintained by CiA members.. The set of CANopen specifications comprise the application layer and communication profile, as well as application, device, and interface profiles. CANopen provides very flexible configuration capabilities, and for this reason CANopen networks are used in a very broad range of application fields, such as machine control, medical devices, off-road and rail vehicles, maritime electronics, building automation, power generation, etc.

The CANopen protocol defines basically two aspects of the communication protocol: how the communication should be formatted (CANopen frame), and what objects are defined in common. Those objects may be used to configure or arbitrate the communication, or simply to exchange application data. Communication objects are available to:

  • Exchange process and service data.
  • Process or system time synchronization.
  • Error state supervision.
  • Control and monitoring of node states.

The following interactive figure depicts this:


For further information about the CANopen protocol, please refer to this link.

CANopen frame

CANopen protocol is based in CAN frames and uses one CAN frame for each CANopen message. There are two important parts of the frame that the user needs to modify: the arbitration field and the data field. The rest of the fields of the frame are normally automatically configured by the CAN hardware.

The CANopen protocol can work over other data link layer protocols. However, as it was designed based on the CAN specification, this document explain the CANopen message format over CAN.

For further information about CAN specification, please refer to the CAN section.

Arbitration field

In CANopen messages the identifier part of the arbitration field is known as Communication Object Identifier (COB-ID). It is divided into a 4-bit part function code and a 7-bit node-ID as depicted:

COB-ID description

Parallel to CAN, every node on a CANopen network must have a unique node-ID. The range of valid values comprises from 1 to 127. Zero is not allowed.

Similarly, the priority is determined by the COB-ID and RTR bits. As expected, the RTR bit on the arbitration field is used to request information from a remote node. In particular, it is used to implement the node guarding and TPDO request features, explained in the following chapters. With the exception of these two circumstances, the RTR bit is always set to zero.

The function code determines the communication object, which should be one of the allowed in CANopen. The final COB-ID of the object depends on the ID of which node receives or transmits the message, which allows to further establish priorities between nodes for the same function code.

In a master/slave communication, the messages could be divided into two groups, as shown in the following tables.

  • CANopen broadcast messages:

Communication Object

Function code (binary)

COB-IDs (hexadecimal)

NMT service






  • CANopen peer-to-peer messages:

Communication Object

Function code (binary)

COB-ID (hexadecimal)

Range of valid COB-IDs (hexadecimal)



0x80 + Node ID

0x81 - 0x0FF

PDO1 (transmit)


0x180 + Node ID

 0x181 - 0x1FF

PDO1 (receive)


0x200 + Node ID

0x201 - 0x27F

PDO2 (transmit)


0x280 + Node ID

0x281 - 0x2FF

PDO2 (receive)


0x300 + Node ID

0x301 - 0x37F)

PDO3 (transmit)


0x380 + Node ID

0x381 - 0x3FF

PDO3 (receive)


0x400 + Node ID

0x401 - 0x47F

PDO4 (transmit)


0x480 + Node ID

0x481 - 0x4FF

PDO4 (receive)


0x500 + Node ID

0x501 - 0x57F

SDO (transmit)


0x580 + Node ID

0x581 - 0x5FF

SDO (receive)


0x600 + Node ID

0x601 - 0x67F

NMT error control


0x700 + Node ID

0x701 - 0x77F

Data field

The content of the data field depends on the CANopen message type. Detailed information about the CANopen message data is found under the appropriate object type in Communication objects.

Data is stored and transmitted in little endian format, which mean that least significant byte of the data is placed in the first position. For example, the number 0x15542612 would be represented as: