python-can-candle
python-can-candle 适合在 Windows 或 Linux 上使用 Python 直接访问
CAN 和 CAN FD 设备。
开发板包含两颗 MCU,每颗 MCU 提供两个 CAN/CAN FD channel,因此通常可 检测到两个 USB 设备、共四个 channel。USB 设备枚举顺序和 channel 编号不能 直接对应板上接口丝印,首次使用时应逐路确认。
python-can-candle 主要用于 Windows Python 程序控制,以及需要跨平台统一
python-can API 的场景。
安装
本说明基于 python-can-candle 1.2.4:
python -m pip install "python-can-candle==1.2.4"
SANPO 集成板已经通过 Windows WCID 自动绑定 WinUSB, 不需要使用 Zadig,也不需要安装驱动。
安装后查看版本:
python -m pip show python-can-candle candle-api python-can
检测通道
import can
for config in can.detect_available_configs("candle"):
print(config)
开发板通常输出四项,channel 格式类似:
SERIAL_0:0
SERIAL_0:1
SERIAL_1:0
SERIAL_1:1
SERIAL_0、SERIAL_1 是两颗 MCU 各自的 USB 序列号。序列号可以稳定区分
两颗 MCU,但不能仅凭序列号判断它对应板上的哪两路接口。
经典 CAN
以下示例在指定 MCU 的 channel 0 上使用 1 Mbit/s,发送一个标准帧并等待回复:
import can
serial = "替换为实际序列号"
with can.Bus(
interface="candle",
channel=f"{serial}:0",
vid=0x1209,
pid=0x2323,
manufacture="SANPO",
product="SANPO gs_usb CDC Composite fdV8",
bitrate=1_000_000,
sample_point=80.0,
ignore_config=True,
) as bus:
message = can.Message(
arbitration_id=0x123,
is_extended_id=False,
data=[0x11, 0x22, 0x33, 0x44],
)
bus.send(message, timeout=1.0)
reply = bus.recv(timeout=1.0)
print(reply)
示例 ID 和数据没有实际设备含义,应替换为所连接设备的协议内容。
CAN FD
以下示例配置仲裁段 1 Mbit/s、数据段 5 Mbit/s,并发送开启 BRS 的 CAN FD 帧:
import can
serial = "替换为实际序列号"
with can.Bus(
interface="candle",
channel=f"{serial}:0",
vid=0x1209,
pid=0x2323,
manufacture="SANPO",
product="SANPO gs_usb CDC Composite fdV8",
fd=True,
bitrate=1_000_000,
sample_point=80.0,
data_bitrate=5_000_000,
data_sample_point=75.0,
ignore_config=True,
) as bus:
message = can.Message(
arbitration_id=0x123,
is_extended_id=False,
is_fd=True,
bitrate_switch=True,
data=bytes(range(16)),
)
bus.send(message, timeout=1.0)
SANPO SPINE 的 CAN FD 数据段支持 2/3/4/5 Mbit/s。使用 2/3/4 Mbit/s 时
推荐 data_sample_point=80.0;使用 5 Mbit/s 时推荐
data_sample_point=75.0。
同一颗 MCU 的两个通道
同一颗 MCU 的两个 channel 应由一个 CandleBus 实例共同打开:
import can
with can.Bus(
interface="candle",
channel=[0, 1],
serial_number="替换为实际序列号",
bitrate=1_000_000,
sample_point=80.0,
ignore_config=True,
) as bus:
message = can.Message(
arbitration_id=0x123,
is_extended_id=False,
channel=1,
data=[0x01, 0x02],
)
bus.send(message, timeout=1.0)
这里的 Message.channel 只用于主机选择物理 CAN 通道,不会写入 CAN 数据,
也不是 SANPO 自定义通道报文。访问完整四路 CAN 时,应分别为两颗 MCU 创建
一个 CandleBus。
小米 CyberGear 示例
示例程序: python-can-candle CyberGear 逐步使用说明
先执行只读设备枚举,不发送 CAN 帧:
python pythoncan_cybergear_demo_v8.py --list-devices
确认两颗 MCU 的序列号和物理通道映射后,再进行空载初始化测试。以下命令会 配置 CAN 并向电机发送初始化、使能和停止指令:
python pythoncan_cybergear_demo_v8.py \
--enable-motion \
--init-only \
--device-serials "SERIAL_0,SERIAL_1" \
--motor-map "0/0:1,2,3;0/1:4,5,6;1/0:7,8,9;1/1:10,11,12"
0/1 表示 --device-serials 中第 0 颗 MCU 的 channel 1。首次运行必须空载,
确认急停有效,并根据实际接线调整电机 ID 和通道映射。
使用限制
同一个 gs_usb 接口不能同时由 CANgaroo、
python-can-candle或其他 WinUSB 程序占用。运行 Python 示例前应关闭 CANgaroo 的连接。同一个物理 CAN/CAN FD 通道不要同时由 USB 透传、管理口协议、SPI 或离线 任务发送数据。
python-can-candle打开通道时会重新配置波特率;这些设置不会作为用户配置 永久保存。Linux 下如果接口已经由内核
gs_usb驱动生成canX,应直接使用 SocketCAN,避免两个主机驱动竞争同一 USB 接口。
常见问题
现象 |
处理方法 |
|---|---|
|
关闭 CANgaroo、其他 Python 进程及占用该 WinUSB 接口的软件 |
能发送但设备不回复 |
检查 channel 与物理接口映射、波特率、终端电阻、设备 ID 和供电 |
CAN FD 通信错误 |
确认仲裁段、数据段波特率及采样点与总线中所有设备一致 |