ESP32+Web服务器实现室内环境数据采集

基于 ESP32-S3 开发板和 Arduino 框架,结合 ESPAsyncWebServer 实现一个本地环境采集与控制系统,包含温湿度、烟感、光照监测,以及蜂鸣器、WS2812 LED 联动控制,设计符合现代 UI 交互的 Web 界面。

PC端界面:

硬件架构与手机端界面:

一、需求分析

1.1 核心需求

本项目旨在基于 ESP32-S3 开发一款低成本、可视化、可交互的室内环境监测系统,满足以下核心诉求:

  • 多维度环境感知:实时采集温度、湿度、烟雾浓度、光照强度四类核心环境数据;

  • 智能联动控制:烟雾浓度超标时自动触发蜂鸣器报警,光照强度异常时自动控制 WS2812 LED 灯色变化;

  • 远程可视化交互:通过 WiFi 构建 Web 服务,提供手机 / 电脑端可视化界面,支持阈值配置、自动联动开关等交互操作;

  • 实时数据同步:采用 WebSocket 实现前端与设备的双向实时通信,配置修改即时生效,数据更新无延迟;

  • 移动端适配:优化界面布局,确保手机端一屏完整显示所有监测卡片,提升易用性。

1.2 非功能性需求

  • 稳定性:传感器数据采集频率 1Hz,连续运行无数据丢失;

  • 易用性:Web 界面操作直观,阈值调节、开关控制无需专业知识;

  • 兼容性:支持主流浏览器(Chrome、Edge、Safari),适配手机 / 平板 / 电脑等终端;

  • 可扩展性:代码模块化设计,便于后续新增传感器或功能。

二、功能分析

2.1 核心功能模块

|----------|----------------------------------------------------|
| 模块名称 | 功能描述 |
| 传感器数据采集 | 采集 DHT11 温湿度、MQ2 烟雾 ADC 值、BH1750 光照强度(lux),做异常值过滤 |
| 智能联动控制 | 1. 烟雾浓度超阈值 → PWM 间歇控制蜂鸣器报警;2. 光照强度联动 WS2812 LED 灯色 |
| Web 服务 | 提供 HTTP 服务,加载自定义可视化界面;WebSocket 实现双向实时通信 |
| 前端交互 | 1. 实时显示传感器数据;2. 调节烟雾 / 光照阈值;3. 开关自动联动功能;4. 状态可视化提示 |
| 数据通信 | JSON 序列化传感器 / 配置数据,WebSocket 广播同步至所有客户端 |

2.2 功能流程

三、核心实现

3.1 硬件层实现

3.1.1 硬件配置

|------------|---------------|------------------------------------|
| 硬件模块 | 引脚定义 | 功能说明 |
| DHT11 温湿度 | 13 | 模拟 / 数字混合传感器,采集温度(°C)、湿度(%) |
| MQ2 烟雾传感器 | 7 | 模拟输入,输出 0-4095 ADC 值表征烟雾浓度 |
| 无源蜂鸣器 | 20(PWM 通道 0) | 4500Hz 频率、80 占空比,间歇报警(500ms 响 / 停) |
| BH1750 光照 | SCL=39/SDA=40 | I2C 通信,输出 lux 级光照强度 |
| WS2812 LED | 48 | 单灯珠,根据光照强度显示蓝 / 绿 / 黄三色 |

