跟思兼学Klipper(38) 成品3D打印机使用外挂上位机提升性能简明指南
前言
原创文章,转载引用务必注明链接,水平有限,如有疏漏,欢迎指正交流。
文章如有更新请访问 DFRobot 社区及 cnblogs 博客园,前者内容较全,后者排版及阅读体验更佳。
随着拓竹的入场和各大 3D 打印机厂商革新追赶 + 价格内卷 + 专利壁垒,目前是商品机(以下简称厂机)为主流的时代,价格便宜、配置齐全、开箱即用。但是出于成本等因素考虑,各家机器都会采用性能不那么高的上位机 ,从而导致用户使用起来不是那么舒服,甚至出现复杂打印任务失败的情况。所以本文的目的是通过网线连接另一台高性能上位机,而不进行硬件上的修改,从而简单提升性能与使用体验。本文在创想三维 K1C 上稳定打印,在起迪 Q2 上测试通过,再次感谢必趣科技、创想三维和起迪科技的赞助。
本文软硬件环境:
- 起迪 Q2 3D 打印机
- 系统版本:Linaro-alip Bullseye
- 必趣 BTTPi2 上位机(RK3566)
- 系统版本:Armbian Bookworm
实际上,只要是 ARM64 CPU 架构的上位机即可,主要受限于部分打印机核心功能以闭源二进制 so 库文件的形式提供。
这里简单解释一下,Q2 的压力调平器等相关代码是运行在 ARM64 CPU 上的兼容 Python3.9 的二进制库文件,也只能运行在相同架构上。
现状
1. 为何不直接更换主板、上位机呢?
主要是为了降低升级硬件和时间成本,最大化利用原有配件。除此之外:
- 屏幕一般采用排线和上位机直接连接(LVDS、MIPI/DSI)
- 二合一主板
- 主板和上位机使用RS232等接口通讯,需要额外的模块
- 操作系统优化不足,需要一个清爽的系统
- 原厂上位机性能一般,256-512M内存,低性能CPU
2. 要解决的问题
- 部分代码如压力调平器、多色模块控制为二进制闭源 so 文件
- 基于旧版 Klipper / 操作系统修改,使用旧版如Py3.8/3.9 而不是主流的Python11/12
3. 方案规划
有线网络比无线网络更稳定,延迟更小,所以此处首选。百兆足够。


