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.PdoMapfor 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_exportfeature 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
- 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.PdoVariablefor the variable specified as"Group.Variable"or"Variable"or as a position starting at 0.
- iter(map)
Return an iterator of the
canopen.pdo.PdoVariableentries in the map.
- len(map)
Return the number of variables in the map.
- add_variable(index, subindex=0, length=None)[source]¶
Add a variable from object dictionary as the next entry.
- data¶
Current message data
- 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
periodmember for this property to work.
-
map:
List[PdoVariable]¶ List of variables mapped to this PDO
-
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:
- remote_request()[source]¶
Send a remote request for the transmit PDO. Silently ignore if not allowed.
- Return type:
- 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:
- class canopen.pdo.PdoVariable(od)[source]¶
One object dictionary variable mapped to a PDO.
- od¶
The
canopen.objectdictionary.ODVariableassociated with this object.
- property bits: Bits¶
Access bits using integers, slices, or bit descriptions.
- 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
- 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
floator anint. 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
UNSIGNEDxx
INTEGERxx
REALxx
VISIBLE_STRING
UNICODE_STRING
OCTET_STRING
DOMAIN
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.
- 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