3.1.2 硬件初始化(initHardware()
  • 初始化 DHT11、BH1750(I2C 总线)、WS2812 LED(初始关灯);
  • 配置 MQ2 引脚为输入模式,蜂鸣器 PWM 初始化(频率 4500Hz、8 位分辨率);
  • 异常处理:无(传感器初始化失败会导致后续数据为 0,串口可观测)。

3.2 数据采集层实现

3.2.1 数据结构设计
复制代码
// 传感器数据结构体:存储核心感知数据
struct SensorData {
  float temperature;  // 温度 (°C)
  float humidity;     // 湿度 (%)
  int mq2Value;       // 烟感模拟值
  float lightValue;   // 光照值 (lux)
  unsigned long updateTime; // 最后更新时间
};

// 报警配置结构体:存储可配置参数
struct AlarmConfig {
  int mq2Threshold;   // 烟感报警阈值(默认800)
  bool mq2AutoAlarm;  // 烟感自动报警开关(默认开启)
  bool mq2AlarmState; // 烟感报警状态(是否超阈值)
  int lightLowThreshold;  // 光照低阈值(100lux,蓝灯)
  int lightHighThreshold; // 光照高阈值(500lux,黄灯)
  bool lightAutoMode;     // 光照自动联动开关(默认开启)
};
3.2.2 数据采集逻辑(updateSensorData()
  • 温湿度采集 :调用 dht.readTemperature()/dht.readHumidity(),过滤 nan 异常值(置 0);
  • 烟雾采集analogRead(MQ2_PIN) 读取 12 位 ADC 值(0-4095);
  • 光照采集lightMeter.readLightLevel() 读取 lux 值,过滤 nan 异常值;
  • 报警状态更新 :对比 MQ2 ADC 值与阈值,更新 mq2AlarmState(仅表征是否超阈值,与蜂鸣器解耦)。

3.3 智能控制层实现

3.3.1 烟雾报警逻辑(handleMQ2Alarm()
  • 核心逻辑:仅当「自动报警开关开启」且「烟雾超阈值」时触发报警;
  • 报警方式:PWM 间歇控制(millis() % 1000 < 500),蜂鸣器 500ms 响、500ms 停,避免持续噪音;
  • 边界处理:自动报警关闭时,强制关闭蜂鸣器,防止误报警。
3.3.2 光照 LED 联动(handleLightLED()
  • 核心逻辑:仅当「自动联动开关开启」时生效,否则关闭 LED;
  • 灯色规则:
  • 光照 < 100lux → 蓝色(环境光弱);
  • 100lux ≤ 光照 ≤ 500lux → 绿色(正常);
  • 光照 > 500lux → 黄色(环境光强);
  • 亮度控制:固定 50% 亮度(strip.setBrightness(128)),避免刺眼。

3.4 通信层实现

3.4.1 JSON 数据序列化(getSensorJson()
  • 使用 StaticJsonDocument<256> 轻量化序列化,包含:
  • 传感器数据:温度、湿度、MQ2 ADC、光照强度;
  • 配置数据:烟雾阈值、自动报警开关、光照高低阈值、自动联动开关;
  • 状态数据:烟雾报警状态;
  • 优势:结构化数据,前端解析便捷,传输体积小。
3.4.2 WebSocket 通信(onWsEvent()
  • 双向通信逻辑:
  • 设备 → 前端:每秒广播一次序列化后的传感器 / 配置数据;
  • 前端 → 设备:接收前端修改的配置(阈值、开关),更新本地 alarmConfig,立即调用 handleMQ2Alarm()/handleLightLED() 应用配置;
  • 异常处理:JSON 解析失败时打印错误日志,不影响系统运行。

3.5 Web 服务层实现

3.5.1 服务器初始化
  • 异步 Web 服务器:AsyncWebServer server(80),非阻塞式处理 HTTP 请求,避免影响传感器采集;
  • WebSocket 挂载:server.addHandler(&ws),绑定 /ws 路径用于实时通信;
  • 静态页面路由:根路径 / 返回内嵌的 HTML 界面,无需外置文件系统。
3.5.2 前端界面核心设计
  • 布局优化
  • 栅格布局(grid-template-columns),适配多终端;
  • 手机端(<480px)单列显示,卡片内边距 / 字体精简,一屏完整显示 3 个卡片;
  • 交互组件
  • 滑块(input[type="range"]):调节烟雾 / 光照阈值,实时显示当前值;
  • 开关(自定义 slider):控制自动报警 / LED 联动;
  • 状态徽章:不同颜色 + 文字提示当前状态(正常 / 报警 / 光线弱 / 强);
  • 实时更新 :WebSocket 监听 onmessage 事件,接收数据后更新 DOM,状态徽章动态切换样式。

3.6 主循环逻辑

  • 定时采集:millis() 实现 1 秒定时,避免 delay() 阻塞;
  • 流程顺序:采集数据 → 执行联动控制 → 广播数据 → 串口调试输出;
  • 资源清理:ws.cleanupClients() 清理闲置 WebSocket 客户端,释放内存。

四、编程流程

4.1 整体编程流程

  1. 预处理阶段:引入依赖库,定义硬件引脚/参数,声明全局对象/结构体;

  2. 工具函数定义:硬件初始化、数据采集、联动控制、数据序列化、WebSocket 事件处理;

  3. 前端界面定义:内嵌 HTML/CSS/JS,实现可视化与交互;

  4. setup() 函数: - 串口初始化 → 硬件初始化 → WiFi 连接 → Web 服务器/WebSocket 启动;

  5. loop() 函数: - 每秒执行:数据采集 → 联动控制 → 数据广播 → 串口输出; - 持续清理闲置 WebSocket 客户端,保证稳定性。

4.2 核心亮点

  • 定时采集使用 millis() 而非 delay(),确保系统响应性。
4.2.3 解耦设计
  • 报警状态与执行逻辑解耦:mq2AlarmState 仅表征是否超阈值,handleMQ2Alarm() 负责执行报警,便于扩展多方式报警;
  • 前端与设备解耦:通过 JSON 标准化数据交互,前端修改不影响设备核心逻辑。
4.2.4 移动端适配
  • 响应式布局:媒体查询(@media (max-width: 480px))适配手机端;
  • 卡片高度优化:精简内边距 / 字体 / 间距,确保手机一屏显示所有内容。

五、代码与使用

5.1 完整代码

代码仓库:https://gitee.com/vopo123/esp32-dev-kit

5.2 使用说明

1. 硬件接线(ESP32-S3)

|------------|-----------------|--------------|
| 模块 | ESP32-S3 引脚 | 备注 |
| DHT11 数据 | 13 | 需接上拉电阻(4.7K) |
| MQ2 模拟输出 | 7 | 模拟输入,无需额外电阻 |
| 无源蜂鸣器 | 20 | 需串 220Ω 限流电阻 |
| BH1750 SCL | 39 | I2C 时钟线 |
| BH1750 SDA | 40 | I2C 数据线 |
| WS2812 数据 | 48 | 需接 5V 供电 |

2. 环境准备
  1. 安装所需库(Arduino 库管理器中搜索):
  • ESPAsyncWebServer(需手动安装:https://github.com/me-no-dev/ESPAsyncWebServer
  • AsyncTCP(ESP32 内置,ESP8266 需手动安装)
  • DHT sensor library(Adafruit 版本)
  • Adafruit NeoPixel
  • BH1750
  • ArduinoJson(v7 版本)
  1. 修改代码中 ssidpassword 为你的 WiFi 名称 / 密码;
  2. 选择开发板:Tools → Board → ESP32 Arduino → ESP32-S3 Dev Module
3. 功能操作
  1. 上传代码后,打开串口监视器,查看 ESP32-S3 分配的 IP 地址;
  2. 在浏览器中输入该 IP 地址,即可进入 Web 界面;
  3. 界面操作:
  • 烟感阈值:拖动滑块设置报警值,开启 "自动报警" 后,超过阈值蜂鸣器间歇报警;
  • 光照阈值:设置低 / 高阈值,开启 "LED 自动联动" 后,WS2812 自动按光照强度变蓝 / 绿 / 黄;
  • 所有配置实时生效,无需重启开发板。
相关推荐
Lupino12 小时前
OpenClaw 都能帮我养鱼了?从“零起点”到跨界控制物联网增氧机
物联网·openai
物联网IoT小易21 小时前
设备管理到底在管什么?从“资产台账”到“持续运营”的能力升级
物联网·iot·物联网平台·iot平台
小龙报21 小时前
【数据结构与算法】别再只会写 demo!C 语言通讯录实战:从单链表底层到业务功能全封装
c语言·开发语言·数据结构·c++·物联网·算法·链表
pingao14137821 小时前
雨量监测新方案:简易设备+智慧无线报警系统
物联网
易知微EasyV数据可视化1 天前
数字孪生+AI:某世界级物联网企业-产线数智化升级,点亮智造之路v
人工智能·经验分享·物联网·信息可视化·数字孪生·空间智能
零一iTEM2 天前
如何解决ArduinoIDE2.0环境下ESP32开发环境安装不了的问题!
c++·单片机·物联网·iot
学AI不秃头2 天前
一键部署到 Jetson:在 PC 上开发,点击一下自动同步代码 + 配环境 + 运行(demo 开源)
人工智能·深度学习·计算机视觉·开源·智能硬件
BY组态2 天前
智捷云:快捷、智能、高效的物联网解决方案提供商
物联网·3d·iot·web组态·组态
CORNERSTONE3652 天前
如何利用变革性新技术(如云计算、物联网、低代码)驱动公司创新与转型
物联网·低代码·数字化转型·企业转型