ESP32-WROOM-32E + Node-RED实战:5分钟搞定物联网数据面板(附完整代码)
ESP32-WROOM-32E + Node-RED实战:5分钟搞定物联网数据面板(附完整代码)
每次看到那些炫酷的物联网数据大屏,你是不是总觉得背后藏着复杂的代码和漫长的开发周期?其实,用ESP32-WROOM-32E这块国民级开发板,配合Node-RED这个可视化工具,搭建一个实时数据面板的速度,可能比你泡一杯咖啡还快。今天,我们就来抛开那些繁琐的理论,直接上手,用最少的代码和最简单的步骤,从零开始构建一个能实时显示传感器数据、并能远程控制设备的物联网仪表盘。无论你是刚接触硬件的爱好者,还是想快速验证产品原型的开发者,这套组合拳都能让你在极短时间内看到成果。
1. 硬件准备与ESP32基础环境搭建
在开始连线之前,我们先明确一下核心组件。ESP32-WROOM-32E是一款功能强大且性价比极高的Wi-Fi & 蓝牙双模模组,它内置了丰富的外设接口,足以应对大多数物联网传感和控制需求。你手头需要准备的物料非常简单:
- ESP32-WROOM-32E开发板(或其兼容板如NodeMCU-32S)
- USB数据线(用于供电和编程)
- 一台电脑(Windows, macOS 或 Linux 均可)
- 网络环境(ESP32和运行Node-RED的电脑需要在同一局域网,或能通过互联网互通)
1.1 安装Arduino IDE与ESP32开发板支持
我们将使用最经典的Arduino IDE来为ESP32编写固件。首先,前往Arduino官网下载并安装最新版的IDE。安装完成后,打开IDE,进入“文件” -> “首选项”。
在“附加开发板管理器网址”中,填入以下网址:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json然后,打开“工具” -> “开发板” -> “开发板管理器”,搜索“esp32”。找到由Espressif Systems提供的“esp32”平台,点击安装。这个过程可能会花费一些时间,取决于你的网络速度。
安装完成后,在“工具” -> “开发板”列表中,就能选择“ESP32 Wrover Module”或类似的型号。端口选择你连接ESP32后出现的串口。
1.2 连接硬件与基础测试
为了演示,我们假设一个最简单的场景:读取开发板内置的霍尔传感器(用于检测磁场变化)数值,并控制板载的LED灯(通常连接在GPIO2上)。这样我们无需任何外部传感器就能完成数据采集和控制的闭环。
首先,让我们写一个简单的测试程序,确保ESP32能正常工作并连接Wi-Fi。将以下代码上传到你的ESP32开发板。请务必将your_SSID和your_PASSWORD替换成你实际的Wi-Fi名称和密码。
// ESP32基础连接测试 #include <WiFi.h> const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; void setup() { Serial.begin(115200); pinMode(2, OUTPUT); // 初始化板载LED引脚(GPIO2)为输出模式 // 连接Wi-Fi WiFi.begin(ssid, password); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); digitalWrite(2, !digitalRead(2)); // 连接过程中LED闪烁 } Serial.println("\nConnected!"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); digitalWrite(2, HIGH); // 连接成功后LED常亮 } void loop() { // 主循环暂时空置,仅用于连接测试 delay(1000); }上传成功后,打开串口监视器(波特率设置为115200),你应该能看到ESP32成功连接到网络并打印出它的本地IP地址。记下这个IP地址,后续在Node-RED中可能会用到。
2. 五分钟部署Node-RED与Dashboard
Node-RED的安装比想象中简单得多。它是一个基于Node.js的流编程工具,我们将主要使用其强大的Dashboard节点库来构建UI。
2.1 一键安装Node-RED
如果你的电脑上还没有Node.js,需要先安装它。访问Node.js官网下载LTS版本的安装包,运行安装程序即可。安装完成后,打开终端(或命令提示符),输入以下命令来全局安装Node-RED:
npm install -g --unsafe-perm node-red注意:在某些系统(如Windows)上,可能需要以管理员权限运行终端。如果安装过程因网络问题缓慢或失败,可以尝试配置npm的国内镜像源,例如
npm config set registry https://registry.npmmirror.com。
安装完成后,直接在终端中输入node-red并回车,即可启动Node-RED服务。你会看到类似下面的日志输出,其中包含了访问地址(通常是http://127.0.0.1:1880)。
Welcome to Node-RED =================== ... Server now running at http://127.0.0.1:1880/打开浏览器,访问这个地址,你就进入了Node-RED的流程编辑器界面。
2.2 安装Dashboard节点库
Node-RED默认的节点并不包含我们需要的UI组件。我们需要安装node-red-dashboard这个第三方节点库。
在Node-RED编辑器的右上角,点击菜单图标(三条横线),选择“节点管理”。在打开的窗口中,切换到“安装”标签页,在搜索框中输入“dashboard”,找到node-red-dashboard并点击“安装”。安装完成后,点击右上角的“部署”按钮。
安装成功后,左侧节点面板会出现一个名为“dashboard”的新分组,里面包含了图表、按钮、滑块、文本显示等各种UI组件。
2.3 创建你的第一个数据面板
现在,让我们用3分钟创建一个最简单的面板。从左侧节点栏拖拽以下节点到工作区:
- 一个
inject节点(位于“输入”分组):用于定时触发数据流。 - 一个
function节点(位于“功能”分组):用于生成模拟的传感器数据。 - 一个
chart节点(位于“dashboard”分组):用于绘制折线图。 - 一个
gauge节点(位于“dashboard”分组):用于显示仪表盘。
双击inject节点,将其设置为每2秒重复注入一个时间戳。双击function节点,输入以下代码来生成一个模拟的随机温度值(范围20-30度):
// 生成模拟温度数据 msg.payload = (Math.random() * 10 + 20).toFixed(2); // 生成20.00到30.00之间的随机数 return msg;分别双击chart和gauge节点,在配置面板的“Group”一栏,点击右侧的铅笔图标,新建一个Dashboard组(例如命名为“环境监控”),并新建一个Tab页(例如命名为“主页”)。这样,这两个UI组件就会被归类到同一个面板组里。
最后,用连线将这些节点依次连接起来:inject->function->chart和gauge。点击右上角的红色“部署”按钮。
部署完成后,在浏览器中访问http://127.0.0.1:1880/ui,一个实时更新的温度监控面板就诞生了!整个过程甚至不需要写一行前端代码。
3. 打通ESP32与Node-RED:MQTT通信实战
要让ESP32的数据在Node-RED的面板上显示,我们需要一个通信桥梁。MQTT协议是物联网领域轻量级的“普通话”,非常适合这种场景。我们不需要搭建复杂的MQTT服务器,可以使用一个公共的测试Broker,或者在本机用Docker快速启动一个。
3.1 在Node-RED中配置MQTT输入
假设我们使用公共Brokertest.mosquitto.org(仅用于测试,生产环境请使用私有服务)。在Node-RED编辑器中,从左侧拖入一个mqtt in节点。
双击它进行配置:
- Server: 点击铅笔图标,添加一个新服务器。
- Server:
test.mosquitto.org - Port:
1883(非加密端口)
- Server:
- Topic: 填写一个你想要订阅的主题,例如
esp32/sensor/data。
点击“更新”,然后“完成”。这个节点就准备好接收来自该主题的消息了。
3.2 编写ESP32的MQTT发布代码
接下来,我们需要让ESP32将数据发布到同一个MQTT主题。在Arduino IDE中,你需要安装PubSubClient库。可以通过“工具” -> “管理库...”搜索并安装。
然后,使用以下完整的示例代码替换之前的测试程序。这段代码实现了:连接Wi-Fi和MQTT服务器,每5秒读取一次内部霍尔传感器数值和芯片温度,并将这些数据以JSON格式发布到指定主题。
#include <WiFi.h> #include <PubSubClient.h> #include <ArduinoJson.h> // WiFi 凭证 const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; // MQTT Broker 配置 const char* mqtt_broker = "test.mosquitto.org"; const int mqtt_port = 1883; const char* topic_pub = "esp32/sensor/data"; WiFiClient espClient; PubSubClient client(espClient); unsigned long lastMsgTime = 0; const long interval = 5000; // 发布间隔5秒 void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void reconnect() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); String client_id = "esp32-client-" + String(WiFi.macAddress()); if (client.connect(client_id.c_str())) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_broker, mqtt_port); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); unsigned long now = millis(); if (now - lastMsgTime > interval) { lastMsgTime = now; // 模拟读取传感器数据(实际项目中替换为真实传感器代码) float hall_value = hallRead(); // 读取内部霍尔传感器值 float temp_value = temperatureRead(); // 读取内部温度传感器值(注意:此函数可能因芯片型号和Arduino核心版本而异) // 创建JSON文档 StaticJsonDocument<200> doc; doc["device_id"] = WiFi.macAddress(); doc["hall"] = hall_value; doc["temperature"] = temp_value; doc["rssi"] = WiFi.RSSI(); // 序列化JSON到字符串 char json_buffer[200]; serializeJson(doc, json_buffer); // 发布消息 client.publish(topic_pub, json_buffer); Serial.print("Message published: "); Serial.println(json_buffer); } }提示:
temperatureRead()函数在某些ESP32核心库中可能需要额外配置或不可用。如果编译出错,可以将其替换为一个模拟的随机温度值,例如float temp_value = 25.0 + (random(0, 100) / 100.0);,这并不影响我们演示通信流程。
将代码中的Wi-Fi信息修改正确后,上传到ESP32。打开串口监视器,你应该能看到它成功连接MQTT Broker并定期发布JSON数据。
3.3 在Node-RED中解析并显示数据
回到Node-RED,我们将刚才创建的mqtt in节点与UI组件连接起来。但MQTT节点输出的msg.payload是JSON字符串,我们需要先解析它。
- 在
mqtt in节点后拖入一个json节点(位于“功能”分组),它负责将字符串自动解析为JavaScript对象。 - 在
json节点后拖入一个function节点。双击它,输入以下代码来提取我们需要的字段,并分配给不同的输出。这里我们创建了两个输出,分别对应霍尔值和温度值。
// 解析传感器数据并分配输出 var hall = msg.payload.hall; var temp = msg.payload.temperature; // 输出1:霍尔传感器数据 var msg1 = { payload: hall, topic: "hall" }; // 输出2:温度数据 var msg2 = { payload: temp, topic: "temp" }; return [msg1, msg2];- 将这个
function节点的两个输出,分别连接到之前创建好的chart节点和gauge节点(你可能需要调整或新建UI节点来匹配数据)。记得在UI节点的配置中,将“Value Format”设置为{{value}},并可以添加单位,如{{value}} °C。 - 点击“部署”。
现在,刷新你的Dashboard页面 (http://127.0.0.1:1880/ui)。你应该能看到来自真实ESP32开发板的传感器数据正在实时更新到图表和仪表盘上。至此,一个完整的、从硬件采集到云端可视化的物联网数据流已经跑通。
4. 进阶:双向交互与面板功能强化
数据显示只是基础,一个完整的控制面板还需要能反向控制设备。我们来实现通过Node-RED Dashboard上的按钮,控制ESP32的板载LED。
4.1 在Node-RED中创建控制界面
- 从Dashboard节点栏拖拽一个
button节点到工作区。 - 双击配置,将其分配到之前创建的“环境监控”组。将“Label”设置为“LED开关”, “Payload”类型选择“JSON”,并设置
{"led":1}表示开,{"led":0}表示关。你可以创建两个按钮,也可以使用一个带切换功能的按钮。 - 拖入一个
mqtt out节点。双击配置,连接到同一个test.mosquitto.org服务器,但主题设置为另一个,例如esp32/led/control。 - 将
button节点连接到mqtt out节点。
4.2 修改ESP32代码以订阅控制指令
我们需要修改ESP32的代码,使其同时订阅控制主题,并根据收到的JSON指令来操作GPIO2的LED。
在ESP32的setup()函数中,在MQTT连接成功后,添加订阅代码:
client.subscribe("esp32/led/control");然后,添加一个回调函数来处理接收到的消息。在setup()函数前或后定义此函数,并在setup()中用client.setCallback(callback);进行设置。
void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived on topic: "); Serial.println(topic); Serial.print("Message: "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // 尝试解析JSON StaticJsonDocument<100> doc; DeserializationError error = deserializeJson(doc, payload, length); if (error) { Serial.print("deserializeJson() failed: "); Serial.println(error.c_str()); return; } // 检查并控制LED if (doc.containsKey("led")) { int led_state = doc["led"]; digitalWrite(2, led_state); // 控制GPIO2 Serial.print("LED set to: "); Serial.println(led_state); } }将修改后的代码上传到ESP32。现在,当你点击Node-RED Dashboard上的按钮时,ESP32的板载LED就会随之点亮或熄灭。
4.3 面板布局优化与多数据源整合
一个专业的仪表盘离不开清晰的布局。Node-RED Dashboard的“Group”配置非常灵活,你可以通过设置“Width”和“Height”来调整UI组件的大小和排列方式。例如,可以将图表设置为“6 wide”,将仪表盘设置为“3 wide”,让它们并排显示。
| 组件类型 | 推荐宽度 | 用途说明 |
|---|---|---|
| 图表 (Chart) | 6 或 8 | 显示历史趋势数据,适合放在面板上方。 |
| 仪表盘 (Gauge) | 3 或 4 | 突出显示当前关键数值,如实时温度、压力。 |
| 文本显示 (Text) | 2 或 3 | 显示状态信息,如IP地址、连接状态。 |
| 按钮/开关 (Button/Switch) | 2 | 用于发送控制指令,可集中放在一个控制区域。 |
此外,你可以在一个流程中接入多个数据源。例如,除了ESP32,你还可以用同样的mqtt in节点订阅其他设备或模拟数据源的主题,经过function节点处理后,统一呈现在同一个Dashboard的不同Tab页或不同小组件中,轻松构建一个集中监控中心。
最后,当你完成整个流程的开发后,可以通过Node-RED编辑器右上角的“导出”功能,将你的流程(包括所有节点配置)保存为一个JSON文件。这份文件就是你的“完整代码”,可以分享给他人,或在不同环境中一键导入恢复,真正实现了项目的快速迁移和复用。
