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', bustype='socketcan')
# network.connect(bustype='kvaser', channel=0, bitrate=250000)
# network.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
# network.connect(bustype='ixxat', channel=0, bitrate=250000)
# network.connect(bustype='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("Found node %d!" % 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.NmtMaster which will affect all nodes.

sync

The canopen.sync.SyncProducer for this network.

time

The canopen.timestamp.TimeProducer for this network.

network[node_id]

Return the canopen.RemoteNode or canopen.LocalNode for the specified node ID.

iter(network)

Return an iterator over the handled node IDs.

node_id in network

Return True if 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.RemoteNode or canopen.LocalNode handled by this network.

add_node(node, object_dictionary=None, upload_eds=False)[source]

Add a remote node to the network.

Parameters:
Return type:

RemoteNode

Returns:

The Node object that was added.

bus

A python-can can.BusABC instance which is set after canopen.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:

None

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.

  • bustype (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:

Network

create_node(node, object_dictionary=None)[source]

Create a local node in the network.

Parameters:
Return type:

LocalNode

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:

None

listeners

List of can.Listener objects. 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.

Parameters:
  • can_id (int) – CAN-ID of the message

  • data (bytearray) – Data part of the message (0 - 8 bytes)

  • timestamp (float) – Timestamp of the message, preferably as a Unix timestamp

Return type:

None

scanner

A NodeScanner for 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.

Parameters:
  • can_id (int) – CAN-ID of the message

  • data (bytes) – Data to be transmitted (anything that can be converted to bytes)

  • remote (bool) – Set to True to send remote frame

Raises:

can.CanError – When the message fails to be transmitted

Return type:

None

send_periodic(can_id, data, period, remote=False)[source]

Start sending a message periodically.

Parameters:
  • can_id (int) – CAN-ID of the message

  • data (bytes) – Data to be transmitted (anything that can be converted to bytes)

  • period (float) – Seconds between each message

  • remote (bool) – indicates if the message frame is a remote request to the slave node

Return type:

PeriodicMessageTask

Returns:

An task object with a .stop() method to stop the transmission

subscribe(can_id, callback)[source]

Listen for messages with a specific CAN ID.

Parameters:
Return type:

None

unsubscribe(can_id, callback=None)[source]

Stop listening for message.

Parameters:
  • can_id (int) – The CAN ID from which to unsubscribe.

  • callback – If given, remove only this callback. Otherwise all callbacks for the CAN ID.

Return type:

None

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, an ObjectDictionary or 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.SdoClient associated with the node.

sdo_channels

List of available SDO channels (added with add_sdo()).

tpdo

The canopen.pdo.PdoBase for TPDO associated with the node.

rpdo

The canopen.pdo.PdoBase for RPDO associated with the node.

nmt

The canopen.nmt.NmtMaster associated with the node.

emcy

The canopen.emcy.EmcyConsumer associated with the node.

object_dictionary

The canopen.ObjectDictionary associated with the node

network

The canopen.Network owning the node

add_sdo(rx_cobid, tx_cobid)[source]

Add an additional SDO channel.

The SDO client will be added to sdo_channels.

Parameters:
  • rx_cobid (int) – COB-ID that the server receives on

  • tx_cobid (int) – COB-ID that the server responds with

Returns:

The SDO client created

Return type:

canopen.sdo.SdoClient

curtis_hack

Enable WORKAROUND for reversed PDO mapping entries

load_configuration()[source]

Load the configuration of the node from the object dictionary.

restore(subindex=1)[source]

Restore default parameters.

Parameters:

subindex (int) –

1 = All parameters

2 = Communication related parameters

3 = Application related parameters

4 - 127 = Manufacturer specific

store(subindex=1)[source]

Store parameters in non-volatile memory.

Parameters:

subindex (int) –

1 = All parameters

2 = Communication related parameters

3 = Application related parameters

4 - 127 = Manufacturer specific

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.SdoServer associated with the node.

object_dictionary

The canopen.ObjectDictionary associated with the node

network

The canopen.Network owning the node

class canopen.network.MessageListener(network)[source]

Bases: Listener

Listens for messages on CAN bus and feeds them to a Network instance.

Parameters:

network (Network) – The network to notify on new messages.

on_message_received(msg)[source]

This method is called to handle the given message.

Parameters:

msg – the delivered message

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.

active = True

Activate or deactivate scanning

nodes: List[int]

A list of nodes discovered

reset()[source]

Clear list of found nodes.

search(limit=127)[source]

Search for nodes by sending SDO requests to all node IDs.

Return type:

None

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 message

  • data (bytes) – Data to be transmitted (anything that can be converted to bytes)

  • period (float) – Seconds between each message

  • bus (can.BusABC) – python-can bus to use for transmission

stop()[source]

Stop transmission

update(data)[source]

Update data of message

Parameters:

data (bytes) – New data to transmit

Return type:

None