Process Data Object (PDO)

The Process Data Object protocol is used to process real time data among various nodes. You can transfer up to 8 bytes (64 bits) of data per one PDO either from or to the device. One PDO can contain multiple object dictionary entries and the objects within one PDO are configurable using the mapping and parameter object dictionary entries.

There are two kinds of PDOs: transmit and receive PDOs (TPDO and RPDO). The former is for data coming from the device and the latter is for data going to the device; that is, with RPDO you can send data to the device and with TPDO you can read data from the device. In the pre-defined connection set there are identifiers for four (4) TPDOs and four (4) RPDOs available. With configuration 512 PDOs are possible.

PDOs can be sent synchronously or asynchronously. Synchronous PDOs are sent after the SYNC message whereas asynchronous messages are sent after internal or external trigger. For example, you can make a request to a device to transmit TPDO that contains data you need by sending an empty TPDO with the RTR flag (if the device is configured to accept TPDO requests).

With RPDOs you can, for example, start two devices simultaneously. You only need to map the same RPDO into two or more different devices and make sure those RPDOs are mapped with the same COB-ID.

Examples

A canopen.RemoteNode has canopen.RemoteNode.rpdo and canopen.RemoteNode.tpdo attributes that can be used to interact with the node using PDOs. These can be subindexed to specify which map to use (first map starts at 1, not 0):

# Read current PDO configuration
node.tpdo.read()
node.rpdo.read()

# Do some changes to TPDO4 and RPDO4
node.tpdo[4].clear()
node.tpdo[4].add_variable('Application Status', 'Status All')
node.tpdo[4].add_variable('Application Status', 'Actual Speed')
node.tpdo[4].trans_type = 254
node.tpdo[4].event_timer = 10
node.tpdo[4].enabled = True

node.rpdo[4].clear()
node.rpdo[4].add_variable('Application Commands', 'Command All')
node.rpdo[4].add_variable('Application Commands', 'Command Speed')
node.rpdo[4].enabled = True

# Save new configuration (node must be in pre-operational)
node.nmt.state = 'PRE-OPERATIONAL'
node.tpdo.save()
node.rpdo.save()

# Start RPDO4 with an interval of 100 ms
node.rpdo[4]['Application Commands.Command Speed'].phys = 1000
node.rpdo[4].start(0.1)
node.nmt.state = 'OPERATIONAL'

# Read 50 values of speed and save to a file
with open('output.txt', 'w') as f:
    for i in range(50):
        node.tpdo[4].wait_for_reception()
        speed = node.tpdo['Application Status.Actual Speed'].phys
        f.write(f'{speed}\n')

# Using a callback to asynchronously receive values
# Do not do any blocking operations here!
def print_speed(message):
    print(f'{message.name} received')
    for var in message:
        print(f'{var.name} = {var.raw}')

node.tpdo[4].add_callback(print_speed)
time.sleep(5)

# Stop transmission of RxPDO
node.rpdo[4].stop()

API

class canopen.pdo.PdoBase(node)[source]

Represents the base implementation for the PDO object.

Parameters:

node (object) – Parent object associated with this PDO instance

pdo[no]

Return the canopen.pdo.PdoMap for the specified map number. First map starts at 1.

iter(pdo)

Return an iterator of the available map numbers.

len(pdo)

Return the number of supported maps.

export(filename)[source]

Export current configuration to a database file.

Note

This API requires the db_export feature to be installed:

python3 -m pip install 'canopen[db_export]'
Parameters:

filename (str) – Filename to save to (e.g. DBC, DBF, ARXML, KCD etc)

Raises:

NotImplementedError – When the canopen[db_export] feature is not installed.

Returns:

The CanMatrix object created

Return type:

canmatrix.canmatrix.CanMatrix

read(from_od=False)[source]

Read PDO configuration from node using SDO.

save()[source]

Save PDO configuration to node using SDO.

stop()[source]

Stop all running tasks.

subscribe()[source]

Register the node’s PDOs for reception on the network.

This normally happens when the PDO configuration is read from or saved to the node. Use this method to avoid the SDO flood associated with read() or save(), if the local PDO setup is known to match what’s stored on the node.

class canopen.pdo.PdoMap(pdo_node, com_record, map_array)[source]

One message which can have up to 8 bytes of variables mapped.

map[name]

Return the canopen.pdo.PdoVariable for the variable specified as "Group.Variable" or "Variable" or as a position starting at 0.

iter(map)

Return an iterator of the canopen.pdo.PdoVariable entries in the map.

len(map)

Return the number of variables in the map.

add_callback(callback)[source]

Add a callback which will be called on receive.

Parameters:

callback (Callable[[PdoMap], None]) – The function to call which must take one argument of a PdoMap.

Return type:

None

add_variable(index, subindex=0, length=None)[source]

Add a variable from object dictionary as the next entry.

