前言
3D打印机一般有两种玩法,一种是让3D打印机成为一种生产力工具,打印各种好玩的模型;另一种是玩3D打印机本身,包括改造3D打印机,优化3D打印机,尝试各种不同类型的3D打印机,甚至是从零DIY一台3D打印机。目前国内3D打印机厂商中,拓竹可谓一枝独秀,其产品虽然价格较高,但是打印速度和打印质量令人惊叹。身为拓竹P1P的用户,对这一点是深有感触。拓竹P1P可以稳定且高效地成为我的生产力工具,也就让我有机会去体验3D打印机的另外一半乐趣——DIY 3D打印机。
DIY 3D打印机的难度,应该是普通人能够理解并完成的上限。就是说,一般人,可能不需要太多专业知识,凭借网络上丰富的资料以及各种淘宝上随手可得的标准套件,只要有耐心,是可以成功组装出一台3D打印机的。目前最流行的高性能3D打印固件,应该就是klipper了。一台基于klipper的3D打印机,不但拥有作为各种电机、传感器驱动核心的下位机控制器,也有承担复杂运算、提供可视化UI界面的上位机。下位机就像是3D打印机的心脏,一般是基于STM32的嵌入式开发板,而上位机则是一台基于Linux的电脑,只要能够和下位机通过USB连接进行串口通信即可。
(相关资料图)
大部分玩家在组装3D打印机的时候,一般会选择树莓派或者同等算力的开发板作为上位机。有的为了节约成本会选择电视盒子、旧手机等等。NAS本质上也是一台基于Linux的电脑,也有USB接口,据我了解,NAS玩家和3D打印玩家有着相当高的重合度,那么使用NAS作为3D打印机的上位机也是一种不错的选择,只要NAS和3D打印机留有合适的放置空间即可。
QNAP NAS安装Klipper
本文所介绍的方法是基于威联通的X86平基于台的NAS设备,其他品牌和架构的NAS不一定适用。威联通的操作系统QTS是Linux的,但是Klipper并不能很方便地直接安装在QTS上,虽然理论上是可行的。那么要安装Klipper,想到的自然是基于虚拟化的方案了。这时候,威联通的三大虚拟化解决方案:Container Station、Ubuntu Station以及Virtualization Station就可以派上用场了。
方案选择
一般情况下,大多数用户会选择使用Container Station,因为这是最轻量级的方案,而且目前也有现成的docker镜像可以选择(https://github.com/dimalo/klipper-web-control-docker),但是却存在无法编译Klipper下位机固件、无法方便地升级等问题。排除Container Station,可能就要考虑Ubuntu Station,虽然略重量级,但好在运行效率高。不过我尝试下来,下位机连接到NAS上后,USB串口的在Ubuntu Station的穿透有一些问题,导致Klipper无法访问到串口。那么最后的选择只有Virtualization Station,虽然不但重量级且效率略低,但是我这台TS-464C性能还是可以的,没有很大压力。不过Virtualization Station安装Klipper后,也会存在USB无法自动分配到虚拟机的问题,好在这个是有解决办法的。Linux系统安装
下面,就详细地讲述一下如何在Virtualization Station上安装Klipper,以及问题的解决方法。第一步肯定是在虚拟机上新建一个Linux实例。
关于Linux发行版的选择,一般人都会选择Ubuntu。不过我为了稍微节约点系统资源,选择了基于Ubuntu的轻量级版本Linux Lite(https://www.linuxliteos.com/download.php),用起来和Ubuntu没有太大差别。Linux Lite的安装步骤就不再赘述了,都是基本操作,耐心等待一段时间就行。
系统安装完成后首先要做的就是替换掉官方的软件源,以加速软件的下载安装。最新的Linux Lite 6.4是基于Ubuntu 22.04的,因此软件源的替换方法也和Ubuntu 22.04一样,按照步骤输入以下几条命令。
备份官方的软件源,执行以下命令
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
替换为清华大学ubuntu 22.04镜像:
sudo bash -c "cat << EOF > /etc/apt/sources.list && apt update deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiversedeb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiversedeb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiversedeb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverseEOF"
由于后续要安装的软件很多都是基于Python开发的,因此也需要替换Python的pip源,按照步骤输入以下命令即可。
mkdir ~/.pip
打开配置文件 ~/.pip/pip.conf,修改如下:
[global]index-url = https://pypi.tuna.tsinghua.edu.cn/simple[install]trusted-host = https://pypi.tuna.tsinghua.edu.cn
Klipper安装
基本工作准备完毕了。接下来要安装Klipper,我们这里需要借助kiauh这个自动化安装脚本。有了这个脚本,安装依赖、下载软件、配置服务都不需要过多干预,全都集成在脚本里面了,用起来很方便。kiauh脚本的代码托管在github上,所以需要首先安装git工具。
sudo apt-get install git -y
然后使用下面的命令将kiauh下载到用户目录。
cd ~ && git clone https://github.com/th33xitus/kiauh.git
最后直接运行脚本即可。
./kiauh/kiauh.sh
接着我们需要根据弹出的菜单提示选择要安装的软件。这里,我们需要安装三个软件:Klipper、Moonraker以及Fluidd。如何理解三者的关系呢:Klipper是3D打印机的固件,Moonraker是基于Python开发的web服务,可以和Klipper交互并提供Apis,Fluidd是web UI前端,利用Moonraker提供的Apis间接控制Klipper,以图形化的方式操作和监视3D打印机。
有了kiauh,这些软件的安装会变得异常简单,唯一的拦路虎可能就是网络问题导致的github访问不畅。解决方法要么挂梯子,要么多试几次即可。按照顺序,我们依次安装Klipper、Moonraker以及Fluidd。根据需要,你还可以将Fluidd替换成另外一个前端Mainsail,如果打印机有屏幕,还可以选择继续安装KlipperScreen。
软件安装配置完毕后,使用虚拟机的IP直接访问,不出意外就能看到Fluidd的页面了。
针对不同的3D打印机硬件配置,我们还需要为下位机编译固件,烧录固件,以及在Fluidd中进行详细的配置。关于这部分,每台打印机都不尽相同,且不在本文的重点讨论范围,因此就略过了。我当前的情况是下位机固件已经烧录好,且已经有了正确的配置文件。这时,因为NAS还没有连接下位机主控板,所以还看不到3D打印机设备。用USB连接NAS和下位机主控板,此时QTS应该是可以直接识别到下位机的。如果想让虚拟机识别到下位机主板,需要手动将USB设备直通到虚拟机里面。
这样,虚拟机里面就能看到这个设备了。把设备路径配置到Fluidd的配置文件中,Fluidd也能正确识别到3D打印机主控板了。
USB自动挂载
这时会有一个问题,如果3D打印机主控板下电了,USB设备是不会自动加载到虚拟机里面的。如果不嫌麻烦的话,就需要每次手动点击一下,但这样做显然太不优雅了。如果可以做到插入指定USB设备,就能将这个设备自动加载到指定的虚拟机中,那么一切就很完美了。
为了解决这个问题,下面,是时候秀一些小技巧了。首先ssh登录到NAS终端,3D打印机上电,下位机主板连接到连接到NAS,输入lsub查看新插入的设备,记下设备的vendor id和product id。比如我这里是这样的结果。OpenMoko是新插入的设备,1d50是vendor id,614e 是product id。
[~] # lsusbBus 001 Device 002: ID 0463:ffff MGE UPS Systems UPSBus 001 Device 003: ID 1d50:614e OpenMoko, Inc. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
新建一个文件mount.xml,输入以下内容,关键是vendor id和product id。文件创建在任意共享目录即可,要记得这个路径。
<hostdev mode = "subsystem" type = "usb" managed = "yes"> <source> <vendor id="0x1d50"/> <product id="0x614e"/> </source></hostdev>
接着,在Virtualization Station中查看当前运行的Linux虚拟机实例的uuid,记下这个值。
在虚拟机实例正常运行的情况下,在NAS终端中输入以下命令:
/QVS/usr/bin/virsh attach-device your_uuid /share/Share/mount.xml
此时回到你的Linux虚拟机终端中,查看一下USB设备是否能够正确加载。如果能够正确加载,那么你就成功了一半了,当前至少证明了是可以通过命令行将USB设备直通到虚拟机中的。将上面的命令复制到新的脚本文件mount.sh中。
#! /bin/sh -xexport LD_LIBRARY_PATH=/QVS/usr/lib:/QVS/usr/lib64/ export PATH=$PATH:/QVS/usr/bin/:/QVS/usr/sbin//QVS/usr/bin/virsh attach-device your_uuid /share/Share/mount.xml
并赋予脚本可执行权限
chmod +x /share/Share/mount.sh
那么接下来要解决的就是插入USB设备后,自动直通到虚拟机中。回到NAS的终端里面,输入命令。
udevadm monitor --env
插拔下位机的USB线,此时会有很多内核udev事件上报,记下对应的add事件的DEVPATH。事件信息输出类似下面。
UDEV [17933.644086] add /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0 (usb)ACTION=addDEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0DEVTYPE=usb_interfaceINTERFACE=2/2/1MODALIAS=usb:v1D50p614Ed0100dc02dsc00dp00ic02isc02ip01in00PRODUCT=1d50/614e/100SEQNUM=2783SUBSYSTEM=usbTYPE=2/0/0USB_1_2=UPS_HIDUSEC_INITIALIZED=17933635952mmc0_0001=root_bootsg0=rootsg1=rootsg2=rootsg3=root
新建文本文件99-usbshare.rules,填入以下内容。不要照抄,你的DEVPATH可能不同。
ACTION=="add",DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0",RUN+="/share/Share/mount.sh",OPTIONS+="last_rule"
然后再新建一个脚本autorun.sh,填入以下内容:
#! /bin/shcp -f /share/qnap/99-usbshare.rules /lib/udev/rules.d/udevadm control --reload-rulesudevadm trigger
这里简单解释一下这些命令和文本文件的作用。首先99-usbshare.rules里面配置的规则是,如果有Action为add,且DEVPATH为指定内容的udev事件上报,就执行mount.sh在虚拟机中挂载这个设备。autorun.sh的命令会将99-usbshare.rules这条规则放到指定目录,并通过udevadm相关命令重新加载这条规则使他生效。那么现在我们给autorun.sh这个脚本赋予可执行权限并运行它。然后尝试拔下并插入USB,进入虚拟机的Linux终端查看,应该可以直接看到响应的设备节点了。
chmod +x /share/Share/autorun.sh
最后一步,是将autorun.sh这个脚本也可以开机自动运行,这样以后重启NAS,也能使通过USB插入到NAS的下位机主板自动加载到对应的虚拟机中,一切一劳永逸,完美无缺。我们还需要进行以下步骤。在NAS终端中运行下面的命令。
mount $(/sbin/hal_app --get_boot_pd port_id=0)6 /tmp/configcp /share/Share/autorun.sh /tmp/configumount /tmp/config
然后再NAS控制台--系统--硬件里面,启用启动时用户自定义进程。
这样,Klipper及其配套软件就可以在NAS中完美运行了。进入Fluidd检查一下3D打印机状态,然后装载耗材,尝试打印一个模型吧。
3D打印机和NAS展示
看了太多的软件部分,下面来秀一下我的硬件:两台3D打印机和一台威联通NAS。第一台3D打印机是拓竹P1P,也是我目前最主要的3D打印生产力工具。作为当前拓竹科技旗下最低端的产品,放在当前消费级成品3D打印机市场,也可以说天花板的存在了。拓竹P1P的打印速度和打印质量让我十分满意,有时候机器飙起来晃的跟洗衣机一样,依然不会影响成品的打印质量。这就是优秀的结构设计和优秀的软件算法结合的魅力。
第二台3D打印机是我自己DIY的Voron 0.1,也是本文用于验证NAS上安装Klipper可行性所使用的3D打印机。这台机器我是直接购买了套件,然后按照官方说明书一点一点拼装、拧螺丝、接线、焊接、安装配置软件,花费了好几个晚上组装完成的。我个人还是非常喜欢这台Voron 0.1的。毕竟是自己从零开始打造的。虽然Voron 0.1打印尺寸不打,打印速度我没有深度调试也不算太高,但是全CNC机身加上酷炫的造型,当个桌面摆件还是很不错的。
最后再说说这台QNAP TS-464C NAS,这时我新升级的NAS设备,以后也会作为我的主力NAS使用。TS-464C采用N5095处理器,4个核心4个线程,最大频率为2.90GHz的时钟,单核性能、多核性能以及核显性能都还不错。搭载8GB LPDDR4X 2933双通道板载内存,虽然失去了扩展行,但是8GB得容量跑一个虚拟机加上几个Docker是没有什么压力的,目前我也是这样使用的。
4个3.5寸硬盘插槽加上两个M.2硬盘插槽,配置上还算良心。内置的2个M.2 2280 PCIe Gen 3 x2 插槽,可支持双M.2 NVMe SSD,可启用快取,提升数据运算能力及存取性能;也可搭配 Qtier启用自动分层存储技术,将存储空间效率发挥地淋漓尽致。
其他接口方面,前后各一个 USB 3.2 Gen 2 端口,背面还有一个USB 2.0端口。一个HDMI 2.0 端口,最高可支持4096 x 2160 @ 60Hz视频输出,打造HTPC必备接口。双2.5GbE接口网络传输,可支持链路聚合(Port Trunking),实现高达5Gbps的传输带宽。
目前威联通也刚刚发布了基于N6005的新品TS-466C,但是相比N5095性能提升不大。在威联通推出N100系列NAS新品前,这台TS-464C我估计还能用上挺长一段时间。
后记
在虚拟机上部署Klipper其实并不是一件很难的事情,毕竟只要使用kiauh和解决网络问题,这一切都会变的很简单。使用虚拟机部署Klipper的难点在于如何解决USB插拔后设备在虚拟机中挂载的问题。虽然威联通的Virtualization Station提供了UI菜单可以手动执行USB挂载,但这显然太不方便了。为了解决这个问题,搜遍中文网站也没找到答案,甚至用NAS部署Klipper的文章都很少。最终我在Google上使用英文搜到了一些线索,并成功解决了这个问题。所以姑且算是国内首创吧。如果你不想额外购买上位机,比如树莓派、香橙派等,也不想使用廉价的电视盒子、红米手机折腾,刚好你手头有一台可以使用虚拟机的NAS,那么不妨试试在这个上面部署Klipper吧。如果你连3D打印机都没有,那么就早点入坑3D打印吧,真的很有趣。