Klipper 多机协同实战:3 台打印机如何组成可远程调度的集群
【免费下载链接】klipperKlipper is a 3d-printer firmware项目地址: https://gitcode.com/GitHub_Trending/kl/klipper
Klipper 是一套 3D 打印机固件,它的多 MCU 架构加 CAN 总线支持,让一组打印机可以组网、集中管理。我们的场景是:3 台机器分在两个车间,每天早上要人过去切 G-code、看谁忘了预热热床。目标是把这 3 台变成可云打印式远程下发、集中监控状态的打印集群。
先判断要不要上 CAN:USB 还是 CAN 总线
先给结论,对比一张表:
| USB | CAN 总线 | |
|---|---|---|
| 接线方式 | 星型,每个 MCU 一根线找主机 | 总线型,多个 MCU 串在同两根线上 |
| 走线距离 | 受 USB 线长限制 | 1Mbps 下几十米内可走线,支持菊花链 |
| 扩容成本 | 每加一个 MCU 多占一个口 | 总线上多接一个节点即可 |
| 典型用途 | 单 MCU 单机 | 2–10 台机器、单台多 MCU 扩展 |
结论:2 台以上、或者单台机器就要挂两个以上 MCU,且主板带 CAN 收发器(STM32、SAM E5x、RP2040 系),优先 CAN。单台单 MCU 就别折腾了。
一个容易混淆的点:Klipper 的 CAN 主要用于一台机器内部多个 MCU 协同;多台机器之间联网靠的是「机内 CAN + 机间以太网/API」的组合,别一开始就想着用一根 CAN 线把车间里的机器串起来。
把链路搭通
CAN 总线接线与终端电阻验证
先把 USB-CAN 主机适配器、CANH/CANL 双绞线和 GND 接好。我们踩过两个坑:
- 终端电阻:整条总线上 CANH 与 CANL 之间必须正好有两个 120Ω,理想情况各在总线两端。很多板子内置了去不掉的 120Ω,先翻原理图数一遍;断电后用万用表量两线间电阻,正常应显示约 60Ω。
- 双绞与防振:CANH/CANL 要绞在一起走线,别贴着电源线平行走。打印时刀架移动会甩动线缆,压接点一松就是间歇性通信错误,这是最难排查的一类故障。
信号层面不放心时,接个几十块的逻辑分析仪,用 PulseView 抓 CAN 报文,能直接看到位流和解析出的帧字段:
Linux 主机侧 can0 接口配置与设备发现
主机端建一个/etc/network/interfaces.d/can0:
allow-hotplug can0 iface can0 can static bitrate 1000000 up ip link set $IFACE txqueuelen 128txqueuelen 128别省:内核默认只排 10 个待发 CAN 包,突发时直接丢包(日志里会刷 No buffer space available);总线上挂 5 个以上 MCU 时还要再评估调大。
上电接好线后,用 canbus_query 脚本 拿 UUID:
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
输出里Found canbus_uuid=11aa22bb33cc就是目标节点。注意这工具只能发现尚未被 Klipper 认领的节点,而且它用低层机制扫描,打印进行中运行可能干扰总线——只在初始接线阶段用。
把 canbus_uuid 写进配置
拿到 UUID 后写进 printer.cfg:
[mcu my_can_mcu] canbus_uuid: 11aa22bb33cc多 MCU 怎么分工,可参考 sample-multi-mcu.cfg 这种三 MCU 示例:运动轴放主 MCU,加热和传感放从 MCU。想把跑 Klipper 的树莓派自身 GPIO 当辅助 MCU 用(控机箱灯、读 I2C 传感器),那是另一条 Linux 进程的路子,步骤见 RPi_microcontroller.md。
让任务真正跑起来:Moonraker + Mainsail 最小部署
Klipper 本体只提供一个 Unix 套接字 API(API_Server 文档),集群需要一个 HTTP 层,分工是这样的:
- 每台打印机上:klipper + moonraker。Moonraker 把 HTTP/WebSocket 请求转发到 Klipper 的
klippy_uds,同时负责 G-code 上传、打印队列、摄像头。 - 工位或管理机上:Mainsail(或 Fluidd)。浏览器指到哪台机器的 moonraker 端口,就看哪台。
换句话说,moonraker 跑在每台机器上,Mainsail 跑在你想操作的地方。想要一个入口管所有机器,用 Mainsail 的多设备模式,把各机器的 moonraker 地址加进同一界面即可——这比「一台开一个页面」省心得多。
最小验证不必等界面,直接用命令行对着 API 发一条请求。用 whconsole 连上套接字后输入:
{"id": 1, "method": "objects/query", "params": {"objects": {"webhooks": ["state"]}}}返回ready说明链路通,后面 Moonraker 只是把这一层搬到 HTTP 上。
Web 端拿到手后,各机器的温度与状态趋势长这样,多机数据可以汇总到同一块看板:
多机任务队列与状态同步设计
调度层不是 Klipper 自带的组件,是架在 moonraker API 之上自己拼的,思路有四条:
- 任务队列:一个中心服务(简单的数据库加 worker 就够)持有任务列表,按优先级排序;下发前查目标机器
webhooks.state是否为 ready,这就是最朴素的负载均衡;失败的任务限次重试,超次进死信列表人工看。 - 状态同步:别轮询,用订阅。Klipper 的
objects/subscribe会把状态和温度的增量变化推过来,中心服务只需聚合每台机器的订阅流。订阅请求长这样:
{"id": 2, "method": "objects/subscribe", "params": {"objects": {"webhooks": ["state"], "extruder": ["temperature"]}}}- 告警:状态切到 shutdown 就通过 Webhook 或 MQTT 推通知,轮询式检查往往发现时打印早已停了。
- 边界情况:机器重启后 moonraker 会重连重订阅,中心服务要能识别「断线」和「就绪」,别把重启当成掉线反复重试同一个任务。
上线前必查清单
- CANH/CANL 终端电阻:总线上恰好两个 120Ω,断电量约 60Ω
ip link show can0确认 qlen 128、比特率 1Mbps- 打印中观察
bytes_invalid计数器不应持续增长,持续涨要查内核与适配器固件版本,细节见 CANBUS_Troubleshooting - TLS 与访问控制:moonraker API 走 HTTPS 反向代理,Mainsail 开账号,服务端口不对公网裸露
- 防火墙:外部只放行 443,局域网内网段放通;访问日志留着备查
- 日志路径统一:各机 klippy.log 与 moonraker 日志放在固定位置,排障时不用找
- 每台机器单独跑通「远程下发→打印完成→状态恢复」全流程,再并入队列
收尾
回到开头:早上不用再跑车间切 G-code 了,文件拖进中心队列,3 台机器按优先级依次自己开工。下一步建议:先接第二台机器,把 UUID 发现到 moonraker 部署这条链路完整走一遍,跑通了再扩第三台。
【免费下载链接】klipperKlipper is a 3d-printer firmware项目地址: https://gitcode.com/GitHub_Trending/kl/klipper
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考