Parameters:
  • index (Union[str, int]) – Index of variable as name or number

  • subindex (Union[str, int]) – Sub-index of variable as name or number

  • length (Optional[int]) – Size of data in number of bits

Return type:

PdoVariable

Returns:

PdoVariable that was added

clear()[source]

Clear all variables from this map.

Return type:

None

cob_id: Optional[int]

COB-ID for this PDO

data

Current message data

enabled: bool

If this map is valid

event_timer: Optional[int]

Event timer (optional) (in ms)

inhibit_time: Optional[int]

Inhibit Time (optional) (in 100us)

property is_periodic: bool

Indicate whether PDO updates will be transferred regularly.

If some external mechanism is used to transmit the PDO regularly, its cycle time should be written to the period member for this property to work.

map: List[PdoVariable]

List of variables mapped to this PDO

property name: str

A descriptive name of the PDO.

Examples:
  • TxPDO1_node4

  • RxPDO4_node1

  • Unknown

period: Optional[float]

Period of receive message transmission in seconds. Set explicitly or using the start() method.

predefined_cob_id: Optional[int]

Default COB-ID if this PDO is part of the pre-defined connection set

read(from_od=False)[source]

Read PDO configuration for this map.

Parameters:

from_od – Read using SDO if False, read from object dictionary if True. When reading from object dictionary, if DCF populated a value, the DCF value will be used, otherwise the EDS default will be used instead.

Return type:

None

remote_request()[source]

Send a remote request for the transmit PDO. Silently ignore if not allowed.

Return type:

None

rtr_allowed: bool

Is the remote transmit request (RTR) allowed for this PDO

save()[source]

Save PDO configuration for this map using SDO.

Return type:

None

start(period=None)[source]

Start periodic transmission of message in a background thread.

Parameters:

period (Optional[float]) – Transmission period in seconds. Can be omitted if period has been set on the object before.

Raises:

ValueError – When neither the argument nor the period is given.

Return type:

None

stop()[source]

Stop transmission.

Return type:

None

subscribe()[source]

Register the PDO for reception on the network.

This normally happens when the PDO configuration is read from or saved to the node. Use this method to avoid the SDO flood associated with read() or save(), if the local PDO setup is known to match what’s stored on the node.

Return type:

None

sync_start_value: Optional[int]

Ignores SYNC objects up to this SYNC counter value (optional)

timestamp: Optional[float]

Timestamp of last received message

trans_type: Optional[int]

Transmission type (0-255)

transmit()[source]

Transmit the message once.

Return type:

None

update()[source]

Update periodic message with new data.

Return type:

None

wait_for_reception(timeout=10)[source]

Wait for the next transmit PDO.

Parameters:

timeout (float) – Max time to wait in seconds.

Return type:

float

Returns:

Timestamp of message received or None if timeout.

class canopen.pdo.PdoVariable(od)[source]

One object dictionary variable mapped to a PDO.

od

The canopen.objectdictionary.ODVariable associated with this object.

property bits: Bits

Access bits using integers, slices, or bit descriptions.

property data: bytes

Byte representation of the object as bytes.

property desc: str

Converts to and from a description of the value as a string.

get_data()[source]

Reads the PDO variable from the last received message.

Return type:

bytes

Returns:

PdoVariable value as bytes.

index

Holds a local, overridable copy of the Object Index

name

Description of this variable from Object Dictionary, overridable

offset

Location of variable in the message in bits

pdo_parent: Optional[PdoMap]

PDO object that is associated with this ODVariable Object

property phys: int | bool | float | str | bytes

Physical value scaled with some factor (defaults to 1).

On object dictionaries that support specifying a factor, this can be either a float or an int. Non integers will be passed as is.

property raw: int | bool | float | str | bytes

Raw representation of the object.

This table lists the translations between object dictionary data types and Python native data types.

Data type

Python type

BOOLEAN

bool

UNSIGNEDxx

int

INTEGERxx

int

REALxx

float

VISIBLE_STRING

str

UNICODE_STRING

str

OCTET_STRING

bytes

DOMAIN

bytes

Data types that this library does not handle yet must be read and written as bytes.

read(fmt='raw')

Alternative way of reading using a function instead of attributes.

May be useful for asynchronous reading.

Parameters:

fmt (str) –

How to return the value
  • ’raw’

  • ’phys’

  • ’desc’

Return type:

Union[int, bool, float, str, bytes]

Returns:

The value of the variable.

set_data(data)[source]

Set for the given variable the PDO data.

Parameters:

data (bytes) – Value for the PDO variable in the PDO message.

subindex

Holds a local, overridable copy of the Object Subindex

write(value, fmt='raw')

Alternative way of writing using a function instead of attributes.

May be useful for asynchronous writing.

Parameters:

fmt (str) –

How to write the value
  • ’raw’

  • ’phys’

  • ’desc’

Return type:

None