python-can API

The python-can module is imported with:

import can

The two main python-can objects are:

  • Bus: Defines a CAN-bus interface[1]

  • Message: Defines a CAN-bus message (containing timestamp, ID, data, and more)[2]


Detect interfaces

The python-can package supports auto-detection of available interfaces.

Detect interface on Windows
>>> can.detect_available_configs("csscan_serial")
[{'interface': 'csscan_serial', 'channel': 'COM19'}]
Detect interface on Linux
>>> can.detect_available_configs("csscan_serial")
[{'interface': 'csscan_serial', 'channel': '/dev/ttyACM0'}]

Auto-detection can be used to automatically find and open a bus.

import can

# Detect busses
configs = can.detect_available_configs("csscan_serial")
assert len(configs) == 1

# Open bus
with can.Bus(interface=configs[0]["interface"], channel=configs[0]["channel"]) as bus:
    ...

Receive messages

The most basic way of receiving messages is demonstrated below.

import can

# Open bus
with can.Bus(interface="csscan_serial", channel="<CHANNEL>") as bus:

    # Receive messages
    for msg in bus:
        print(f"{msg.timestamp:.3f} {msg.arbitration_id:X} {msg.data.hex()}")

The python-can notifier can be used for more advanced use-cases. Below demonstrates how to use the existing python-can Printer and Logger together with a custom Listener.

import can
from time import sleep

class CustomListener(can.Listener):
    def on_message_received(self, msg: can.Message) -> None:
        # Some custom handling of received messages
        pass

# Open bus
with can.Bus(interface="csscan_serial", channel="<CHANNEL>") as bus:

    # Printer (prints formatted messages to screen)
    print_listener = can.Printer()

    # Logger (logs formatted messages to file)
    log_listener = can.Logger("out.log")

    # Custom listener (invokes listener call-back when message received)
    custom_listener = CustomListener()

    # Create notifier with printer, logger, and custom listeners
    notifier = can.Notifier(bus, listeners=[print_listener, log_listener, custom_listener])
    sleep(10)
    notifier.stop()

For more information, see https://python-can.readthedocs.io/en/stable/listeners.html#notifier.


Transmit messages

The most basic way of transmitting messages is demonstrated below.

import can

# Open bus
with can.Bus(interface="csscan_serial", channel="<CHANNEL>") as bus:

    # Transmit message
    bus.send(can.Message(arbitration_id=0x123, is_extended_id=False, data=[0x01, 0x23, 0x45, 0x67]))

Periodic transmit messages can be configured using the python-can broadcast-manager, see https://python-can.readthedocs.io/en/stable/bcm.html.