Python CAN / SLCAN send and receive example
SLCAN is a CAN interface protocol operating via serial communication. It’s often used to connect to CAN interfaces via USB.
The following example uses the python-can
library to send and receive CAN messages via SLCAN.
The basic intention is to have two separate CAN adapters (such as the really cheap FYSETC UCAN with the slcan firmware)
First, install the python-can
library:
pip install python-can
Sender example
This code connects to /dev/ttyACM0
and repeatedly sends a single CAN message:
#!/usr/bin/env python3
import can
import time
# Configuration for the SLCAN device
slcan_device = '/dev/ttyACM0'
baud_rate = 500000 # Set the appropriate baud rate for your setup
# Create a CAN bus instance using the SLCAN interface
bus = can.interface.Bus(interface='slcan', channel=slcan_device, bitrate=baud_rate)
# Define a simple CAN message
can_id = 0x123 # CAN ID
data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] # 8 bytes of data
# Create a CAN message
message = can.Message(arbitration_id=can_id, data=data, is_extended_id=False)
try:
while True:
# Send the CAN message
bus.send(message)
print(f"Sent: {message}")
# Wait for a second before sending the next message
time.sleep(1)
except KeyboardInterrupt:
print("Stopped by user")
except can.CanError as e:
print(f"CAN error: {e}")
Example output
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Sent: Timestamp: 0.000000 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Receiver example
This code connects to /dev/ttyACM1
and listens for incoming CAN messages (and prints them on the command line):
#!/usr/bin/env python3
import can
# Configuration for the SLCAN device
slcan_device = '/dev/ttyACM1'
baud_rate = 500000 # Set the appropriate baud rate for your setup
# Create a CAN bus instance using the SLCAN interface
bus = can.interface.Bus(interface='slcan', channel=slcan_device, bitrate=baud_rate)
try:
print("Listening for CAN messages on", slcan_device)
while True:
# Read a message from the CAN bus
message = bus.recv()
if message is not None:
print(f"Received: {message}")
except KeyboardInterrupt:
print("Stopped by user")
except can.CanError as e:
print(f"CAN error: {e}")
Example output
Listening for CAN messages on /dev/ttyACM1
Received: Timestamp: 1722300573.156834 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157226 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157592 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157937 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.979205 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300574.979508 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300575.979660 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300576.979969 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08
Received: Timestamp: 1722300577.980201 ID: 123 S Rx DL: 8 01 02 03 04 05 06 07 08