Python CAN Bus Interface

4.6.1 · active · verified Fri Apr 10

The python-can library provides Controller Area Network (CAN) support for Python developers, offering common abstractions to various hardware devices and a suite of utilities for sending and receiving messages on a CAN bus. It supports CPython and PyPy, running on Mac, Linux, and Windows. The current version is 4.6.1, with frequent updates to the 4.x series.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize a CAN bus and send a single message. It uses a `with` statement for proper resource management. For testing without physical hardware, a virtual CAN interface (like `vcan0` on Linux) can be used.

import can
import os

# For a runnable example without physical hardware, you can set up a virtual CAN interface:
# On Linux, run in terminal: `sudo modprobe vcan && sudo ip link add dev vcan0 type vcan && sudo ip link set vcan0 up`
# Then, use channel='vcan0' below.

# Configure bus interface and channel (can be set via environment variables or config file too)
# Using 'socketcan' with 'vcan0' is a common virtual setup on Linux.
# Replace 'socketcan' and 'vcan0' with your actual interface and channel if using real hardware.
BUS_INTERFACE = os.environ.get('CAN_INTERFACE', 'socketcan')
CAN_CHANNEL = os.environ.get('CAN_CHANNEL', 'vcan0')

try:
    # Using 'with' statement ensures the bus is properly shut down
    with can.Bus(interface=BUS_INTERFACE, channel=CAN_CHANNEL, receive_own_messages=True) as bus:
        # Create a CAN message
        message = can.Message(
            arbitration_id=0x123,  # Standard or extended ID
            is_extended_id=False, # Set to True for extended IDs
            data=[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], # 0-8 bytes for CAN 2.0, up to 64 for CAN FD
            is_fd=False,          # Set to True for CAN FD messages
            bitrate_switch=False, # Relevant for CAN FD
            error_state_indicator=False # Relevant for CAN FD
        )

        print(f"Attempting to send message: {message}")
        bus.send(message)
        print(f"Message sent successfully on {bus.channel} using {bus.interface} interface.")

        # Optional: Receive a message
        # received_message = bus.recv(10.0) # Wait up to 10 seconds for a message
        # if received_message:
        #    print(f"Received message: {received_message}")
        # else:
        #    print("No message received.")

except can.CanError as e:
    print(f"Error sending message: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

view raw JSON →