Network and nodes¶
The canopen.Network represents a collection of nodes connected to the
same CAN bus. This handles the sending and receiving of messages and dispatches
messages to the nodes it knows about.
Each node is represented using the canopen.RemoteNode or
canopen.LocalNode class. It is usually associated with an
object dictionary and each service has its own attribute owned by this node.
Examples¶
Create one network per CAN bus:
import canopen
network = canopen.Network()
By default this library uses python-can for the actual communication. See its documentation for specifics on how to configure your specific interface.
Call the connect() method to start the communication, optionally providing
arguments passed to a the can.BusABC constructor:
network.connect(channel='can0', interface='socketcan')
# network.connect(interface='kvaser', channel=0, bitrate=250000)
# network.connect(interface='pcan', channel='PCAN_USBBUS1', bitrate=250000)
# network.connect(interface='ixxat', channel=0, bitrate=250000)
# network.connect(interface='nican', channel='CAN0', bitrate=250000)
Add nodes to the network using the add_node() method:
node = network.add_node(6, '/path/to/object_dictionary.eds')
local_node = canopen.LocalNode(1, '/path/to/master_dictionary.eds')
network.add_node(local_node)
Nodes can also be accessed using the Network object as a Python dictionary:
for node_id in network:
print(network[node_id])
To automatically detect which nodes are present on the network, there is the
scanner attribute available for this purpose:
# This will attempt to read an SDO from nodes 1 - 127
network.scanner.search()
# We may need to wait a short while here to allow all nodes to respond
time.sleep(0.05)
for node_id in network.scanner.nodes:
print(f"Found node {node_id}!")
Finally, make sure to disconnect after you are done:
network.disconnect()
API¶
- class canopen.Network(bus=None)[source]¶
Representation of one CAN bus containing one or more nodes.
- Parameters:
bus (can.BusABC) – A python-can bus instance to re-use.
- nmt¶
The broadcast
canopen.nmt.NmtMasterwhich will affect all nodes.
- sync¶
The
canopen.sync.SyncProducerfor this network.
- time¶
The
canopen.timestamp.TimeProducerfor this network.
- network[node_id]
Return the
canopen.RemoteNodeorcanopen.LocalNodefor the specified node ID.
- iter(network)
Return an iterator over the handled node IDs.
- node_id in network
Return
Trueif the node ID exists is handled by this network.
- del network[node_id]
Delete the node ID from the network.
- values()¶
Return a list of
canopen.RemoteNodeorcanopen.LocalNodehandled by this network.
- add_node(node, object_dictionary=None, upload_eds=False)[source]¶
Add a remote node to the network.
- Parameters:
node (
Union[int,RemoteNode,LocalNode]) – Can be either an integer representing the node ID, acanopen.RemoteNodeorcanopen.LocalNodeobject.object_dictionary (
Union[str,ObjectDictionary,None]) – Can be either a string for specifying the path to an Object Dictionary file or acanopen.ObjectDictionaryobject.upload_eds (
bool) – SetTrueif EDS file should be uploaded from 0x1021.
- Return type:
- Returns:
The Node object that was added.
- bus¶
A python-can
can.BusABCinstance which is set aftercanopen.Network.connect()is called
- check()[source]¶
Check that no fatal error has occurred in the receiving thread.
If an exception caused the thread to terminate, that exception will be raised.
- Return type:
- connect(*args, **kwargs)[source]¶
Connect to CAN bus using python-can.
Arguments are passed directly to
can.BusABC. Typically these may include:- Parameters:
channel – Backend specific channel for the CAN interface.
interface (str) – Name of the interface. See python-can manual for full list of supported interfaces.
bitrate (int) – Bitrate in bit/s.
- Raises:
can.CanError – When connection fails.
- Return type:
- create_node(node, object_dictionary=None)[source]¶
Create a local node in the network.
- Parameters:
node (
int) – An integer representing the node ID.object_dictionary (
Union[str,ObjectDictionary,None]) – Can be either a string for specifying the path to an Object Dictionary file or acanopen.ObjectDictionaryobject.
- Return type:
- Returns:
The Node object that was added.
- disconnect()[source]¶
Disconnect from the CAN bus.
Must be overridden in a subclass if a custom interface is used.
- Return type:
- listeners¶
List of
can.Listenerobjects. Includes at least MessageListener.
- notify(can_id, data, timestamp)[source]¶
Feed incoming message to this library.
If a custom interface is used, this function must be called for each message read from the CAN bus.
- scanner¶
A
NodeScannerfor detecting nodes
- send_message(can_id, data, remote=False)[source]¶
Send a raw CAN message to the network.
This method may be overridden in a subclass if you need to integrate this library with a custom backend. It is safe to call this from multiple threads.
- send_periodic(can_id, data, period, remote=False)[source]¶
Start sending a message periodically.
- Parameters:
- Return type:
- Returns:
An task object with a
.stop()method to stop the transmission
- class canopen.RemoteNode(node_id, object_dictionary, load_od=False)[source]¶
A CANopen remote node.
- Parameters:
node_id (
int) – Node ID (set to None or 0 if specified by object dictionary)object_dictionary (
Union[ObjectDictionary,str,TextIO]) – Object dictionary as either a path to a file, anObjectDictionaryor a file like object.load_od (
bool) – Enable the Object Dictionary to be sent through SDO’s to the remote node at startup.
- id¶
The node id (1 - 127). Changing this after initializing the object will not have any effect.
- sdo¶
The
canopen.sdo.SdoClientassociated with the node.
- tpdo¶
The
canopen.pdo.PdoBasefor TPDO associated with the node.
- rpdo¶
The
canopen.pdo.PdoBasefor RPDO associated with the node.
- nmt¶
The
canopen.nmt.NmtMasterassociated with the node.
- emcy¶
The
canopen.emcy.EmcyConsumerassociated with the node.
- object_dictionary¶
The
canopen.ObjectDictionaryassociated with the node
- network¶
The
canopen.Networkowning the node
- add_sdo(rx_cobid, tx_cobid)[source]¶
Add an additional SDO channel.
The SDO client will be added to
sdo_channels.- Parameters:
- Returns:
The SDO client created
- Return type:
- curtis_hack¶
Enable WORKAROUND for reversed PDO mapping entries
- load_configuration()[source]¶
Load the configuration of the node from the Object Dictionary.
Iterate through all objects in the Object Dictionary and download the values to the remote node via SDO. To avoid PDO mapping conflicts, PDO-related objects are handled through the methods
canopen.pdo.PdoBase.read()andcanopen.pdo.PdoBase.save().- Return type:
- class canopen.LocalNode(node_id, object_dictionary)[source]¶
- id¶
The node id (1 - 127). Changing this after initializing the object will not have any effect.
- sdo¶
The
canopen.sdo.SdoServerassociated with the node.
- object_dictionary¶
The
canopen.ObjectDictionaryassociated with the node
- network¶
The
canopen.Networkowning the node
- class canopen.network.MessageListener(network)[source]¶
Bases:
ListenerListens for messages on CAN bus and feeds them to a Network instance.
- Parameters:
network (
Network) – The network to notify on new messages.
- class canopen.network.NodeScanner(network=None)[source]¶
Observes which nodes are present on the bus.
- Listens for the following messages:
Heartbeat (0x700)
SDO response (0x580)
TxPDO (0x180, 0x280, 0x380, 0x480)
EMCY (0x80)
- Parameters:
network (canopen.Network) – The network to use when doing active searching.
- class canopen.network.PeriodicMessageTask(can_id, data, period, bus, remote=False)[source]¶
Task object to transmit a message periodically using python-can’s CyclicSendTask
- Parameters:
can_id (
int) – CAN-ID of the messagedata (
bytes) – Data to be transmitted (anything that can be converted to bytes)period (
float) – Seconds between each messagebus (can.BusABC) – python-can bus to use for transmission