资讯详情

资讯详情

基于Arduino与MQTT的衣物自动烘干系统设计与实现

简介基于Arduino与MQTT的衣物自动烘干系统完整工程包面向物联网开发者、嵌入式初学者及智能家居DIY爱好者。项目利用DHT温湿度传感器采集环境数据结合MQTT协议实现传感器与烘干设备间的实时通信与自动控制涵盖开关机、功率调节、串口可视化及异常处理等典型功能可帮助读者掌握温湿度采集、MQTT发布订阅、设备联动控制等实用技能。压缩包共131个文件包含35个ino主控程序、25个h头文件、22个cpp库文件、12个txt配置文件、11个md说明文档以及若干Python脚本、C文件、构建脚本和makefile全面覆盖源码、依赖库、配置与文档整个资源包仅282KB轻量易用适合快速阅读与二次开发。资源发布后已有41人学习浏览适合作为物联网课程设计或Arduino实战项目的参考资料。 你们有没有遇到过这种情况周末把一桶洗好的衣服晾出去结果阴雨天晾了两天摸上去还是潮的。更让人无语的是把烘干机拉出来“抢救”一下定时器倒是到了衣服也热透了拿出来手感还是半干不干的得返工再烘一轮。问题的根源不在烘干机功率而在它根本不知道衣服到底干没干只知道傻乎乎地计时。所以我花了两个周末做了一套基于Arduino和MQTT的衣物自动烘干系统源码已经整理成zip包分享出来了。这套系统的核心思路很简单用温湿度传感器采集环境数据把数据通过MQTT协议实时发布再让主控根据数据变化判断衣物干燥状态自动启停加热器和风扇。它解决的问题就一个——让烘干这件事从“按时间猜”变成“按数据判断”。如果你正准备入门Arduino项目或者家里有烘干需求想改造成智能控制又或者你想看MQTT协议在真实项目里怎么落地这篇记录应该对你有参考价值。我不会只贴源码我会把当时为什么选这个方案、哪几个环节反复踩坑、最终怎么调通的完整过程都讲清楚。1. 一台普通烘干设备为什么需要Arduino和MQTT1.1 定时的傻劲与感知的聪明传统的烘干机基本都是“定时器逻辑”你设定60分钟它就老老实实加热60分钟到点停机。这个逻辑听着没什么问题实际用起来漏洞很多。衣服少的时候可能30分钟就干了剩下半小时的加热纯粹是在耗电而且高温空转对衣物纤维也有损伤衣服多的时候60分钟可能只烘了个表面内层还是湿的。我查了一下干燥过程的温度湿度曲线发现一个特别有意思的规律衣物刚放进烘干柜时随着加热器工作水分大量蒸发柜内湿度会先快速上升等衣物表面的自由水被带走得差不多了湿度曲线就开始持续下降而当衣物基本干燥时湿度变化会进入一个明显的平台期几乎不再波动。换句话说判断“干没干”根本不需要你去猜时间只需要盯着湿度曲线看。基于这个认知我的系统里定义了几个关键状态待机IDLE、加热HEATING、烘干中DRYING、完成FINISH、冷却COOLING。主控通过传感器实时读取柜内温湿度再用一套判断规则在状态之间切换。这样烘出来的衣物状态稳定得多而且不会出现过烘。1.2 为什么选MQTT而不是HTTP轮询可能有人会问一个Arduino项目而已直接用HTTP请求上报数据不就行了为什么还要引入MQTT我当时也纠结过这个问题最后选了MQTT原因有几个第一场景里有多个节点。柜内有一个传感器柜外阳台还有一个参考传感器未来可能还要加显示屏、红外遥控模块。MQTT的发布订阅模型天然适合这种“多点对多点”的通信传感器节点只负责发布数据控制节点只负责订阅指令互相之间不需要知道对方的IP地址解耦非常干净。第二实时性和流量开销。HTTP轮询需要客户端定时去请求服务器周期短了浪费流量周期长了数据实时性差。而MQTT是服务端主动推送消息传感器每次采集完数据几秒钟之内就能推送出去。对于烘干这种需要及时响应的场景推送模型明显更合适。第三也是最重要的——MQTT broker可以作为“中间人”存在。我的手机、Home Assistant、甚至是远程的规则引擎都可以同时订阅这台烘干机的数据。如果哪天下班路上想远程打开烘干机预热只需要向command主题发送一条消息就行完全不用给路由器做端口映射也不用在内网穿透上折腾。这一点做完整套系统之后体会特别深。2. 硬件选型与接线每块板子都不是凑数的2.1 主控、传感器、执行器的选择逻辑先看主控。很多Arduino入门教程用的都是Uno R3但Uno没有WiFi模块要联网还得外接ESP8266模块或者网线转接光接线就多了一堆麻烦事。我在这个项目里直接用了ESP8266 NodeMCU理由很直接它自带WiFi价格便宜GPIO数量足够驱动一个继电器和一个风扇跑MQTT客户端也完全不吃力。如果你预算稍微宽裕一点或者后面想外接OLED屏、接多个传感器那直接用ESP32会更省心。它双核240MHz引脚多还有蓝牙可扩展性比ESP8266强不少。不过就烘干柜这个场景而言ESP8266已经绰绰有余了。传感器方面我对比过DHT22和SHT30做了个小表格传感器通信方式湿度精度价格稳定性DHT22单总线±2%RH低对时序敏感易受线材影响SHT30I2C±2%RH中稳定性更好读数平滑BME280I2C/SPI±3%RH中自带气压温度适合户外参考最终烘干柜内我用了SHT30柜外参考点用了一个DHT22。原因在后面“踩坑”章节会详细说——DHT22的单总线时序太容易被干扰了放在柜内这种电磁环境复杂的地方容易抽风而SHT30走I2C协议稳定得多。执行器我用了一个5V低电平触发的继电器模块外加一个PTC陶瓷加热片和一个12V直流风扇。PTC加热片的好处是温度上升到居里点之后电阻会急剧增大自动限温不容易烧糊衣物安全性比电热丝高不少。2.2 完整接线方案与供电注意事项接线其实不复杂但有几个点特别值得注意。我把自己的实际接法列出来ESP8266的D4GPIO2接SHT30的SCLD3GPIO0接SHT30的SDA同时接上拉电阻到3.3V。D6GPIO12接继电器模块的IN引脚。D7GPIO13接12V风扇的MOS管驱动模块控制端。柜外DHT22的DATA脚接D5GPIO14注意DATA和VCC之间要加一个4.7k上拉电阻。供电是整个项目里最容易踩雷的地方。ESP8266的USB供电和继电器驱动不能共用一个电源因为继电器吸合瞬间电流会突然拉高导致ESP8266直接重启。我最后用的是ESP8266单独用一个5V/2A的手机充电头供电继电器和PTC加热片共用一组220V交流线路12V风扇单独用一个小功率适配器。三个电源之间物理隔离互不干扰。还要强调一点PTC加热片和220V交流电相关的高压部分接线时一定要做好绝缘处理。我用的继电器模块自带光耦隔离这样信号端和负载端没有电气连接主控部分相对安全。如果完全没接触过交流电建议先把加热部分换成12V的PTC片整机变成低电压系统先跑通逻辑再说。3. 源码核心逻辑数据怎么走、决策怎么下3.1 MQTT主题设计把流程理清楚再写代码写过几个MQTT项目之后我越来越觉得主题设计比代码本身更重要。主题其实就是系统里的“消息管道”管道命名乱后面维护起来就是灾难。我这里的主题设计是这样的主题方向消息内容说明home/dryer/tele/temp设备发布柜内温度值传感器遥测数据home/dryer/tele/humidity设备发布柜内湿度值传感器遥测数据home/dryer/tele/ref_humidity设备发布柜外参考湿度用于基线对比home/dryer/status设备发布idle/heating/drying/finish当前状态home/dryer/lwt设备发布offline/online遗嘱消息异常断线通知home/dryer/command订阅start/stop/auto远程指令下发tele和status分开是因为数据更新频率不一样。传感器遥测每5秒发一次状态只有切换时才发这样broker那边的消息流量控制得比较好不会出现一堆无意义消息刷屏。lwt遗嘱消息是PubSubClient库自带的机制设备突然掉线时broker会帮你发布一条遗嘱消息这样控制端立刻能感知到设备“死了”。3.2 温湿度判干算法与状态机这部分是整套源码的灵魂我直接讲算法逻辑。判干算法不能只看单次湿度值。柜内湿度受环境影响很大夏天和冬天的基础湿度都不一样。所以我在柜外放了一个参考传感器算法比较的是“柜内湿度与柜外湿度的差值”以及“柜内湿度的变化趋势”而不是绝对湿度值。具体规则是这样的启动烘干后如果柜内湿度持续3分钟高于柜外湿度15%以上说明衣物水分正在大量蒸发系统进入DRYING状态。当柜内湿度与柜外湿度的差值缩小到8%以内并且持续5分钟没有再反弹就判定进入FINISH状态。为了防止误判我还加了一个“防反弹”机制判定完成前必须看到湿度连续5分钟呈下降趋势。如果中途出现一次明显上升就重置计时器。这招是从PID控制里的“滞后区间”思想学来的效果非常明显。下面是我简化后的核心代码完整版在源码包里void updateState() { unsigned long now millis(); float diff indoorHumidity - outdoorHumidity; bool humidityTrendDown (currentHumidity - lastHumidity) -0.3; if (state STATE_HEATING) { if (diff 15.0) { state STATE_DRYING; dryStartTime now; } } else if (state STATE_DRYING) { if (diff 8.0 humidityTrendDown) { if (dryStableStartTime 0) { dryStableStartTime now; } else if (now - dryStableStartTime 5 * 60 * 1000UL) { transitionTo(STATE_FINISH); } } else { dryStableStartTime 0; } } }判干完成后不能立刻全停因为PTC加热片还有余热直接停机柜内温度太高衣物闷在里面容易返潮。所以我加了一个COOLING状态停止加热但继续让风扇转3分钟把柜内热空气排出去等温度降到40℃以下才彻底断电。3.3 Arduino端代码骨架Arduino端的代码骨架大概是这样的核心就是WiFi连接、MQTT连接、数据发布三个部分#include ESP8266WiFi.h #include PubSubClient.h #include Wire.h #include SHT30.h const char* ssid your_wifi_ssid; const char* password your_wifi_password; const char* mqttServer 192.168.1.100; const int mqttPort 1883; WiFiClient espClient; PubSubClient mqttClient(espClient); SHT30 sht30; const int relayPin D6; const int fanPin D7; void setup() { Serial.begin(115200); pinMode(relayPin, OUTPUT); pinMode(fanPin, OUTPUT); // 关键上电先拉低继电器防止误动作 digitalWrite(relayPin, LOW); digitalWrite(fanPin, LOW); connectWiFi(); mqttClient.setServer(mqttServer, mqttPort); mqttClient.setCallback(callback); connectMQTT(); } void loop() { if (!mqttClient.connected()) { connectMQTT(); } mqttClient.loop(); static unsigned long lastPublish 0; if (millis() - lastPublish 5000) { publishSensorData(); lastPublish millis(); } updateState(); applyActuators(); }这段代码里最重要的一行是setup()里那两个digitalWrite(relayPin, LOW)。你往下看就知道为什么我把它单独拎出来说。4. 实测中我踩过的坑从继电器误动作到MQTT失联4.1 上电瞬间的“啪”声GPIO默认电平惹的祸第一版硬件焊好之后我第一次插电源还没等程序跑起来继电器就“啪”地一声吸合了加热器跟着闪了一下。虽然只通了零点几秒的电但我后背还是凉了一下这要是柜子里有易燃物后果不敢想。原因我查了很久才确定ESP8266的GPIO在上电瞬间的默认电平并不完全一致有一部分IO口会短暂处于浮动状态或者高电平。如果是高电平那继电器模块很多是低电平触发可能不会动如果是低电平触发模块高电平反而不会触发。偏偏我用的继电器模块是“低电平触发”GPIO默认高电平的时候没事但上电过程中那几十毫秒的电压爬升过程足够让继电器误动作一次。解决办法是双保险硬件上在继电器IN引脚对GND加了一个10k下拉电阻软件上在setup()最开头就把继电器引脚拉低。这样即使WiFi连接失败、程序卡在其他地方继电器也保持在断开状态。这个经验后来成了我做所有执行器项目的默认固定动作。有一点要提醒如果你用的继电器模块是“高电平触发”那上电默认高电平反而会有问题建议换用低电平触发的模块从机理上规避上电误动作。4.2 DHT22读不到数据时序和线材的战争第一个版本我图省事柜内柜外都用DHT22。结果发现柜内那个DHT22经常读不出数据串口监视器里反复跳NaN。最诡异的是它刚开机的时候一切正常运行十来分钟就开始频繁失败。排查下来有两个直接原因。第一个是线材问题。DHT22是单总线通信时序要求很严格我从它到ESP8266之间用了一根大约30厘米的杜邦线中间还要拐来拐去绕开继电器导线上的分布电容把信号边沿拖慢了导致数据帧校验失败。第二个问题是DHT22本身要求两次读取间隔至少2秒我一开始为了数据平滑把读取间隔压到了1秒结果就是Grove库里的读取函数一个接一个报超时。最后的处置方案柜内换成了SHT30走I2C总线抗干扰能力强很多柜外那个DHT22因为离主控近、线材短保留下来用。顺带一提如果你一定要用DHT22请保证接线长度不超过20厘米并且每次读取之间至少间隔2秒。4.3 设备“失联”导致衣服烘不干重连机制必须写这个坑几乎要了我整个项目的老命。有一阵子我家里路由器每天晚上定时重启路由器一重启ESP8266的WiFi断了MQTT连接自然也就断了。但问题是WiFi恢复之后设备并没有自动重新连接MQTT broker它的循环里还在傻乎乎地执行mqttClient.loop()但底层socket已经断开了消息根本发不出去。最气人的是烘干流程已经进行到一半我远程想发一条“start”指令把它唤醒消息发到broker之后broker找不到任何订阅者直接把消息丢了。那次衣服在柜子里闷了整整一晚上第二天打开一股馊味。解决方式是在loop()里显式处理重连逻辑。我的做法是用一个非阻塞的时间判断避免反复尝试连接导致卡死主循环unsigned long lastReconnectAttempt 0; void loop() { if (!mqttClient.connected() millis() - lastReconnectAttempt 5000) { if (connectMQTT()) { lastReconnectAttempt millis(); } } mqttClient.loop(); }同时加上WiFi层防护WiFi.setAutoReconnect(true); WiFi.persistent(true);现在这套系统已经连续跑了一个多月中途故意断电、重启路由器都试过设备都能在10秒内恢复连接之前那种“设备失联但程序还在跑”的假死状态再也没有出现过。4.4 Retained消息引发的“灵异开机”还有一个特别隐蔽的坑说出来希望你们别像我一样被坑到。有一次我调试完程序手动给home/dryer/command发了一条“start”消息当时没注意把retained标志位设成了true。结果第二天早上起来烘干柜莫名其妙自己启动了。问题就出在retained消息上。MQTT broker会把retained消息保存下来当设备端重新订阅这个主题时broker会把最后一条retained消息推送给它。所以第二天ESP8266重新联网、订阅command主题的一瞬间收到了一条“start”指令设备就傻乎乎地开干了。以后凡是涉及“指令类”主题发布消息时千万不要开retained标志位只有“状态类”主题才适合用retained让新上线的订阅者能立刻拿到当前状态。这一个规则能帮你避免无数个灵异事件。5. 这套系统还能往哪走从单机烘干到全屋联动5.1 接入Home Assistant做场景自动化单一设备的烘干功能跑通之后我很快就不满足了。烘干柜如果只靠自己的状态机工作那它和一台“聪明一点的定时器”也没本质区别。真正让它变得有生命力的是接入整个家庭自动化系统。因为我用的MQTT协议所以对接Home Assistant相当顺畅。在HA的configuration.yaml里加一个MQTT传感器就能把柜内温湿度、状态全部同步上来。更重要的是可以写自动化规则automation: - alias: Auto Dry on Rainy Day trigger: - platform: mqtt topic: home/dryer/tele/humidity condition: - condition: numeric_state entity_id: sensor.outdoor_humidity above: 75 - condition: state entity_id: sensor.dryer_status state: idle action: - service: mqtt.publish data: topic: home/dryer/command payload: start这条规则的意思是柜外湿度超过75%阴雨天晾不干的气候且烘干柜处于待机状态时自动启动烘干流程。从那以后我再也不用每天出门前纠结“今天要不要开烘干”。系统自己会根据环境和衣物情况做判断这才是“自动”两个字真正的含义。5.2 更聪明一点加红外补盲、对接气象数据和谷电策略如果家里本来就有热泵式烘干机不想像我一样从头搭PTC加热柜也可以用一个相对轻量的思路在衣柜里只部署传感器和Arduino主控不直接驱动加热器而是通过网络把“需要启动烘干”的指令推送给已有的烘干机。市面上不少烘干机支持红外遥控可以在ESP8266上接一个NEC格式的红外发射管把原装遥控器的编码学习进去解析后通过红外控制原机启动或停机。这样一来烘干系统的智能判断能力保留了下来执行部分复用原有家电成本更低改造风险也更小。还可以考虑接入天气数据。我目前在做的一个扩展是在云端跑一个脚本定时抓取本地的天气预报把未来几个小时的降雨概率发布到home/weather/rain_probability主题。烘干系统的控制逻辑里增加一条规则如果降雨概率超过60%即使柜外湿度正常也优先选择启动柜内烘干防止衣服晾出去又被淋湿。另外如果你的电费有峰谷电价你还可以让系统只在谷电时段执行烘干任务。比如把“启动指令”改成“预约启动”让烘干柜等到晚上22点电价低谷后再开始工作。这种优化不改变硬件只是在MQTT消息链路上多了一层定时规则性价比极高。从我个人的使用体会来说这套基于Arduino和MQTT的衣物自动烘干系统最初只是一个解决“衣服晾不干”的应急方案真正跑了几个月之后它已经变成了我家里物联网架构里一个非常踏实的数据节点。它的价值不在于用了多先进的技术而在于用一套简单可靠的方式把传感器数据、消息传输、自动控制这三件事串成了一个闭环。如果你也想复刻这个项目我的建议是从最简版本开始一个ESP8266、一个传感器、一个继电器先跑通“数据采集上云”再逐步加入烘干判断和远程控制。源码zip包里的所有文件都做了注释重点逻辑和踩坑点基本都在本篇里说明了剩下的就靠你动手试了。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →