大概是这个东西

《摆》,节点各自摆动
作品名称:《摆》 作者:卿雨竹、李哲宇、柴云青、杨文琪、陈茁、郑豪 类别:装置 尺寸:1000cm × 30cm × 150cm 材料:PCB(印制电路板)、铝型材、LED 数码管、单片机、舵机、深度相机 创作年份:2023 年
之前装置在供电和通信上都有比较大的问题。供电上发现舵机和单片机共享5v电源线,会在高负载时候拉低电压导致单片机断电。然后在展厅的复杂环境里 WLAN 控制不够可靠。接手的时候,舵机是老的,esp32是老的,数码管和 74HC595 是焊死在板子上的,几乎没有资料,隔着阻焊看铜线。改新PCB太麻烦了,于是暴力加电源解决了供电问题,然后下文说软件问题。
代码在 f4bb0/Pendulum0,只有三个文件:PC 端的 control.py(协议与动作生成)、cam.py(摄像头交互)、节点固件 Pendulum0.ino。
系统大概长这样,测试规模为24个,理论支持120个设备
PC (Python) ──UDP 广播 :4210──▶ 24 × ESP32 节点
│ ├─ 舵机 (50Hz, 500–2500us)
└─ USB 摄像头 (cv2) └─ 3 × 74HC595 → 三位数码管设计了一个协议:
节点之间不通信,也没有主从握手,PC 直接往局域网 UDP 广播
Magic(1) | StartID(1) | Cmd(1) | Len(1) | N × [v1(2) v2(2)] | Checksum(1)
0xAA 起始 ID 0x01.. 4N 大端 uint16 sum & 0xFF三个命令:
| 命令 | v1 | v2 |
|---|---|---|
0x01 SET_BASIC | 舵机角度 0–360 | 显示值 0–999 |
0x02 SWING | 摆动速度 0–999 | 显示值 0–999 |
0x03 SWING_LIMIT | 最小角度 | 最大角度 |
其中,设备 ID 是隐式的。包里不写 24 个 ID,只写起始 ID,第 i 块数据属于 StartID + i,节点比对 MY_DEVICE_ID 决定要不要处理这一块。于是"只动 3–7 号"和"全部一起动"是同一个函数,只改参数。
一个包最多带 120 个设备的数据(udpBuffer 是 512 字节),24 个节点的完整状态是 101 字节。这样每个包都有所有设备的控制代码,每个设备解析自己需要的部分。包控制在比较小的尺寸,所以能达到比较高的帧率。无连接则保证稳定性,不过还是不能排除 wifi 直接断开的情况,这时候就会触发重连,乱动一下。
摄像头识别则写得相当简单。只是连续三帧找运动像素,然后映射成摆动速度。已经有不错的互动效果。
最后控制软件有相当好的可靠性。不过我写的有不好的地方:没有任何反馈。时间上不是严格的。MY_DEVICE_ID 是 #define,24 块板子要编译上传 24 次固件。

