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.
>>> can.detect_available_configs("csscan_serial")
[{'interface': 'csscan_serial', 'channel': 'COM19'}]
>>> 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.