CANopenDemo
CANopenNode demo, tutorial and testing
|
A PDO (Process Data Object) is providing real-time data transfer of object entries of a CANopen device's object dictionary. The transfer of PDO is performed with no protocol overhead. The PDO correspond to objects in the object dictionary and provide the interface to the application objects. Data type and mapping of application objects into a PDO is determined by a corresponding PDO mapping structure within the object dictionary.
This chapter describes PDO configuration and some experimenting with the demoDevice. Example runs with CANopen devices as specified in tutorial/README.md.
TPDO with specific 11-bit CAN identifier is transmitted by one device and recieved by zero or more devices as RPDO. PDO communication parameters(COB-ID, transmission type, etc.) are in the Object Dictionary at index 0x1400+ and 0x1800+. PDO mapping parameters (size and contents of the PDO) are in the Object Dictionary at index 0x1600+ and 0x1A00+.
Each PDO can be configured with any valid 11-bit CAN identifier. Lower numbers have higher priorities on CAN bus. As a general rule, each CAN message is identified with own CAN-ID, which must be unique and produced by single source. The same is with PDO objects: Any TPDO produced on the CANopen network must have unique CAN-ID and there can be zero to many RPDOs (from different devices) configured to match the CAN-ID of the TPDO of interest.
CANopen standard provides pre-defined connection sets for four RPDOs and four TPDOs on each device with specific 7-bit Node-ID. These are default values and are usable in configuration, where CANopen network contains a master device, which directly communicates with many slaves. In de-centralized systems, where devices operate without a master, it makes sense to configure CAN-IDs of the RPDOs to the non-default values. For default CAN identifiers see Default CANopen identifiers.
PDOs can be configured with Object Dictionary Editor or can be configured dynamically inside device running in CANopenNetwork, could be in NMT operational state.
Configure PDO by writing to the OD variables in the following procedure:
Set the default Node-ID to 4 for demoDevice:
cocomm "set node 4"
RPDO communication parameters, COB-ID used by RPDO and RPDO mapping parameters, number of mapped application objects:
cocomm "r 0x1400 1 x32" "r 0x1401 1 x32" "r 0x1402 1 x32" "r 0x1403 1 x32" cocomm "r 0x1600 0 u8" "r 0x1601 0 u8" "r 0x1602 0 u8" "r 0x1603 0 u8" [1] 0x00000204 [2] 0x00000304 [3] 0x80000404 [4] 0x80000504 [1] 2 [2] 4 [3] 0 [4] 0
RPDO 1 is enabled, accepts CAN messages with CAN-ID = 0x204 and has mapped two objects. RPDO 2 is enabled, accepts CAN messages with CAN-ID = 0x304 and has mapped four objects. RPDO 3 and RPDO 4 are disabled.
Read communication and mapping parameter for RPDO 1:
pc=0x1400; pm=0x1600 cocomm "[1] r $pc 1 x32" "[2] r $pc 2 u8" "[5] r $pc 5 u16" cocomm "[0] r $pm 0 u8"; for i in {1..8}; do cocomm "[$i] r $pm $i x32"; done [1] 0x00000204 [2] 255 [5] 0 [0] 2 [1] 0x62000108 [2] 0x62000208 [3] 0x62000308 [4] 0x62000408 [5] 0x62000508 [6] 0x62000608 [7] 0x62000708 [8] 0x62000808
Mapping parameter shows, that OD variable at index 0x6200, subindex 0x01 and OD variable at index 0x6200, subindex 0x02 are mapped to that RPDO. Both have length of 8 bits, that means RPDO must have two data bytes. See demo/demoDevice.md for documentation about OD variables. In our case 0x6200 are digital outputs on the device. Transmission type of RPDO 1 is 255, which means, every received PDO is processed. Event timer is 0, so timeout monitoring is not used.
To conclude: if basicDevice is in NMT operational state and it receives a CAN message with 11-bit CAN identifier equal to 0x204 and data length of two bytes, then data from that message will be written into OD variables 0x6200,1 and 0x6200,2. Furthermore, if CANopen device has digital outputs in its hardware, those OD variables will most likely be written to them. Received CAN message is usually named PDO in CANopen network and is transmitted from known device as TPDO.
Read communication and mapping parameter for RPDO 2:
pc=0x1401; pm=0x1601 cocomm "[1] r $pc 1 x32" "[2] r $pc 2 u8" "[5] r $pc 5 u16" cocomm "[0] r $pm 0 u8"; for i in {1..8}; do cocomm "[$i] r $pm $i x32"; done [1] 0x00000304 [2] 255 [5] 0 [0] 4 [1] 0x64110110 [2] 0x64110210 [3] 0x64110310 [4] 0x64110410 [5] 0x00000000 [6] 0x00000000 [7] 0x00000000 [8] 0x00000000
RPDO 2 accepts 0x304 CAN-ID, 8 bytes long and maps to four 16-bit analog outputs.
TPDO communication parameters, COB-ID used by TPDO and TPDO mapping parameters, number of mapped application objects:
cocomm "r 0x1800 1 x32" "r 0x1801 1 x32" "r 0x1802 1 x32" "r 0x1803 1 x32" cocomm "r 0x1A00 0 u8" "r 0x1A01 0 u8" "r 0x1A02 0 u8" "r 0x1A03 0 u8" [1] 0x40000184 [2] 0x40000284 [3] 0xC0000384 [4] 0xC0000484 [1] 2 [2] 4 [3] 0 [4] 0
Read communication and mapping parameter for TPDO 1:
pc=0x1800; pm=0x1A00 cocomm "[1] r $pc 1 x32" "[2] r $pc 2 u8" "[3] r $pc 3 u16" "[5] r $pc 5 u16" "[6] r $pc 6 u8" cocomm "[0] r $pm 0 u8"; for i in {1..8}; do cocomm "[$i] r $pm $i x32"; done [1] 0x40000184 [2] 255 [3] 0 [5] 0 [6] 0 [0] 2 [1] 0x60000108 [2] 0x60000208 [3] 0x60000308 [4] 0x60000408 [5] 0x60000508 [6] 0x60000608 [7] 0x60000708 [8] 0x60000808
TPDO 1 has mapped 2*8 digital inputs. It has CAN-ID 0x184 and 2 data bytes, when sent. Transmission type is 255, so it sends on event timer or on application specified event like change-of-state of digital inputs. TPDO 1 is always transmitted on communication reset. Set event timer to send some more:
cocomm "w 0x1800 5 u16 500" # observe candump cocomm "w 0x1800 5 u16 0"
Read communication and mapping parameter for TPDO 2:
pc=0x1801; pm=0x1A01 cocomm "[1] r $pc 1 x32" "[2] r $pc 2 u8" "[3] r $pc 3 u16" "[5] r $pc 5 u16" "[6] r $pc 6 u8" cocomm "[0] r $pm 0 u8"; for i in {1..8}; do cocomm "[$i] r $pm $i x32"; done [1] 0x40000284 [2] 255 [3] 0 [5] 0 [6] 0 [0] 4 [1] 0x64010110 [2] 0x64010210 [3] 0x64010310 [4] 0x64010410 [5] 0x00000000 [6] 0x00000000 [7] 0x00000000 [8] 0x00000000
TPDO 2 has mapped 4 16-bit analog inputs. It has CAN-ID 0x284 and 8 data bytes, when sent.
One 32-bit OD variable will be mapped to TPDO 3: 0x2110,1. See demoDevice, section "OD variable mapped to TPDO".
Disable TPDO, if not already disabled, configure mapping and enable TPDO with default CAN-ID:
cocomm "w 0x1802 1 u32 0x80000000" cocomm "w 0x1A02 0 u8 0" cocomm "w 0x1A02 1 u32 0x21100120" cocomm "w 0x1A02 0 u8 1" cocomm "w 0x1802 1 u32 0x00000384"
candump shows one TPDO:
can0 384 [4] 00 00 00 00
Use event timer, watch candump:
cocomm "w 0x1802 5 u16 500"
Write something to 0x2110,1 via SDO:
cocomm "w 0x2110 1 u32 0xAB00CDEF" #candump: can0 384 [4] EF CD 00 AB
Disable event timer and test change-of-state mechanism, used by application in demoDevice. SDO write will change the value of the variable mapped to TPDO and application will trigger TPDO when change-of-state is detected. Observe candump between the commands (ignore SDO messages):
cocomm "w 0x1802 5 u16 0" cocomm "w 0x2110 1 u32 0x12345678" cocomm "w 0x2110 1 u32 0x12345678" # same data, no TPDO cocomm "w 0x2110 1 u32 0xAABBCCDD"
Use any free RPDO and configure it to accept PDO with CAN-ID = 0x384 and data length of 4 bytes. Provide OD variables for data from demoDevice and map RPDO to them.
CANopenNode enables mapping length smaller than variable length. For example, only two bytes of variable of type uint32_t can be mapped, where its little end will be used.
To adjust the length of TPDO or RPDO, dummy entries can be used for mapping, for example:
Data Type | dummy mapping |
---|---|
int8_t | 0x00020008 |
int16_t | 0x00030016 |
int32_t | 0x00040032 |
int64_t | 0x00150064 |
CANopenNode granularity is 8 bits, so smallest mappable length is one byte.
More deterministic transmission of PDOs may be configured with usage of CANopen SYNC messages. See CANopen documentation.