Full featured CAN driver for Geschwister Schneider USB/CAN devices.
Support Multichannel and CAN FD.
pip install python-can-candleThis library implements the plugin interface in python-can, aiming to replace the gs_usb interface within it.
import can
from candle import CandleBus
# Create a CandleBus instance in the python-can API.
with can.Bus(interface='candle', channel=0, ignore_config=True) as bus:
# Bus is an instance of CandleBus.
assert isinstance(bus, CandleBus)Set ignore_config=True is recommended to prevent potential type casts.
You can configure the device by appending the following parameters when creating the can.Bus.
- bitrate: int, defaults to 1000000
- sample_point: float, defaults to 87.5
- data_bitrate: int, defaults to 5000000
- data_sample_point: float, defaults to 87.5
- fd: bool, defaults to False
- loop_back: bool, defaults to False
- listen_only: bool, defaults to False
- triple_sample: bool, defaults to False
- one_shot: bool, defaults to False
- bit_error_reporting: bool, defaults to False
- termination: bool or None, defaults to None
For example, create a canfd device with 1M bitrate and 5M data bitrate.
with can.Bus(interface='candle', channel=0, fd=True, bitrate=1000000, data_bitrate=5000000, ignore_config=True) as bus:
...When connecting multiple devices at the same time, you can set channel to serial_number:channel to create the specified can.Bus.
with can.Bus(interface='candle', channel='208233AD5003:0', ignore_config=True) as bus:
...You can also select devices by appending some additional parameters.
- vid: int, vendor ID
- pid: int, product ID
- manufacture: str, manufacture string
- product: str, product string
- serial_number: str, serial number
Detect all available channels.
channels = can.detect_available_configs('candle')
print(channels)This driver now supports opening multiple channels from the same device in a single CandleBus instance.
- Pass a list of channel indices belonging to the same device, e.g.
channel=[0, 1]. - For multiple devices, pass
serial_number=SERIALto select the device by serial number. - Configure each channel separately with
channel_configs.
Create a CandleBus instance with multiple channels.
bus = CandleBus(channel=[0, 1], serial_number='208233AD5003', bitrate=1000000)Create and configure channels with different bitrates.
bus = CandleBus(channel=[0, 1], serial_number='208233AD5003', channel_configs={0: {'bitrate': 500000}, 1: {'bitrate': 1000000})Send to a specific channel.
msg = can.Message(arbitration_id=0x100, channel=1, data=[0x1, 0x2, 0x3, 0x4])
bus.send(msg)Send to multiple channels.
msg = can.Message(arbitration_id=0x100, channel=[0, 1], data=[0x1, 0x2, 0x3, 0x4])
bus.send(msg)Distinguish channels in received messages.
msg = bus.recv()
print(f'Received message on channel {msg.channel}.')send()routes frames to the target channel based onmsg.channel(int,"SERIAL:idx", orSequence[int]).recv()returnsMessage.channelset to the source channel number.- When
msg.channelis not set,send()defaults to the first channel.
The communication layer is implemented based on pybind11 with libusb. You can run the following scripts to evaluate the performance.
For single-channel performance:
python -m candle.stressFor multi-channel performance:
python -m candle.stress_multichannel