给竹子垫高一层,再教它自己开灯
为了给竹子接上 AMS、解决料盘卡料,我搜了一圈,没有找到完全满足要求的现成产品,于是自己画模型、3D 打印,做了一个会看人、会看打印动作、也能远程控制的智控增高架。本文沿着脑图、四根 GPIO 和装配过程讲起,对照早期视频与当前公开固件,拆开灯带计时、MQTT 控制和网页升级,并说明风扇与复刻资料还缺哪些部分。
鸿尘客 Honchic · 机器人开发
这是我的第一个 DIY 作品,算是开端。
当时脑子里突然冒出一个想法:竹子的 AMS 要装到 P1S 上,料盘卡料的问题也一直挂着,能不能给打印机垫一层架子,顺便把它变得更好用一点?
想法有了,我先去搜现成的产品。搜来搜去,没有一款完全满足我的要求,那就自己动手。
我的要求是自己一条条理出来的:架子要能承重,要能封箱打印,四周要有灯,要能联网远程控制,还要能靠红外感知人和打印动作。这些后来都写进了脑图里。
增高架本来是件很朴素的东西。垫高一层,扛住上面的重量,任务就算完成了。
可这一层空间都腾出来了,不往里塞点东西,总觉得有点亏。
于是它多了一圈灯带、两个红外检测模块和一块 ESP-01S。走过去看打印进度,灯自己亮;打印结束,过一会儿自己灭;人不在旁边,也能从手机上给它下指令。
一层垫子,就这样变成了打印机的小中控。
先在脑图里把账算清楚
动手之前,我先开了一张脑图,把这件事拆成功能、硬件、软件三支。视频里能看到,它是一点点长出来的:起初只有三个空分支,后来才填进增高架、人体检测和云端控制。
功能这一支写得很贪心。增高架要承重,要能封箱打印,前后装风扇,四周再绕一圈灯带做顶部照明。电控部分另加三样,人体检测、打印任务检测,还有云端联网控制。
硬件清单倒是不长:
| 部件 | 在这里干什么 |
|---|---|
| ESP-01S 继电器模块 | 主控,负责联网,用继电器开关灯带 |
| 红外检测模块 ×2 | 一个看机外有没有人,一个看机内有没有打印动作 |
| COB 灯带 | 环绕增高架一圈,做顶部照明 |
| 静音风扇 ×6 | 前后通风,为封箱打印准备 |
| USB 转端子线 | 取电接线 |
| 自锁 LED 按钮 | 风扇总控开关 |
主控选 ESP-01S,理由也写在制作流程里:利用它的四个小端口,同时完成外部人体检测和内部打印动作检测。整块模块能拿来干活的 GPIO 就四根,要接一路继电器、两路红外,还想给风扇留个位置。
四个小端口,极限压榨。
四根 GPIO,一根不剩
当前仓库的固件里,四根引脚是这样分的:
| 引脚 | GPIO | 用途 |
|---|---|---|
RelayPIN | GPIO2 | 继电器,开关灯带 |
Relay2PIN | GPIO0 | 预留的第二路继电器 |
TXDPIN | GPIO1 | 机内红外检测,占用串口 TX |
RXDPIN | GPIO3 | 机外人体红外检测,占用串口 RX |
灯带继电器按低电平开、高电平关来控制,固件运行起来后会先拉低 GPIO2,让灯亮起来。复刻时要先核对自己手上模块的触发电平。
ESP-01S 的这几根脚,每根都有自己的本职工作。
GPIO0 和 GPIO2 跟启动有关。上电那一刻,它们的电平参与决定芯片怎么启动,正常从 Flash 运行,需要两根都是高电平;GPIO0 被拉低,芯片就进了下载模式,乖乖等人烧录。
GPIO1 和 GPIO3 原本是串口的 TX、RX,烧录固件、打印日志都走它们。拿来读红外,串口调试就得让一让路。视频里的代码用Debug开关控制部分串口打印。当前仓库只屏蔽了部分调试日志,仍会初始化串口、输出连接信息,不能把这个开关当成串口已经彻底空出来。
复刻时可以记两件小事。烧录或者看串口日志前,先把接在 GPIO1、GPIO3 上的红外模块断开,免得它们和串口抢线。接在 GPIO0、GPIO2 上的模块,也要确认上电时不会把引脚拉低,否则板子可能卡在启动阶段,看起来像是坏了,其实只是没起来。
第二路继电器留在 GPIO0。视频里风扇还没装,电路图先把端口留了出来。
灯什么时候亮,听谁的
一圈灯带,一个继电器,听起来很简单。麻烦的是规矩。什么时候该亮,什么时候该灭,几路信号一起来了,到底听谁的。
脑图里的软件那一支,我先写了五条设计规则。灯带和红外先做起来,风扇那两条留给后面的安装与控制补齐:
- 云端下发指令时,自动检测全部停下。
- 有打印任务时,灯带自动打开,打印完成后延时关闭。
- 没有任务时,灯带默认关着,感应到有人才亮,延时后自动关闭。
- 自锁按钮打开后,风扇才加入自动检测,否则风扇全关。
- 风扇加入后,有任务时自动开启,打印完成后自动关闭。
第一条放在最前面。如果手机上点了「开」,灯却因为没检测到人又自己灭掉,云端那一下就白点了。这张脑图和下面的示意图,画的是我想要的控制顺序。
当前固件的接管方式还要分开、关来看。收到on后,灯持续亮着,自动检测暂停;收到off后,灯先关闭,同时恢复自动检测。随后红外再次触发,灯仍可能亮起来。远程关灯不会一直锁住关闭状态。
脑图里「没任务时默认关灯」也是目标规则。当前代码上电先亮灯,再进入检测和计时逻辑,启动时的表现要分开看。
两个红外的分工很明确。机外那个看人,有人走近就亮灯。机内那个看打印动作,里面一直在动,就当作有任务在跑。
它没有去读打印机的任务状态,靠的是机内那个红外模块。代价是它只认动作,两次动作之间隔得久一点,它分不清机器是在歇口气还是真的打完了。关灯前留一段延时,就是给这种间隙留的余量。
延时多长,脑图里一开始写的是 10 秒,后来改成了「XX 秒」,留给调试再定。视频里的早期版本写得很直接,检测到信号就拉继电器,delay(10000)等上 10 秒,再切回去。
delay()写起来省事,代价是整个循环在这 10 秒里停住。早期版本把 MQTT 消息处理排在检测后面,这段时间轮不上它,云端发来的指令只能等着;两路检测接连触发,等待还会叠加。
当前仓库已经把这两段长等待改成了millis()计时。每一圈记下现在的时间,再跟上一次动作的时间比较,主循环继续往下跑。
| 当前固件的检测逻辑 | 动作与等待条件 |
|---|---|
| 机内红外有动作 | 开灯,刷新机内计时,并清空机外计时 |
| 机内最后一次动作后满 30 秒 | 才进入机外人体检测与关灯判断 |
| 机外红外有动作 | 开灯,刷新机外计时 |
| 已进入机外判断,机外最后一次动作后满 20 秒 | 关灯;若机外从未触发,也关灯 |
这两个时间是代码中实际比较的数值,不是简单把 30 秒和 20 秒相加。两路检测还各留了 50 毫秒的消抖等待,所以它去掉了原先的 10 秒阻塞,但还没有完全消除短暂停顿。
从一块板子,到一层架子
规矩定好,下面就是动手开干。
先建模。板子上阵列了一排长条通风槽,一格一格排得整整齐齐。
模型画完,零件交给 P1S 自己打。打印机给自己打增高垫,这活儿它干得倒是一点不含糊。
然后是代码框架和电路图。再然后,就是接线、调试、接线、调试。
灯带沿着增高架内圈贴了一整圈,装回打印机上点亮,打印区域一下子亮堂了。
ESP-01S 继电器模块这个小中控,我给它做了个磁吸架,藏在打印机侧边。
视频里,装好后又测了一轮。机外检测正常,机内检测正常,云端控制也正常。
云端那一路
视频里录的这一版,云端接的是阿里云物联网平台。
代码按平台规则拼出属性主题,设备订阅/sys/{PRODUCT_KEY}/{DEVICE_NAME}/thing/service/property/set。消息到了,先用 ArduinoJson 解析,再从params里取出开关状态,写给继电器。上报用的.../thing/event/property/post主题也一并定义好了。
测试时,我在手机上打开物联网平台的调试页,找到「智能灯开关」,点一下设置,灯带就跟着亮了。
视频记录的是早期阿里云版本。后来代码接入了自建 MQTT、微信小程序和 Home Assistant,现在公开的DIY_3DPrint_Parts仓库保存的是这一版。两条链路分开看,视频中的阿里云主题不能直接拿来控制当前固件。
自建 MQTT 版的客户端 ID 是3D_Print,主题也重新起了名字:
| 主题 | 方向 | 内容 |
|---|---|---|
3D_client/sub | 设备发布 | 上报继电器状态 |
Wechat/pub | 设备订阅 | 微信小程序的控制指令 |
HA/3D_Control | 设备订阅 | Home Assistant 的控制指令 |
固件每 5 秒上报一次继电器状态。灯开着时,数据长这样:
{"info":{"name":"3D_Print"},"param":{"relay_pin":"on"}}关灯时,relay_pin的值换成off。这个值来自 GPIO2 的电平,表示控制输出的状态,不是灯带是否真的发光,也不是打印机的任务状态。
小程序控制使用info.name和equipment.switch1。一条开灯消息可以这样写:
{"info":{"name":"Wechat"},"equipment":{"switch1":"on"}}关灯时把switch1改为off。协议里也留了info.time,但当前代码没有用它判断消息先后或重复。Home Assistant 那一路更省事,消息体直接发on或off。两个入口的格式不同,发错主题或消息结构,不能指望设备猜出你的意思。
这份代码用 PlatformIO 管理,platformio.ini定义esp01_1m环境和 Arduino 框架,库依赖约束为 ArduinoJson^7.0.3、PubSubClient^2.8。具体控制逻辑集中在src/main.cpp。
Wi-Fi 与 MQTT 服务配置也写在这个文件里。当前代码会调用WiFi.config(...)使用静态 IP,换网络时要一起检查设备 IP、网关、子网和 DNS,不能只改 Wi-Fi 名称与密码。
代码还接入了ESP8266WebServer和网页 HTTP OTA,默认升级入口在设备本地 IP 下的/update。先通过串口烧好固件、让设备连入局域网,再从浏览器上传新的固件文件,才有机会少拆一次藏在侧边的小盒子。
MQTT 连接使用 1883 明文端口,当前connect()调用只传客户端 ID,没有传用户名和密码;网页升级也没有设置登录凭据。复刻时要改成自己的配置,认证需要补进连接代码,不能只在服务端设密码。
网络部分还写了断线重连和约 48 小时自动重启。这里也留着需要继续打磨的地方:MQTT 重连会反复等待 broker,连不上时后面的检测和网页服务也会等;控制主题只在启动时订阅,重连后还需要重新订阅。定时重启接上了,长期稳定性仍要靠设备运行来检验。
想先把固件跑起来
可以先从灯带和两路检测开始,把最小的一圈接通,再考虑风扇。当前公开仓库收录了电控固件,增高架模型、电路源文件和完整物料规格还没有放进去;文章里的部件表和视频截图能帮助理解,但还不是一套完整的复刻资料。仓库也未附许可证,使用范围需要另行明确。
- 用 PlatformIO 打开仓库根目录,选
esp01_1m环境。 - 在
src/main.cpp中换成自己的网络与 MQTT 配置,再核对继电器触发电平和两路传感器的信号。 - 编译后用自己的串口烧录器首次上传。烧录时断开 GPIO1、GPIO3 上的红外模块,按 ESP-01S 的下载模式连接 GPIO0,烧录后再恢复正常启动接线。
- 分别验证机内动作、机外人体检测、MQTT 开关与恢复自动的行为,再试设备本地的
/update页面。先确认灯带控制符合预期,再继续扩展。
工程的编译与串口上传命令是:
pio run-eesp01_1m pio run-eesp01_1m--targetupload串口上传还需要实际烧录器、供电和正确的下载模式接线。这两行命令不会替你把线接好。
风扇的位置,先空着
六个静音风扇和那颗自锁按钮,是为夏天准备的。脑图里写着「夏天就可以愉快的封箱打印 PLA 材料啦」,风扇就是为这一句准备的。
视频里,风扇这一路还没装。位置、端口和设计规则先留着,当前固件也仅声明了 GPIO0 这根预留脚,没有初始化风扇输出,更没有自锁按钮和风扇的控制逻辑。后面要补的是供电、接线和代码,不只是把六个风扇拧上去。
脑洞先落地,细节慢慢打磨。增高架里的位置,先给它留着。
AMS 最后稳稳坐了上去。我用它打了一块多色的磁吸封箱板,吸在正面,顺手把多色打印也测了一遍。
一开始,只是想给 AMS 垫高一层。
现在这一层会看人,会看打印机,也听手机的话。走过去,灯亮了。走开一会儿,它自己熄掉。
灯先亮起来了,风扇的位置还给下一步留着。
鸿尘客 Honchic · 把脑洞焊到电路板上