使用ESP32-C6和毫米波雷达构建智能楼梯灯
这个概念虽然简单却十分有趣:两台毫米波雷达检测到人的移动方向,楼梯灯则像流水一样依次亮起,从下往上或从上往下依次闪烁。
原始项目围绕 Home Assistant 构建,包含完整的自动化设置和教程。
我的第一反应是:
我也想建一个。
然而,没过多久我就意识到,我不想完全复制原来的样式。
为什么我没有选择Home Assistant
原因其实相当简单。
尽管 Home Assistant 是一个功能非常强大的平台,但它并不完全适合我的环境。
我住在一套相对较小的公寓里,设备都集中在一起,因此我通常更倾向于选择轻量化的独立系统,而不是维护一个庞大的智能家居生态系统。
还有一个实际的网络考虑因素。
我主要依靠移动网络,不想为楼梯照明系统额外建设网络基础设施。
与此同时,这两个雷达节点仍然需要一种无线通信方式。
这最终让我走向了ESP-NOW。
事实证明,ESP-NOW 对这类项目几乎再合适不过了:
•无需路由器
•无云依赖
•低延时
•直接点对点通信
•轻量,适合嵌入式系统
系统架构
该系统由以下部分组成:
•雷达检测到移动或人体存在
•位置信息通过ESP-NOW传输
•系统确定行走方向
•LED状态机执行动画
•灯光短暂亮起后逐渐熄灭
与基于云的智能家居解决方案不同,所有功能均在本地运行。
这使得响应延迟极低,同时无需依赖Wi-Fi基础设施。
硬件选择
电力系统
电源供应被证明是整个项目中最重要的部分之一。
我并没有直接用ESP32为LED灯带供电,而是使用了之前我协助设计的LED驱动板作为电源基础。
电力系统的设计基于以下要求:
•12V 输入
•12V稳定输出,适用于LED灯带
•用于控制电子设备的稳定5V输出
•独立LED电源供电
这使得ESP32-C6能够完全专注于逻辑处理和通信,而无需处理LED的电流负载。
我之前用过这个驱动板,制作了一些外观相当不错的演示效果,它既用户友好又非常稳定。所以这次我打算再次使用它来制作我的LED灯。
雷达传感器
与原作者的楼梯照明项目类似,我选择了毫米波雷达,而非更简单的PIR传感器。然而,我选择LD2410C雷达,原因如下:
•静态人体检测
•更好的灵敏度调节
•蓝牙支持
•OTA 固件更新
•官方配置应用
•为未来实验提供更大的灵活性
与PIR传感器相比,LD2410C显然更适合用于响应式室内交互系统。
第一个原型
原型有意地设计得简单。
现阶段,唯一的目标是:
•雷达能否直接控制LED灯带?
•软件架构非常简洁:
•查看雷达状态
•判断某人是否在场
•打开或关闭LED灯
一切仍然以简洁的程序化风格编写。
尽管这个阶段十分简单,但它极为重要,因为它验证了:
•雷达通信
LED控制
•人体存在检测
•静态目标检测
项目第一次感觉到了真实。
添加ESP-NOW通信
下一步是建立两个ESP32-C6节点之间的ESP-NOW通信。
这正是项目从单设备原型发展为分布式系统的关键阶段。
下层雷达节点发送了:
•目标状态
•距离
•雷达模式
•与运动相关的数据
上层节点随后结合本地和远程雷达信息,以确定行走方向。
起初,大多数挑战看起来都可掌控:
•枚举类型转换
•ESP32 Arduino 核心 API 变更
•ESP-NOW 回调更新
•结构同步
烦人,但可以解决。
真正的挑战后来才出现。
系统开始变得不稳定时
随着功能的不断增加,该软件逐渐变得难以管理。
主循环逐渐演变为以下组合:
•雷达测距
•通信处理
•动画逻辑
•方向检测
•超时管理
•串行调试
•状态追踪
而且,不可避免地:
•延迟()
•嵌套的if语句
•重复的逻辑
•阻塞动画
开始出现在各个地方。
令人沮丧的是,每个独立模块都能单独正常运行。但一旦所有模块协同工作时,就出现了奇怪的行为:
•方向检测错误
•随机触发器
•口吃动画
•灯不关掉
•时间冲突
起初我将问题归因于硬件不稳定或ESP32库的问题。
最终我意识到,真正的问题其实是另一回事。
是建筑本身。
理解真正的问题
我注意到,许多之前的项目中都存在一个模式:一旦多个模块开始相互作用,整个系统就会变得脆弱。问题并不在于某个具体的功能,而在于所有内容都封装在 loop()() 函数内部。
一切皆由其他一切决定。长时间的延迟阻碍了通信,动画时间影响了传感器轮询,状态逻辑也变得紧密耦合。
项目发展到一个阶段,新增功能比实现现有功能还要困难。于是,我决定彻底重新思考软件架构。
迁移到 FSM FSM 架构
我并未将项目视为一个大型程序,而是将其拆分为多个独立的有限状态机。最终架构演变为三个主要子系统。
雷达 FSM
仅负责:
•读取雷达传感器
•去抖传感器数据
•生成稳定的在场快照
Passage FSM
仅负责:
•确定行走方向
•跟踪通过状态
•生成灯光活动
LED FSM
仅负责:
•运行动画
•渲染LED效果
•管理动画时间
与此同时,loop()() 函数本身不过是一个调度器:
这成为该项目最大的转折点。
突然,系统变成了:
•可预测的
•稳定
•调试更简单
•更容易扩展
最重要的是:
模块终于不再相互干扰了。
自然出现的新功能
一旦架构稳定下来,许多之前觉得难以实现的功能突然变得容易了。
入口预览照明
当有人靠近楼梯时,系统不再立即点亮整个楼梯。
相反,检测到的入口附近的前10个LED会先亮起。
它营造出一种更加自然的体验。
楼梯似乎能察觉到你的存在。
定向流动动画
一旦两个雷达节点都确认了行走方向,LED灯便会相应地亮起:
•上楼时从下往上走
•下楼时从上到下
这是启发该项目的原始视觉效果。
楼梯占用保持
如果有人在楼梯上停下,灯就会一直亮着。
系统不会因为动画已经结束而立即强制超时。
延迟关机
当楼梯空置时,灯光会保持开启一段时间,之后自动关闭。
这能带来更加流畅的用户体验。
雷达去抖
即使是毫米波雷达传感器,也会偶尔出现波动。
为了提高可靠性,我引入了去抖机制:
存在状态只有在保持稳定一段预定义的时间后,才被视为有效。
这最终成为保障系统整体稳定性的主要因素之一。
最终,我开始重新设计硬件。
软件架构稳定后,另一个问题变得越来越明显:
目前,这个系统看起来更像是一个临时搭建的实验室,而非一个完整的项目,而且摆放在楼梯上显得不太美观。此外,任何使用过XIAO的人都知道,按钮实在太小了。每次调试、固件更新或硬件修改都变得越来越麻烦。
最终,我将整个系统重新设计成一块专用的PCB。幸运的是,Seeed提供了一个与XIAO兼容的毫米波雷达模块。经过测试后,我发现其功能与LD2410C非常相似。Seeed开源的电路图提供了极大的帮助。
但一开始,我并不是要设计一个全新的电路板。而是从一个现有的LED驱动板设计开始。我的目标很简单:
减少布线,将所有功能集成到一块板上。
这实际上是我的第一次定制PCB设计。我对LED驱动板做了一些实际的改进:
•XIAO ESP32-C6 集成
•雷达接口
•光传感器集成
•扩展 GPIO 接头
Boot按钮暴露在外部,无需再通过XIAO模块上的小按钮进行操作。
未使用的GPIO将被连接到边缘引脚,以便未来扩展。
乍一看,这些变化似乎很直接。
他们不是。
了解每个组件的实际功能
我很快发现的一个问题是,我对原始LED驱动电路的许多部分并不完全理解。
在修改任何内容之前,我必须倒推回去,弄清楚每个组件存在的原因。
对于每一个不熟悉的部件,我发现自己不断反复地问:
•这部分有什么作用?
•为什么在这里?
•如果我把它移除会发生什么?
•它的位置重要吗?
这一过程最终发展成一个个人的硬件知识库,我在其中记录了PCB设计的概念、布局实践以及常见的错误。
我不想盲目地复制电路,而是想理解它们。
只有在理解了原始设计之后,我才能自信地开始对其进行修改。
当电路图完成后……我以为自己已经完成了
和许多初学者一样,我一开始以为完成原理图就代表辛苦的劳动结束了。然后我打开PCB布局编辑器,立刻意识到自己错了。
原理图看起来整洁有序,而PCB板却像一团乱糟糟的:线路到处交叉,元件似乎无法合理布局,完全不符合我的想象。
我第一次尝试使用自动路由器,软件虽然技术上连接了所有设备,但结果看起来非常糟糕。
一些边缘连接器最终靠近电路板中心,电源走线横跨整个PCB,信号路径走着奇怪的路线,电路板虽然实现了电气连接,但这并不是我真正想制造的设计。
最终我删除了大部分路由,然后重新开始。
一次只留下一条痕迹。
每个部件都有其独特的个性
让我感到意外的一点是,PCB设计不仅仅是将引脚连接起来。不同元件对布局的要求差异很大。
原理图告诉你哪些部分需要连接,而PCB布局则决定了这些连接是否真正能良好工作。
例如:
输入保护组件
保险丝、反向极性保护二极管和TVS二极管应尽可能靠近12V电源输入端安装。
他们的工作是在电气问题扩散到电路板其他部分之前,阻止这些问题的发生。
如果放置得太远,它们的效果就会显著降低。
开关电源组件
5V开关稳压器所使用的电感行为差异很大。
它承载的电流相对较大,会产生电磁噪声。
正因如此:
•痕迹应短而宽
•应避免靠近敏感电路
•周围区域应保持相对清晰
忽略这些建议可能会导致电路板出现不稳定和噪声。
敏感控制电路
与此同时,用于电压调节的小型电容和反馈元件也有其自身的要求。
这些部件应靠近调节器IC。
长距离信号可能导致噪声并降低调节性能。
我学得越多,就越意识到PCB布局几乎是一种物理工程逻辑。
原理图定义了关系。
布局定义行为。
为高温而设计
另一个挑战是热管理:LED系统可能消耗大量电流。即使在电气方面一切正常,过热也可能成为长期可靠性问题。
在设计的这一部分,我借鉴了原始LED驱动板的几种技术。
大电流的元件被集中在一起。电源网络被合并为大面积的铜汇流,而非完全依赖细线。通过使用大面积铜区域,可以更有效地分配电流,并将热量均匀地分散到PCB上。
我还添加了大量连接不同层之间铜区域的导热通孔。这些通孔有助于将热量传递到更大的铜区域,从而提升整体散热性能。
这在看成品电路板时并不显得突出,但它对可靠性有着重大影响。
从模块到平台
当PCB板完成后,项目已经发生了巨大变化。讽刺的是,最初的目标仅仅是制作一个楼梯灯。但硬件方面的经历最终教会了我与软件部分一样多的东西。
由于最近供应紧张,我的新款毫米波雷达还没到货。等它们与控制板集成完成后,我会在楼梯上进行一次正式测试,而不是只是把灯带放在长桌上。
本文编译自hackster.io





