跳转到内容

智能家居传感器数据采集

智能家居传感器数据采集

本节介绍如何在智能家居面板上采集和显示传感器数据。学习完成后,您将能够:

  • 集成常见传感器(温湿度、光照、PIR)到智能家居系统
  • 在 LVGL 界面上实时显示传感器数据
  • 实现传感器数据的定时刷新和 MQTT 上报
  • 理解传感器数据在智能家居场景中的联动方式

在开始本节之前,请确保:

  • 已完成 LVGL UI 设计基础
  • 了解 ESP32 传感器采集方法
  • 传感器模块已接线到 ESP32
传感器型号测量内容接口GPIO
温湿度DHT22 / BME280温度、湿度单总线 / I2CGPIO 4 / I2C
光照BH1750光照强度 (lux)I2CI2C
人体存在HC-SR501 PIR人体移动检测GPIOGPIO 14
空气质量CCS811eCO2, TVOCI2CI2C
声音MAX9814环境声音ADCGPIO 36
#include <DHT.h>
#include <BH1750.h>
#include <Wire.h>
class SensorManager {
private:
// 温湿度传感器
DHT dht;
BH1750 lightMeter;
// 读取间隔
const unsigned long READ_INTERVAL = 5000; // 5秒
unsigned long lastReadTime = 0;
public:
// 传感器数据缓存
float temperature = 0;
float humidity = 0;
float lux = 0;
bool motionDetected = false;
SensorManager() : dht(4, DHT22) {} // GPIO 4
bool begin() {
dht.begin();
Wire.begin(21, 22); // SDA, SCL
if (!lightMeter.begin()) {
Serial.println("BH1750 未找到");
return false;
}
pinMode(14, INPUT); // PIR 传感器
return true;
}
void update() {
unsigned long now = millis();
if (now - lastReadTime < READ_INTERVAL) return;
lastReadTime = now;
// 读取温湿度
temperature = dht.readTemperature();
humidity = dht.readHumidity();
// 读取光照
lux = lightMeter.readLightLevel();
// 读取 PIR
motionDetected = digitalRead(14) == HIGH;
// 打印调试
Serial.printf("传感器: %.1f°C, %.1f%%, %.0f lux, 运动: %s\n",
temperature, humidity, lux,
motionDetected ? "" : "");
}
};
SensorManager sensors;
// 温度显示标签
lv_obj_t* tempLabel;
lv_obj_t* humLabel;
lv_obj_t* luxLabel;
void create_sensor_display() {
// 温度
tempLabel = lv_label_create(screen);
lv_label_set_text(tempLabel, "--.-°C");
lv_obj_set_style_text_font(tempLabel, &lv_font_montserrat_32, 0);
lv_obj_set_style_text_color(tempLabel, lv_palette_main(LV_PALETTE_CYAN), 0);
lv_obj_align(tempLabel, LV_ALIGN_TOP_LEFT, 20, 20);
// 湿度
humLabel = lv_label_create(screen);
lv_label_set_text(humLabel, "--%");
lv_obj_set_style_text_font(humLabel, &lv_font_montserrat_24, 0);
lv_obj_set_style_text_color(humLabel, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_align_to(humLabel, tempLabel, LV_ALIGN_OUT_RIGHT_MID, 30, 0);
// 光照
luxLabel = lv_label_create(screen);
lv_label_set_text(luxLabel, "-- lux");
lv_obj_set_style_text_font(luxLabel, &lv_font_montserrat_16, 0);
lv_obj_set_style_text_color(luxLabel, lv_palette_main(LV_PALETTE_YELLOW), 0);
lv_obj_align_to(luxLabel, humLabel, LV_ALIGN_OUT_RIGHT_MID, 30, 0);
}
// 定时更新传感器数据显示
void update_sensor_display() {
sensors.update();
// 更新标签文本
char buf[16];
sprintf(buf, "%.1f°C", sensors.temperature);
lv_label_set_text(tempLabel, buf);
sprintf(buf, "%.0f%%", sensors.humidity);
lv_label_set_text(humLabel, buf);
sprintf(buf, "%.0f lux", sensors.lux);
lv_label_set_text(luxLabel, buf);
}
// LVGL 实时数据图表
lv_obj_t* chart;
void create_chart() {
chart = lv_chart_create(screen);
lv_obj_set_size(chart, 280, 120);
lv_obj_align(chart, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 50);
lv_chart_set_point_count(chart, 30); // 30 个数据点
// 温度系列
lv_chart_series_t* tempSerie = lv_chart_add_series(
chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
// 初始化数据
for (int i = 0; i < 30; i++) {
tempSerie->y_points[i] = LV_CHART_POINT_DEF;
}
}
// 更新图表
void update_chart(float temperature) {
static int index = 0;
// 添加新数据点
lv_chart_set_next_value(chart, NULL, (int)(temperature * 10));
index++;
if (index >= 30) index = 0;
// 刷新图表显示
lv_chart_refresh(chart);
}
void publish_sensor_data() {
StaticJsonDocument<128> doc;
doc["temp"] = sensors.temperature;
doc["hum"] = sensors.humidity;
doc["lux"] = sensors.lux;
doc["motion"] = sensors.motionDetected;
doc["rssi"] = WiFi.RSSI();
char buffer[128];
serializeJson(doc, buffer);
mqttClient.publish("home/panel/sensors", buffer);
}
// 定时发布(每 30 秒)
void loop() {
static unsigned long lastPublish = 0;
lv_timer_handler();
// 更新传感器数据(每 5 秒)
update_sensor_display();
// 发布数据(每 30 秒)
if (millis() - lastPublish > 30000) {
lastPublish = millis();
publish_sensor_data();
// 更新图表
update_chart(sensors.temperature);
}
delay(5);
}
// PIR 传感器使显示屏自动唤醒
void check_motion_auto_wake() {
if (sensors.motionDetected) {
// 点亮屏幕
ledcWrite(0, 255); // 背光 PWM 最大
// 重置自动熄屏计时
lastMotionTime = millis();
}
// 3 分钟无运动自动熄屏
if (millis() - lastMotionTime > 180000) {
ledcWrite(0, 0); // 关闭背光
}
}
传感器展示方式买家价值
温湿度大数字 + 图表趋势”温湿度一目了然,历史变化可视化”
光照数值 + 自动调光建议”根据环境光自动调节室内亮度”
人体检测图标 + 时长统计”人来屏亮,人走屏灭”
空气质量颜色指示器”空气质量差时自动开启空气净化器”

本节介绍了传感器数据在智能家居面板上的采集和显示:

  1. 传感器集成:DHT22 温湿度、BH1750 光照、PIR 运动检测
  2. LVGL 数据展示:实时数据标签、历史趋势图表
  3. MQTT 发布:定时上报传感器数据到 MQTT 系统
  4. 智能交互:PIR 运动检测实现屏幕自动唤醒/熄屏
  5. 数据联动:传感器数据可以触发场景自动化(详见 14-11)