尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于LoRa的智能温控系统:从硬件选型到低功耗固件设计实战

基于LoRa的智能温控系统:从硬件选型到低功耗固件设计实战 1. 项目缘起为什么是LoRa而不是Wi-Fi或蓝牙去年冬天我遇到了一个挺头疼的问题。家里是老房子暖气片是那种老式的铸铁暖气每个房间都装了一个机械式的温控阀。这东西的原理很简单就是靠一个感温包热胀冷缩来调节阀门开度。问题在于它只能感知阀门本体的温度而不是整个房间的空气温度。这就导致了一个很尴尬的局面靠近窗户或者有穿堂风的房间暖气片拼命加热但室温还是上不去而一些密闭的、阳光好的房间可能早就热得不行了阀门却还没关小白白浪费燃气。我当时的第一反应和大多数人一样是去看看市面上那些“智能温控器”。主流方案无非两种一种是基于Wi-Fi的需要每个房间装一个温控面板通过家里的路由器联网用手机App控制另一种是Zigbee或蓝牙Mesh的需要搭配一个网关。Wi-Fi方案看似简单但实际部署起来问题不少。首先每个温控器都需要一个电源插座或者从灯具取电走线是个大麻烦。其次Wi-Fi设备功耗高待机电流大不适合用电池长期供电。最关键的是Wi-Fi信号穿墙能力有限对于我家这种承重墙多的老房子角落房间的信号时好时坏设备经常掉线体验极差。Zigbee和蓝牙Mesh在功耗和组网上有优势但它们的工作频率2.4GHz和Wi-Fi一样穿墙能力依然是短板。而且它们的有效通信距离通常在室内10-30米对于别墅或者多层住宅依然需要多个中继节点网络配置和维护复杂度不低。就在我几乎要放弃的时候一次偶然的机会接触到了LoRaLong Range Radio远距离无线电技术。LoRa工作在Sub-GHz频段如433MHz、868MHz、915MHz这个频段的电磁波波长更长绕射和穿透能力远超2.4GHz。简单来说它就像能“拐弯”的信号能轻松穿透数层砖墙实现几百米甚至上公里的稳定通信。更重要的是LoRa模块在休眠模式下的功耗可以低至微安级别一节普通的5号电池就能让一个设备工作好几年。这不正是我需要的吗超低功耗、超远距离、稳定可靠完美契合了“每个房间一个无线温控器”的应用场景。于是一个自己动手打造“基于LoRa的远程控制房间温控器”项目的想法就诞生了。我的目标很明确制作一批电池供电的、带温度传感器和阀门控制接口的终端节点它们通过LoRa无线网络将室温数据上报给一个中央网关同时接收来自网关的阀门开关指令。用户可以通过连接在网关上的手机App或者网页实时查看每个房间的温度并远程设定目标温度或直接控制阀门。2. 核心硬件选型从芯片到天线的全链路考量确定了技术路线接下来就是硬件的选型。这不仅仅是买几个模块那么简单需要从系统层面考虑功耗、成本、通信可靠性和开发便利性。2.1 主控MCU与LoRa芯片的搭配对于终端节点温控器核心是超低功耗。我选择了意法半导体的STM32L0系列MCU具体型号是STM32L073RZT6。选择它的理由有几个首先它基于ARM Cortex-M0内核在运行模式和多种低功耗模式睡眠、停止、待机下都有极佳的能效比。其次它内置了丰富的模拟和数字外设比如12位ADC可以高精度采集温度传感器信号多个定时器可以用于生成PWM信号驱动阀门电机还有LPUART低功耗串口可以以极低的功耗与LoRa模块通信。最后ST的生态系统完善开发工具和资料丰富踩坑时容易找到解决方案。LoRa芯片方面Semtech的SX1276/78系列是行业标杆。我最终选择了SX1278它支持137MHz至1020MHz的宽频段正好覆盖国内常用的433MHz ISM频段。与其搭配一个独立的MCU另一种流行的方案是使用集成了LoRa调制解调器和MCU的单芯片方案比如Semtech的LLCC68MCU或者国内厂商的一些ASR6501等模块。这类模块集成度高尺寸小但对于深度定制和功耗的极致控制灵活性稍差。我选择SX1278STM32L0的分离方案虽然PCB面积大一点但可以更精细地控制每一个IO口的状态实现纳安级的漏电流管理这对于追求“一颗电池用五年”的目标至关重要。2.2 传感器与执行器的选择温度传感器必须精准且低功耗。DS18B20这种单总线数字传感器虽然常见但其在转换温度时需要较大的工作电流约1.5mA。我选择了TI的TMP117。这是一款高精度、低功耗的数字温度传感器精度可达±0.1°C典型值。最关键的是它在单次转换模式下的平均电流可以低至3.5μA每秒测量一次的情况下。通过I2C接口与MCU通信完美契合低功耗设计。执行器也就是驱动暖气阀门的部件是项目的关键。市面上有通用的“热电执行器”它内部是一个蜡质热膨胀元件通过通电加热来推动阀杆。但它的驱动需要220V交流电且控制是开关量开或关不够精细。我决定使用微型直流减速电机来直接驱动阀门的旋转手柄。选用的是一款额定电压3-6V带有编码器的减速电机。编码器用于检测阀门旋转的角度实现闭环控制避免因堵转损坏电机或阀门。电机驱动芯片选用DRV8833双H桥驱动器它可以由MCU的PWM信号控制正反转和速度。2.3 电源管理与天线设计电源是电池供电设备的生命线。我使用两节串联的AA5号锂亚硫酰氯电池ER14505。这种电池标称电压3.6Vx27.2V容量约2400mAh自放电率极低非常适合物联网设备。电源管理分两级第一级是一个低压差线性稳压器LDO将7.2V降至3.3V给MCU、传感器和LoRa模块供电。这里选用了TPS7A系列LDO其在轻载下的静态电流仅几微安。第二级是一个开关稳压器Buck电路将7.2V降至5V专门给电机驱动芯片供电以提高驱动效率。天线是LoRa通信距离的决定性因素之一。我选择了433MHz频段的弹簧天线俗称“猪尾巴”天线其长度经过计算约为16.5cm波长/4。在PCB布局上天线接口必须严格按照芯片数据手册的要求进行阻抗匹配通常为50欧姆并预留π型匹配网络由电感和电容组成的焊盘以便在实际调试时进行微调确保天线驻波比SWR最佳将更多的能量辐射出去而不是反射回来损耗掉。3. 固件设计低功耗与通信协议的深度博弈硬件是骨架固件Firmware才是灵魂。对于物联网终端固件设计的核心矛盾永远是功能实现 vs. 功耗控制。3.1 低功耗状态机设计终端设备绝大多数时间应该处于深度睡眠状态。我设计了一个基于定时器唤醒的状态机其工作周期为10秒。深度睡眠Stop Mode持续9.99秒。此时MCU内核关闭所有高速时钟关闭仅保留低速内部时钟LSI给看门狗和唤醒定时器RTC供电。LoRa模块、温度传感器、电机驱动全部断电。整个系统的电流消耗小于5μA。测量与上报周期每10秒被RTC唤醒一次。第一步-上电与初始化MCU退出停止模式首先给温度传感器和LoRa模块的电源控制MOS管上电然后初始化I2C和SPI总线。第二步-温度采集通过I2C向TMP117发送单次转换命令等待约16ms后读取温度数据。整个过程电流峰值约200μA。第三步-数据打包将温度数据、电池电压通过ADC分压测量、设备ID等信息打包成一个短数据包。第四步-LoRa发射通过SPI配置SX1278为发射模式设置发射功率通常设为14dBm约25mW将数据包发送出去。发射时间取决于数据包长度和扩频因子Spreading Factor, SF以SF7为例发送11字节的数据约需60ms。这是功耗最高的阶段瞬时电流可达120mA。第五步-监听下行指令可选发射完成后LoRa模块会短暂切换到接收模式开启一个约200ms的接收窗口监听网关是否有下行指令如新的温度设定值。如果有则接收并处理如果没有则超时关闭。第六步-断电与休眠关闭所有外设电源MCU配置所有IO口为模拟输入模式以降低漏电最后再次进入深度睡眠模式。通过这个精密的时序控制设备在99%的时间处于极低功耗状态仅在那不到1秒的活跃期内消耗能量。计算平均电流假设发射电流120mA持续60ms接收电流10mA持续200ms其他活动电流1mA持续200ms睡眠电流5μA。那么一个10秒周期的平均电流约为 (120mA0.06s 10mA0.2s 1mA0.2s 0.005mA9.54s) / 10s ≈ 0.92mA。对于2400mAh的电池理论续航可达2400mAh / 0.92mA ≈ 2608小时约108天。这显然不够。因此在实际应用中我会将测量上报周期延长比如每5分钟300秒上报一次。这样平均电流会骤降至约0.03mA理论续航可达数年这才符合预期。3.2 LoRaWAN与私有协议之争LoRa技术本身只是物理层和链路层在其之上需要一套网络协议。最著名的就是LoRaWAN它是一个由LoRa联盟推动的开放标准协议定义了设备入网、安全加密、自适应数据速率ADR等机制。使用LoRaWAN的优点是标准化可以接入公共或私有的LoRaWAN网络服务器如ChirpStack生态成熟。但我最终选择了自研一个简化的私有协议。原因如下控制权与简化LoRaWAN为了兼容性和安全性协议栈相对复杂对于点对点或星型网络的小规模应用显得臃肿。我的网络结构很简单一个网关对几十个终端私有协议可以极度精简减少代码量和通信开销。实时性LoRaWAN的Class A设备最省电的类别只有在发送数据后的两个短暂窗口内可以接收下行指令实时性较差。我的私有协议可以更灵活地定义通信时序比如在网关需要紧急广播关阀指令时可以主动发送一个前导码很长的唤醒信号让所有终端临时唤醒监听。成本与调试无需兼容复杂的LoRaWAN规范开发调试更直接。网关端我用树莓派LoRa HAT实现运行一个用Python写的简单服务负责解析数据包、写入本地数据库如SQLite、并通过MQTT协议转发到Home Assistant等智能家居平台或者提供一个简单的Web控制界面。我的私有协议数据包格式如下示例字节偏移长度内容说明01帧头0xAA用于帧同步14设备ID唯一标识一个温控器52温度数据16位有符号整数单位0.01°C72电池电压16位无符号整数单位mV91阀门状态0关1开2故障101CRC8校验和校验数据完整性下行指令包格式类似包含目标设备ID和指令码如设定温度、开关阀门。3.3 电机控制与阀门校准算法驱动电机旋转阀门听起来简单实则暗藏玄机。首先需要知道阀门从全关到全开需要旋转多少度。这因阀门型号而异。我的做法是在设备首次安装时进入一个“校准模式”。通过手机App或网关发送开始校准指令设备会控制电机向一个方向缓慢旋转直到编码器检测到电机堵转电流骤增或转速为零记录下这个位置作为“机械零点”。然后向反方向旋转再次遇到堵转记录为“机械终点”。两点之间的编码器脉冲数就是阀门的有效行程。日常控制时采用闭环PID比例-积分-微分控制算法。设定温度与实际室温的差值作为PID的输入输出值映射为阀门的目标开度0%-100%。MCU根据目标开度与当前开度由编码器反馈的差值计算出电机需要旋转的方向和脉冲数并控制PWM占空比即电机速度进行驱动。到达目标位置后停止。为了防止电机因长期堵转而过热在到达目标位置后驱动芯片会进入高阻态仅由编码器保持位置信息。这里有一个重要的细节暖气阀门通常有“自锁”功能即断电后能保持当前位置。这对于节省电能至关重要。我们的电机驱动方案在停止时完全断电依靠阀门的自锁力来保持开度。4. 网关与上层应用数据的汇聚与控制的中枢终端节点是触手网关就是大脑。网关负责与所有终端进行LoRa通信并桥接到更上层的网络如家庭局域网、互联网。4.1 网关硬件与基础服务搭建我选用树莓派4B作为网关主机搭配一款基于SX1301芯片的LoRa集中器HAT如RAK2245 Pi HAT。SX1301是Semtech的网关芯片内置了8个并行解调通道和1个发射通道可以同时监听多个频点上的LoRa信号极大地提高了网关的容量和并发处理能力比单通道的SX1278收发器强大得多。在树莓派上我主要运行三个服务LoRa数据包转发器使用开源项目packet_forwarder。它负责与SX1301硬件交互接收来自终端的原始LoRa射频数据包加上时间戳、信号强度RSSI、信噪比SNR等信息封装成JSON格式通过UDP协议发送到本地的网络服务器Network Server。私有协议网络服务器Network Server这是我用Python写的核心服务。它监听UDP端口接收来自packet_forwarder的数据。解析我自定义的数据包格式校验CRC然后将设备ID、温度、电压等信息写入本地的SQLite数据库。同时它维护一个设备状态表记录每个设备最后一次通信的时间用于判断设备是否离线。这个服务也负责生成下行指令。当从上层应用如MQTT收到控制命令时它会将命令编码成下行数据包并通过调用packet_forwarder提供的UDP接口发送出去。MQTT代理桥接为了融入现有的智能家居生态我使用了开源的MQTT代理Mosquitto。我的网络服务器会将每个设备的温度数据发布到类似home/lora-thermostat/room1/temperature的MQTT主题。同时它订阅类似home/lora-thermostat/room1/set的主题以接收来自Home Assistant、Node-RED或自定义App的控制指令。4.2 控制界面与智能逻辑数据有了如何呈现和控制我有几种方案。Home Assistant集成这是最优雅的方式。在Home Assistant中通过MQTT自动发现功能每个LoRa温控器会被识别为一个“Climate”实体。我可以在HA的仪表盘上看到每个房间的当前温度、设定温度并直接进行调节。HA强大的自动化引擎可以设置复杂的场景比如“晚上10点后如果卧室温度高于22度自动关小阀门”“白天如果客厅有人通过人体传感器判断则保持客厅21度无人时降至18度”。简易Web控制台我用Python的Flask框架写了一个简单的Web应用直接读取SQLite数据库展示所有设备的实时数据和历史曲线通过Chart.js绘制并提供了手动控制阀门的按钮。这个界面适合直接在家庭内网访问不依赖外部智能家居平台。移动端App对于更便捷的控制可以使用Blynk、IoT MQTT Panel这类App生成器快速创建一个手机控制界面通过MQTT与网关通信。智能逻辑的核心是温度控制算法。除了前面提到的终端本地的PID控制在网关或HA层面还可以实现更高级的优化分时段设定根据作息时间设置不同的目标温度曲线如睡眠时段降低温度。联动控制与窗户传感器联动如果检测到窗户打开自动关闭该房间的暖气阀门避免能源浪费。基于学习的预测记录房间温度变化与阀门开度、室外温度的关系逐渐学习房间的热惰性实现提前预判式控制让室温更加平稳。5. 部署、调试与实战中的坑硬件焊接、代码编写都只是开始真正的挑战在于部署和长期稳定运行。5.1 网络规划与信号测试LoRa虽然穿墙能力强但也不是无限制的。在部署前需要进行简单的信号测试。我使用一个终端设备设置为持续发射模式用网关在不同位置接收记录RSSI和SNR。目标是确保所有需要安装终端的位置其信号强度RSSI高于接收灵敏度例如-120dBm至少10dB以上信噪比SNR为正数且最好大于5。对于个别信号极弱的角落如地下室、金属柜子内可能需要考虑增加一个LoRa中继节点或者稍微调整网关天线的位置尽量放在房屋中心的高处。LoRa使用扩频技术同一时间在同一频点上只能有一个信号被正确解调。如果设备很多随机发射可能会碰撞。我的解决方法是时分复用给每个设备分配一个粗略的、错开的发送时间偏移量。例如设备1在每分钟的第0-2秒发送设备2在第3-5秒发送以此类推。结合随机延迟碰撞概率大大降低。频分复用如果设备非常多50可以考虑使用多个通信频点。LoRa在433MHz频段有多个100kHz宽的信道可用。可以将设备分组分别使用不同的频点与网关通信。5.2 功耗优化实战与测量理论计算的平均电流和实际相差往往很大。必须用高精度的万用表或电流探头进行实测。我将设备接入万用表的电流档记录一个完整工作周期的电流波形。常见的功耗陷阱有IO口漏电未使用的IO口未设置为模拟输入模式或者外部电路有上拉/下拉电阻在睡眠时形成了漏电通路。务必在进入睡眠前将所有未使用的IO配置为模拟输入对于STM32。外设未彻底断电代码里只是停止了外设时钟但外设的电源引脚依然供电。必须通过MOS管或负载开关在物理上切断传感器、LoRa模块等的电源。唤醒源干扰除了RTC其他中断如外部中断意外唤醒MCU。检查所有中断标志位确保只有预期的唤醒源能生效。软件延时忙等待在活跃期使用的delay函数可能是基于循环的空等待这会阻止MCU进入低功耗模式。应使用基于定时器中断的延时或者在等待外设操作完成时让MCU进入睡眠模式Sleep Mode由中断唤醒。经过一轮又一轮的优化我最终将终端设备在每5分钟上报一次的模式下实测平均电流控制在了约20μA。两节2400mAh的锂亚电池理论续航达到了惊人的2400mAh / 0.02mA 120,000 小时 ≈ 13.7年。当然实际受电池自放电、温度等因素影响用上5-8年是完全可以期待的。5.3 可靠性保障与故障处理系统要可靠必须考虑各种异常情况。通信失败处理终端发送数据后如果在接收窗口内没有收到网关的确认ACK它会启动一个指数退避算法在随机延迟后重试。重试超过一定次数如3次后设备会记录一次通信失败并暂时进入一个更长的休眠周期如30分钟后再尝试避免在网关故障时快速耗尽电池。阀门防卡死与状态反馈电机驱动阀门时如果编码器反馈的位置长时间不变化而电机电流很大则判断为堵转。设备会立即停止电机反转一小段距离释放应力并上报“阀门故障”状态。网关收到后可以发出警报。电池低压报警终端定期测量电池电压当电压低于预设阈值如5.4V对应单节2.7V时会在每次上报的数据包中携带低压标志。网关可以汇总这些信息提醒用户更换电池。网关看门狗与自恢复树莓派上的服务可能因各种原因挂掉。我使用systemd来管理所有服务并设置看门狗。另外写了一个简单的Shell脚本定时检查关键服务的状态如果发现异常尝试重启服务甚至重启树莓派本身。这个项目从构思到最终稳定运行花了近四个月的时间。过程中充满了焊接、调试、抓包、改代码的日夜。但当我在寒冷的冬天躺在沙发上用手机将书房暖气调小将卧室温度提前调高时那种创造的满足感和实实在在的舒适感是购买任何成品都无法替代的。LoRa技术为智能家居的“最后几十米”无线控制提供了一个极其优秀的解决方案它弥补了Wi-Fi和蓝牙在距离与功耗上的短板。如果你也有类似的远程、低功耗控制需求不妨从一个小模块开始亲手搭建一个属于自己的LoRa网络。
返回列表