Skip to main content

Interfacing To Inverter using Python and Peak CAN Interface

Emsiso Inverters primarily use the CANOpen protocol to communicate with outside tools. It is possible to use public libraries to communicate with the inverter using Python to automate production or assembly processes.

In this article, we will show how to connect to an Emsiso inverter using a PEAK CAN Interface and set/get a parameter value using an SDO Read/Write operations.

  • Note that all conditions or limitations still remain the same as if using the emDrive Configurator.
  • The article is intended for programmers with working knowledge of Python.

  • This article expects a basic understanding of CANOpen. It is suggested to get a cursory overview by reading this article on CANOpen basics: CANopen Explained - A Simple Intro [2025] – CSS Electronics

We will be using the publicly available Python CANOpen Library: canopen · PyPI

Exhaustive documentation for canopen is available on the official docu website:
canopen 0.1.dev52+ge840449 documentation

Minimum Requirements:
  • Python 3.8 or up (except for Python 3.12.0 due to an unresolved issue with the canopen library)
  • PEAK CAN Interface Drivers
  • Any Emsiso Inverter
Initial Setup:

First we need to install dependencies. In our case, the canopen library already installs the can-interface. It is strongly recommended to also install the uptime library in order to correctly show the frame times.

  • pip install canopen
  • pip install uptime
Step 1: Verify Connection:

In order to verify that the setup has been performed correctly, we can scan the nodes on the bus.

Take care to define proper channel and bitrate. The example below contains the values:

  • PCAN_USBBUS1: Windows machine with 1 CAN interface connected
  • 500000: 500 kbps bit rate

Further information on connecting HW interfaces (esp. PEAK) is available here:
PCAN Basic API - python-can 4.5.0 documentation

import canopen
import time

network = canopen.Network()

# We connect to the interface here. In our case it's the PCAN interface on bus 1.
network.connect(interface='pcan', channel='PCAN_USBBUS1', bitrate=500000)

time.sleep(0.05)
for node_id in network.scanner.nodes:
    # We expect to find 1 node if the inverter connection is successful
    print(f"Found node {node_id}!")

network.disconnect()

If the inverter is properly connected, is the only device on the bus, and all dependencies are correctly installed, you can expect the following output:

  • Found node 1!
Step 2: SDO Read/Write

After the connection is verified, we can proceed to perform an SDO write and read. 

In order to properly use the CANOpen protocol the object definition file (.eds) needs to be provided. The EDS can either be downloaded from the device using the emDrive configurator or can be provided by request from Emsiso. The object dictionary defines the available objects on the devices, it's indexes, subindexes, descriptions and types.

For more information on how to interact or get values from the object dictionary, please refer to the documentation for Python canopen.

Read Operation:

We will read from the [1018:1] - Vendor ID. The expected Vendor ID for Emsiso devices is: 966.

import canopen
import time

network = canopen.Network()

# We connect to the interface here. In our case it's the PCAN interface on bus 1.
network.connect(interface='pcan', channel='PCAN_USBBUS1', bitrate=500000)

#Insert the node ID of the device you want to connect to and provide the EDS file.
#In this case, we are using node ID 1 and the EDS file for the emDRIVE COMPACT 450/60.
node = canopen.RemoteNode(1, 'emDRIVE_COMPACT_450_60_APP_V1.18.4.eds')

# We add the node to the network.
network.add_node(node)

# Here we perform an SDO read operation from Index 0x1018, Subindex 1 in order to get the vendor ID.
vendor_id = node.sdo[0x1018][1].raw

#Print the vendor ID.
print(f"Vendor ID: {vendor_id}")

network.disconnect()

Expected Output:

  • Vendor ID: 966

Write Operation:

Writing to the object is very similar to reading. In this example we will be writing to object 2010:2 - Key Input. This object is normally used to raise the device access level, but in this case we will simply use it as an example. The device behaviour will not be changed by our write operation.

import canopen
import time

network = canopen.Network()

# We connect to the interface here. In our case it's the PCAN interface on bus 1.
network.connect(interface='pcan', channel='PCAN_USBBUS1', bitrate=500000)

#Insert the node ID of the device you want to connect to and provide the EDS file.
#In this case, we are using node ID 1 and the EDS file for the emDRIVE COMPACT 450/60.
node = canopen.RemoteNode(1, 'emDRIVE_COMPACT_450_60_APP_V1.18.4.eds')

# We add the node to the network.
network.add_node(node)

# Here we preform a SDO write operation into the Key Input parameter - Index 0x2010, Subindex 2. Writing a value of 1 to this parameter.
node.sdo[0x2010][2].raw = 1

#Print the vendor ID.
print(f"Write Successful.")

network.disconnect()
Step 3: NMT Operations

During the configuration of the inverter, it will sometimes be necessary to switch between different NMT states. In this case, we can use the NMT command.

An example on how to set the NMT state of the device (note that the network setup and disconnect must still be performed as in the above code examples):

node.nmt.state = 'OPERATIONAL'