{"id":4465,"library":"canopen","title":"CANopen Stack for Python","description":"The `canopen` library provides a comprehensive Python implementation of the CANopen communication protocol. It allows developers to interact with CANopen devices, manage CANopen networks, and implement custom CANopen nodes. The current stable version is 2.4.1. Releases occur on an as-needed basis, driven by bug fixes, new features, and compatibility updates, typically every few months to once a year.","status":"active","version":"2.4.1","language":"python","source_language":"en","source_url":"https://github.com/python-canopen/canopen","tags":["canopen","canbus","industrial automation","protocol","embedded"],"install":[{"cmd":"pip install canopen","lang":"bash","label":"Base installation"},{"cmd":"pip install 'canopen[socketcan]' # For Linux SocketCAN\npip install 'canopen[pcan]'    # For PEAK-System PCAN\n# ... or other specific backends based on your CAN hardware","lang":"bash","label":"Install `python-can` backend"}],"dependencies":[{"reason":"Core dependency for CAN bus communication; specific hardware-related backends (e.g., `python-can[socketcan]`) must be installed separately.","package":"python-can","optional":false}],"imports":[{"symbol":"Network","correct":"import canopen\nnetwork = canopen.Network()"},{"symbol":"Node","correct":"import canopen\nnode = canopen.Node(node_id, 'eds_file.eds')"},{"symbol":"SdoError","correct":"from canopen.sdo import SdoError"}],"quickstart":{"code":"import canopen\nimport time\nimport os\n\n# Configuration\nCAN_BUSTYPE = os.environ.get('CAN_BUSTYPE', 'socketcan') # e.g., 'socketcan', 'pcan', 'ixxat'\nCAN_CHANNEL = os.environ.get('CAN_CHANNEL', 'can0')     # e.g., 'can0', 'PCAN_USBBUS1'\nNODE_ID = int(os.environ.get('CANOPEN_NODE_ID', '1'))\nEDS_FILE = os.environ.get('CANOPEN_EDS_FILE', 'example.eds') # Replace with your device's EDS file\n\n# Create a dummy EDS file for demonstration if it doesn't exist\n# In a real application, you would use a manufacturer-provided .eds\nif not os.path.exists(EDS_FILE):\n    print(f\"Warning: {EDS_FILE} not found. Using a generic one (may not work with your device).\")\n    with open(EDS_FILE, 'w') as f:\n        f.write(\"\"\"\n[FileInfo]\n; Generated EDS for a generic CANopen device\nFileName = ExampleDevice.eds\nFileVersion = 1.0\nVendorName = Example Vendor\nProductName = Example Product\nProductCode = 0\nRevisionNo = 1.0\nCreationTime = 2023-01-01 12:00:00\n\n[Device]\nDeviceType = 0x00020002\n\n[0x1000] ; Device Type\nParameterName = Device Type\nObjectType = 7\nDataType = 0x0007\nAccessType = ro\nDefaultValue = 0x00020002\n\n[0x1001] ; Error Register\nParameterName = Error Register\nObjectType = 7\nDataType = 0x0005\nAccessType = ro\nDefaultValue = 0x00\n\n[0x2000] ; Example Manufacturer Specific Integer (RW)\nParameterName = My Integer\nObjectType = 7\nDataType = 0x0007\nAccessType = rw\nDefaultValue = 123\n\"\"\")\n\ntry:\n    # Start with creating a network representing one CAN bus\n    network = canopen.Network()\n\n    # Connect to the CAN bus\n    # The bustype and channel must match your installed python-can backend\n    print(f\"Connecting to CAN bus: bustype='{CAN_BUSTYPE}', channel='{CAN_CHANNEL}'\")\n    network.connect(bustype=CAN_BUSTYPE, channel=CAN_CHANNEL)\n    print(\"Connected to CAN bus.\")\n\n    # Add a CANopen node with documentation from the EDS file\n    # For a real device, replace NODE_ID and EDS_FILE with your device's info\n    node = canopen.Node(NODE_ID, EDS_FILE)\n    network.add_node(node)\n    print(f\"Added Node {NODE_ID} using {EDS_FILE}.\")\n\n    # Read a value from the object dictionary (e.g., Device Type 0x1000)\n    device_type = node.sdo['Device Type'].raw\n    print(f\"Node {NODE_ID} Device Type (0x1000): {hex(device_type)}\")\n\n    # Write and read a manufacturer-specific object (e.g., 0x2000 subindex 0)\n    # This assumes your EDS or device supports object 0x2000\n    try:\n        original_val = node.sdo[0x2000].raw\n        print(f\"Original value of 0x2000: {original_val}\")\n\n        new_val = 456\n        node.sdo[0x2000].raw = new_val\n        print(f\"Wrote {new_val} to 0x2000.\")\n\n        read_val = node.sdo[0x2000].raw\n        print(f\"Read back value of 0x2000: {read_val}\")\n        assert read_val == new_val\n\n    except canopen.sdo.SdoError as e:\n        print(f\"Could not access object 0x2000 on Node {NODE_ID}. This might be an EDS mismatch or device limitation: {e}\")\n\n    # For real-time data (PDOs), you'd typically start the network's processing loop\n    # in a separate thread or call network.process() periodically.\n    # For this quickstart, we'll just demonstrate it briefly.\n    print(\"Starting network processing for 1 second...\")\n    network.nmt.state = 'OPERATIONAL' # Set node to operational for PDOs\n    start_time = time.time()\n    while time.time() - start_time < 1:\n        network.process(0.01) # Process messages for 10ms\n        time.sleep(0.01)\n    print(\"Network processing finished.\")\n\nexcept canopen.CanError as e:\n    print(f\"CANopen Error: {e}\")\n    print(\"Please ensure your CAN hardware is connected and the python-can backend is correctly installed.\")\n    print(f\"Tried bustype='{CAN_BUSTYPE}', channel='{CAN_CHANNEL}'\")\nexcept FileNotFoundError:\n    print(f\"Error: EDS file '{EDS_FILE}' not found. Please provide a valid EDS file for your device.\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\nfinally:\n    # Disconnect from CAN bus\n    if 'network' in locals() and network.is_connected:\n        print(\"Disconnecting from CAN bus.\")\n        network.disconnect()\n    if os.path.exists(EDS_FILE) and 'Warning: ' in locals() and 'generic one' in locals(): # Clean up dummy EDS\n        os.remove(EDS_FILE)\n        print(f\"Removed dummy EDS file: {EDS_FILE}\")\n","lang":"python","description":"This quickstart demonstrates how to connect to a CAN bus, add a CANopen node using an EDS file, and perform basic SDO (Service Data Object) read/write operations. It includes error handling for common issues like CAN connection problems and missing EDS files. Remember to replace placeholder values for `CAN_BUSTYPE`, `CAN_CHANNEL`, `NODE_ID`, and `EDS_FILE` with your actual setup. A dummy `example.eds` is created if not found, but a real EDS file for your device is crucial for proper communication."},"warnings":[{"fix":"Install the appropriate `python-can` backend for your system, e.g., `pip install 'canopen[socketcan]'` if your hardware uses SocketCAN.","message":"The `canopen` library relies on `python-can` for CAN bus communication. You must install `python-can` with the correct backend specific to your CAN hardware (e.g., `pip install 'python-can[socketcan]'` for SocketCAN on Linux, `pip install 'python-can[pcan]'` for PEAK-System PCAN). The base `pip install canopen` does not install these hardware-specific dependencies, leading to `canopen.CanError` or `NoBackendError` if missing.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Obtain the correct EDS file for your CANopen device from its manufacturer and pass its path to `canopen.Node(node_id, 'path/to/your/device.eds')`.","message":"Most CANopen operations, especially for specific devices, require an Electronic Data Sheet (EDS) file. This file describes the device's object dictionary and communication behavior. Not providing a valid EDS file, or using a generic one that doesn't match your device, will prevent correct SDO/PDO communication and can lead to errors like `KeyError` when accessing object dictionary entries.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Implement a separate thread or an asynchronous loop that regularly calls `network.process(timeout)` with a small `timeout` value (e.g., `0.01` seconds).","message":"For non-blocking operations, such as receiving PDOs (Process Data Objects) or background processing, you must periodically call `network.process(timeout)` in a loop or dedicated thread. If only SDOs are used, it might appear optional, but for robust and real-time interaction, especially with multiple nodes, the network processing loop is critical. Failing to do so will result in missed PDOs and potentially stale network states.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Implement robust `try...except canopen.sdo.SdoError` blocks around SDO operations. You can also configure the SDO timeout for individual nodes, e.g., `node.sdo.timeout = 1.0` (for 1 second).","message":"SDO (Service Data Object) requests are blocking by default. If the remote device does not respond within the default timeout (usually 500 ms), a `canopen.sdo.SdoError` will be raised. This can be problematic in noisy environments or with slow-responding devices.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"search_vec":"'2.4.1':39 'allow':19 'as-need':44 'autom':68 'basi':47 'bug':50 'canbus':66 'canopen':1,6,15,24,27,32,65 'communic':16 'compat':55 'comprehens':10 'current':35 'custom':31 'develop':20 'devic':25 'driven':48 'embed':70 'everi':58 'featur':53 'fix':51 'implement':12,30 'industri':67 'interact':22 'librari':7 'manag':26 'month':60 'need':46 'network':28 'new':52 'node':33 'occur':41 'protocol':17,69 'provid':8 'python':4,11 'releas':40 'stabl':36 'stack':2 'typic':57 'updat':56 'version':37 'year':64","created_at":"2026-04-12T13:53:49.458452+00:00","updated_at":"2026-04-16T01:24:03.711452+00:00","problems":[{"fix":"Install the library using pip: `pip install canopen`.","cause":"The 'canopen' library is not installed in the Python environment, or the Python interpreter cannot find it in its search path.","error":"ModuleNotFoundError: No module named 'canopen'"},{"fix":"Ensure `python-can` is correctly installed for your specific CAN interface (e.g., `pip install 'python-can[pcan]'`). Verify the `bustype`, `channel`, and `bitrate` parameters match your hardware setup and `python-can` configuration. Check device drivers and permissions for the CAN interface.","cause":"The `canopen.Network.connect()` method failed to establish a connection to the specified CAN bus. This often indicates issues with the `python-can` backend configuration, incorrect channel or bitrate parameters, or problems with the physical CAN interface (e.g., driver issues, device not connected, permissions).","error":"can.CanError: Could not connect to CAN bus"},{"fix":"Verify the remote node's ID and ensure it is in the 'Operational' NMT state. Check the physical CAN bus for connectivity and termination. Increase the SDO timeout if the network is busy or the node is slow to respond, or ensure the node is actively participating in the CANopen network.","cause":"During an SDO (Service Data Object) communication, the remote CANopen node did not respond within the expected timeout period. This can be due to an incorrect node ID, the node being in the wrong NMT state (e.g., not operational), network communication issues, or the node being unresponsive.","error":"canopen.sdo.exceptions.SdoCommunicationError: No SDO response received"},{"fix":"Review the EDS file used to load the object dictionary and compare it against the device's actual object dictionary implementation. Ensure the EDS file is correct and matches the firmware version of the device. If writing, ensure the data being sent matches the expected size for the object index and sub-index.","cause":"This error occurs when the object dictionary (typically loaded from an EDS file) defines a certain data size for an object, but the actual data received from or sent to the CANopen device via SDO has a different size.","error":"canopen.objectdictionary.ObjectDictionaryError: Mismatch between expected and actual data size"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.4.1","cli_name":"canopen","cli_version":"sh: 1: canopen: not found","type":"library","homepage":null,"github":"https://github.com/canopen-python/canopen","docs":"https://canopen.readthedocs.io/en/stable/","changelog":null,"pypi":"https://pypi.org/project/canopen/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["communication","http-networking"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}