二、原厂上位机软件操作
由于我们计划使用网线直连,优先选择使用 DHCP 服务器自动分配 IP 地址。当然你也可以选择交换机(路由器)或者在 local 和 2ndhost 上设置静态 IP 地址。至于 DHCP 服务器运行在 local 和 2nd_host 上都可以,前者更方便。
可以选择 dnsmasq-base 或 udhcpd,此处选择后者,更简单轻量。使用 htop 可以看到原厂系统使用 wpa_supplicant 直接管理网络,配置文件地址为:/etc/wpa_supplicant/wpa_supplicant-wlan0.conf。安装了 networkmanager 但是没有启用,好嘞,正品 MKS 风。
2.1 配置静态 IP 地址
sudo apt install wget usbutils net-tools gpiod bash-completion fonts-wqy-zenhei udhcpd jq -y
# 配置 eth0 使用静态 IP
sudo tee /etc/network/interfaces > /dev/null <<'EOF'
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source /etc/network/interfaces.d/*
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
# 本地回环接口
auto lo
iface lo inet loopback
# 有线网络接口
auto eth0
iface eth0 inet static
address 192.168.1.1
netmask 255.255.255.0
EOF
2.2 部署 DHCP 服务器
sudo apt install udhcpd
# /etc/default/udhcpd,注释来 ENABLE,不需要-f前台
# 修改udhcpd服务,注意网卡名称,或者不设置网卡名称
# 创建服务配置覆盖目录
sudo mkdir -p /etc/systemd/system/udhcpd.service.d
sudo tee /etc/systemd/system/udhcpd.service.d/override.conf > /dev/null <<'EOF'
[Unit]
# 清除原有After依赖
Before=
After=
# 设置新的依赖关系
#After=network.target network-online.target sys-subsystem-net-devices-eth0.device
After=network.target network-online.target
Wants=network-online.target
#BindsTo=sys-subsystem-net-devices-eth0.device
EOF
# 修改udhcpd.conf
sudo tee /etc/udhcpd.conf > /dev/null <<'EOF'
start 192.168.1.2
end 192.168.1.2
interface eth0
option subnet 255.255.255.0
max_leases 1
EOF
设置串口局域网转发
MCU 通过串口与上位机通讯,需要通过网络把本机串口转发到外挂上位机。此类主板的特点是上位机通过串口通讯与主控板、打印头板、调平小板连接,必要时加上电平转换如 RS232、RS485。
使用的工具是 socat,也可以使用 ser2net。
# 解除本机 klipper 对串口 mcu 的占用
sudo systemctl disable --now klipper
sudo apt install socat
# 创建socat服务模板
# 改成socat_serv_
# serv_socat_mcu.service
# serv_socat_S4_nozzle.service
cat << _EOF_ > /tmp/socat_serv_mcu.service
[Unit]
Description= Start socat (%i)
After=network.target udhcpd
[Service]
Type=simple
User=printer
ExecStart=/usr/bin/socat -d -d TCP-LISTEN:2020,reuseaddr,keepalive,nodelay,forever,ignoreeof,keepidle=60,keepintvl=10,keepcnt=3 /dev/serial/by-id/usb-Klipper_QIDI_MAIN_V2_1.0.4_754E32373534350B34343539-if00,raw,echo=0,clocal=1,cs8,cstopb=0,parenb=0,ignoreeof,nonblock
Restart=always
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
_EOF_
sudo mv /tmp/socat_serv_mcu.service /lib/systemd/system/socat_serv_mcu.service
cat << _EOF_ > /tmp/socat_serv_S4_nozzle.service
[Unit]
Description= Start socat (%i)
After=network.target udhcpd
[Service]
Type=simple
User=printer
ExecStart=/usr/bin/socat -d -d TCP-LISTEN:2021,reuseaddr,keepalive,nodelay,forever,ignoreeof,keepidle=60,keepintvl=10,keepcnt=3 /dev/ttyS4,b500000,raw,echo=0,clocal=1,cs8,cstopb=0,parenb=0,ignoreeof,nonblock
Restart=always
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
_EOF_
sudo mv /tmp/socat_serv_S4_nozzle.service /lib/systemd/system/socat_serv_S4_nozzle.service
sudo systemctl enable --now socat_serv_S4_nozzle.service socat_serv_mcu.service
2.3 摄像头画面转发
使用 crowsnest,没有 GPU,也不支持画面硬件加速编码。允许局域网访问。
sed -i 's/^custom_flags:.*/custom_flags: --host=0.0.0.0/' ~/print_data/config/crowsnest.cfg
2.4 使用 KlipperScreen 取代原厂触摸界面
参考这个教程即可:https://github.com/qidi-community/q2-wiki/blob/main/content/klipperscreen-installation/README.md
修改 KlipperScreen.conf,控制外挂上位机。
三、外挂上位机操作
插上网线后 IP 直接自动分配为 192.168.1.2
3.1 网络串口转发为本地虚拟串口设备
sudo apt install socat
# 测试指令,socat 不支持 250000 buad,直接 raw
/usr/bin/socat -d -d PTY,link=/home/biqu/ttyV0,raw,echo=0,mode=666,waitslave,ignoreeof tcp:192.168.1.1:2020,nodelay,keepalive,forever,ignoreeof,retry=9999,keepidle=60,keepintvl=10,keepcnt=3
/usr/bin/socat -d -d PTY,link=/home/biqu/ttyV1,b500000,raw,echo=0,mode=666,waitslave,ignoreeof tcp:192.168.1.1:2021,nodelay,keepalive,forever,ignoreeof,retry=9999,keepidle=60,keepintvl=10,keepcnt=3
3.2 安装 Q2 版 Klipper
由于so,Python3.9 ,但是我们使用的是Python11
最终方案,使用 KIAUH v6 安装 qidi 版 klipper,使用 Py3.9 创建虚拟环境。
安装 Python 3.9 及依赖
Bookworm 官方源默认无 Python 3.9(仅 3.11/3.12),需通过 deadsnakes 第三方源安装(稳定且安全):
# 0. 必要时使用国内镜像源,如 ustc,目前 Debian Bookworm 的容器镜像和 Debian Trixie 已经使用 DEB822 格式,且其安全更新源默认设置为 http://deb.debian.org/debian-security,因此以上命令会同时替换 Debian 官方源和安全更新源。
# https://mirrors.ustc.edu.cn/help/debian.html#__tabbed_2_2
sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources
# 1. 安装添加源所需的依赖
sudo apt update && sudo apt install -y software-properties-common wget gnupg
# 2. 添加 deadsnakes 源(专为 Debian/Ubuntu 提供多版本 Python)
echo "deb [signed-by=/usr/share/keyrings/deadsnakes-archive-keyring.gpg] https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/deadsnakes.list
# 安装密钥
sudo apt update
# W: GPG error: https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY BA6932366A755776
gpg --keyserver keyserver.ubuntu.com --recv-keys BA6932366A755776
gpg --export BA6932366A755776 | sudo tee /usr/share/keyrings/deadsnakes.gpg > /dev/null
# 3. 更新源并安装 Python 3.9 + venv 模块
sudo apt install -y python3.9 python3.9-venv python3.9-dev
python3.9 -V
KIAUH 使用 Py3.9 创建虚拟环境
kiauh 使用 v6 后,从 shell 切换到 python,初始思路是修改配置脚本,使用python3.9而不是 3.11 重新创建 klippy-env。搜索思路及步骤如下:venv -> create_python_venv (kiauh/utils/sys_utils.py) -> :param use_python_binary: allows to override default python binary
继续搜索 找到这次提交:
以及对应的讨论:Support for low resouces / weird platforms,主要目的:
a) skip installation of
moonraker-speedups.txtdue to limitation of RAM on this platform (the compilation of these dependencies takes ages)
b) be able to define custom python version for klipper (i need to run klipper on python3.8 when the default system python is 3.11)
正好是我们所需的。参考示例配置可知,修改 default.kiauh.cfg 文件,添加以下内容:
# default.kiauh.cfg
[klipper]
repositories:
https://github.com/53Aries/Q2-Klipper/
use_python_binary: /usr/bin/python3.9
[moonraker]
use_python_binary: /usr/bin/python3.9
由此使用 KIAUH 安装 Klipper 时即使用 Python3.9 创建虚拟环境,起迪 Q2 版的 Klipper。
解决报错:
# × Encountered error while trying to install package.
╰─> python-can
# 修改~/klipper/scripts/klippy-requirements.txt
setuptools==58.2.0
# 安装后需要补充py包:
~/klippy-env/bin/python -m pip install pyudev
至此 Q2-Klipper 安装完毕。
3.3 修改配置文件
路径需要是绝对路径,不能使用 ~ 代替 $HOME
[mcu]
serial: /home/biqu/ttyV0
baud: 250000
[mcu THR]
serial: /home/biqu/ttyV1
baud: 500000
3.4 摄像头画面转发
以下使用 nginx 的反向代理功能,将原厂上位机的摄像头画面转发到外挂上位机的 8080 端口。
sudo tee /etc/nginx/conf.d/cam_proxy.conf > /dev/null <<'EOF'
server {
listen 8080; # A的无线网卡监听端口
location / {
proxy_pass http://192.168.1.1:8080; # 转发到B的摄像头服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
sudo systemctl restart nginx
3.5 效果展示

正确连接 MCU 和 THR Toolhead 了。

通讯质量也不错

温度信息已经正常显示

浙公网安备 33010602011771号