ESP8266-NodeMCU 传感器数据上云:MQTT对接EMQX,5分钟实现微信告警
在智能家居和工业物联网应用中,实时监测环境数据并及时响应异常情况是核心需求。本文将手把手教你如何用ESP8266-NodeMCU采集温湿度、烟雾等传感器数据,通过MQTT协议上传至EMQX消息服务器,并触发微信实时告警。整个过程仅需5分钟即可完成部署,无需复杂代码编写。
1. 硬件准备与环境搭建
1.1 所需硬件清单
- 主控模块:ESP8266-NodeMCU开发板(内置WiFi功能)
- 传感器模块:
- DHT11温湿度传感器
- MQ-2烟雾传感器
- 火焰传感器(数字输出型)
- HC-SR501人体红外传感器
- 其他配件:
- 微型USB数据线
- 杜邦线若干
- 面包板(可选)
1.2 硬件连接示意图
各传感器与NodeMCU的连接方式如下表所示:
| 传感器 | NodeMCU引脚 | 连接说明 |
|---|---|---|
| DHT11 DATA | GPIO5 (D1) | 需接4.7K上拉电阻 |
| MQ-2 AOUT | A0 | 模拟量输出 |
| 火焰传感器 DO | GPIO4 (D2) | 数字量输出 |
| HC-SR501 OUT | GPIO14 (D5) | 人体检测信号输出 |
提示:实际接线时建议使用3.3V供电,避免部分传感器在5V下工作不稳定。
1.3 开发环境配置
- 安装Arduino IDE(建议1.8.x以上版本)
- 添加ESP8266开发板支持:
- 文件 > 首选项 > 附加开发板管理器网址填入:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
- 文件 > 首选项 > 附加开发板管理器网址填入:
- 安装所需库:
// 在库管理中搜索安装以下库 #include <ESP8266WiFi.h> // WiFi连接 #include <PubSubClient.h> // MQTT客户端 #include <DHT.h> // 温湿度传感器
2. MQTT通信实现
2.1 EMQX服务器配置
EMQX是一款开源的MQTT消息服务器,我们使用其公共测试服务器:
const char* mqtt_server = "broker.emqx.io"; // EMQX公共MQTT服务器 const int mqtt_port = 1883; // 非加密端口 const char* topic_pub = "nodemcu/sensor"; // 发布主题 const char* topic_sub = "nodemcu/alert"; // 订阅主题2.2 MQTT客户端实现
在Arduino代码中初始化MQTT客户端并实现回调函数:
WiFiClient espClient; PubSubClient client(espClient); void callback(char* topic, byte* payload, unsigned int length) { // 收到消息时的处理逻辑 Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); String clientId = "ESP8266Client-"; clientId += String(random(0xffff), HEX); if (client.connect(clientId.c_str())) { Serial.println("connected"); client.subscribe(topic_sub); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } }2.3 数据上传实现
在主循环中定时采集并上传传感器数据:
void loop() { if (!client.connected()) { reconnect(); } client.loop(); static unsigned long lastMsg = 0; if (millis() - lastMsg > 5000) { // 每5秒上传一次 lastMsg = millis(); // 读取传感器数据 float h = dht.readHumidity(); float t = dht.readTemperature(); int smoke = analogRead(A0); int flame = digitalRead(D2); int pir = digitalRead(D5); // 构建JSON格式数据 String payload = "{"; payload += "\"temp\":" + String(t) + ","; payload += "\"humi\":" + String(h) + ","; payload += "\"smoke\":" + String(smoke) + ","; payload += "\"flame\":" + String(flame) + ","; payload += "\"motion\":" + String(pir); payload += "}"; // 发布MQTT消息 client.publish(topic_pub, payload.c_str()); Serial.println("Data published: " + payload); } }3. 微信告警集成
3.1 Server酱配置
Server酱提供免费的微信消息推送服务,注册后获取SCKEY:
- 访问 Server酱官网 并登录
- 在「发送消息」页面获取你的SCKEY
- 记录Webhook地址:
https://sctapi.ftqq.com/[SCKEY].send
3.2 EMQX规则引擎设置
在EMQX Dashboard中配置规则,当传感器数据超过阈值时触发Webhook:
- 登录EMQX管理控制台(默认地址:http://localhost:18083)
- 进入「规则引擎」>「规则」页面
- 创建新规则,输入以下SQL语句:
SELECT payload.temp as temperature, payload.humi as humidity, payload.smoke as smoke, payload.flame as flame, payload.motion as motion FROM "nodemcu/sensor" WHERE payload.temp > 40 OR payload.humi > 80 OR payload.smoke > 500 OR payload.flame == 0 OR payload.motion == 1 - 添加「Webhook」动作,填写Server酱的Webhook地址
- 配置消息模板:
{ "title": "家居安防告警", "desp": "检测到环境异常!\n\n温度: {{temperature}}℃\n湿度: {{humidity}}%\n烟雾浓度: {{smoke}}\n火焰状态: {{flame}}\n人体移动: {{motion}}" }
3.3 告警测试
触发各传感器异常条件,检查微信是否收到如下格式的消息:
【家居安防告警】 检测到环境异常! 温度: 42.3℃ 湿度: 85% 烟雾浓度: 623 火焰状态: 0 人体移动: 14. 进阶优化方案
4.1 本地数据缓存
添加EEPROM存储,在网络中断时暂存数据:
#include <EEPROM.h> #define EEPROM_SIZE 512 void setup() { EEPROM.begin(EEPROM_SIZE); } void saveData(String data) { for (int i = 0; i < data.length(); i++) { EEPROM.write(i, data[i]); } EEPROM.commit(); }4.2 OTA远程升级
实现无线固件更新功能:
#include <ESP8266HTTPClient.h> #include <ESP8266httpUpdate.h> void performUpdate() { WiFiClient client; ESPhttpUpdate.update(client, "http://your-server.com/firmware.bin"); }4.3 低功耗优化
对于电池供电场景,启用深度睡眠模式:
#define uS_TO_S_FACTOR 1000000 // 微秒到秒的转换系数 #define TIME_TO_SLEEP 300 // 休眠时间(秒) void setup() { esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); ESP.deepSleep(TIME_TO_SLEEP * uS_TO_S_FACTOR); }5. 常见问题排查
5.1 WiFi连接失败
- 检查SSID和密码是否正确
- 确保路由器工作在2.4GHz频段(ESP8266不支持5GHz)
- 尝试在代码中添加WiFi信号强度检测:
Serial.print("Signal strength: "); Serial.println(WiFi.RSSI());
5.2 MQTT连接不稳定
- 检查EMQX服务器状态
- 增加重连间隔时间
- 使用MQTT over WebSocket(端口8083或8084)
5.3 传感器数据异常
- 检查供电电压是否稳定
- 添加传感器数据滤波算法:
#define FILTER_SAMPLES 5 int filterAverage(int input) { static int buf[FILTER_SAMPLES]; static int count = 0; buf[count] = input; count = (count+1) % FILTER_SAMPLES; long sum = 0; for(int i=0; i<FILTER_SAMPLES; i++) { sum += buf[i]; } return sum / FILTER_SAMPLES; }
实际部署中发现,当多个传感器同时工作时,电源噪声可能导致ADC读数波动。建议在模拟传感器电源端并联100μF电容,数字信号线加10K上拉电阻。