IoT-Home 智能家居控制系统
一个基于 ESP32-C3 的完整智能家居控制系统,集成了环境传感器采集、智能自动控制、远程MQTT通信、本地可视化显示等功能。
目录
项目简介
基本信息
- 项目名称: IoT-Home 智能家居控制系统
- 目标芯片: ESP32-C3 (RISC-V 单核 160MHz)
- 开发框架: ESP-IDF 5.5.2
- 项目类型: 智能家居控制系统
- 作者: beihong.wang
- 版本: 1.0
- 创建日期: 2026-01-19
功能概述
本项目是一个功能完善的智能家居控制系统,主要特性包括:
- 环境监测: 集成温湿度、光照强度、空气质量三种传感器
- 智能控制: 根据时间段和环境数据自动控制窗帘、照明、风扇
- 闹钟系统: 支持多闹钟,具备温和唤醒功能(提前开窗帘)
- 远程控制: 基于MQTT协议的云端双向通信
- 本地显示: LVGL图形界面,实时显示环境数据
- 双MCU架构: ESP32主控 + 副MCU扩展控制能力
- 持久化配置: NVS存储所有配置参数
硬件清单
主控芯片
| 参数 | 说明 |
|---|---|
| 芯片型号 | ESP32-C3 |
| 架构 | RISC-V 32位 |
| 运行频率 | 160 MHz |
| Flash | 4 MB |
| SRAM | 400 KB |
| 无线模块 | Wi-Fi 2.4GHz + BLE 5.0 |
传感器模块
| 传感器型号 | 功能 | 接口 | GPIO | 说明 |
|---|---|---|---|---|
| AHT30 | 温湿度传感器 | I2C | SCL=5, SDA=4 | 温度-40 |
| BH1750 | 光照强度传感器 | I2C | SCL=5, SDA=4 | 测量范围1~65535 lux |
| MQ135 | 空气质量传感器 | ADC | ADC1_CH0 (GPIO34) | 有害气体浓度检测 |
执行器件
| 设备 | 功能 | 接口 | GPIO | 控制方式 |
|---|---|---|---|---|
| SG90舵机 | 窗帘开合控制 | PWM | GPIO10 | 30°=关, 195°=开 |
| LED灯 | 照明控制 | 串口 | UART1_TX | 亮度0-100% |
| 风扇 | 通风降温 | GPIO | GPIO1 | 高低电平控制 |
| 蜂鸣器 | 声音提示 | 串口 | UART1_TX | 开关控制 |
| LCD屏幕 | 本地显示 | SPI | GPIO2,3,6,7,8,9 | ST7735S 160x80 |
通信接口
| 接口 | 用途 | 配置 |
|---|---|---|
| Wi-Fi | 网络通信 | 2.4GHz, WPA2/WPA3 |
| UART1 | 副MCU通信 | 230400 baud, TX=GPIO21, RX=GPIO20 |
| I2C | 传感器总线 | 100kHz, SCL=GPIO5, SDA=GPIO4 |
| SPI2 | LCD显示 | 40MHz, SPI2_HOST |
系统架构
整体架构图
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 │
├──────────────┬──────────────┬──────────────┬───────────────┤
│ 传感器采集 │ 自动控制 │ 设备控制 │ 通信上报 │
│ │ │ │ │
│ - AHT30 │ - 时间段控制 │ - 窗帘控制 │ - MQTT发布 │
│ - BH1750 │ - 降温模式 │ - LED控制 │ - MQTT订阅 │
│ - MQ135 │ - 通风模式 │ - 风扇控制 │ - 命令解析 │
│ │ │ - 蜂鸣器控制 │ │
├──────────────┴──────────────┴──────────────┴───────────────┤
│ FreeRTOS 任务层 (10个任务) │
├─────────────────────────────────────────────────────────────────┤
│ ESP-IDF 组件层 │
├──────────┬──────────┬──────────┬──────────┬──────────────┤
│ I2C驱动 │ SPI驱动 │ UART驱动 │ MQTT组件 │ NVS组件 │
├──────────┴──────────┴──────────┴──────────┴──────────────┤
│ 硬件抽象层 (HAL) │
├─────────────────────────────────────────────────────────────────┤
│ ESP32-C3 硬件层 │
└─────────────────────────────────────────────────────────────────┘
任务架构
系统使用 FreeRTOS 多任务架构,10个任务协同工作:
| 任务名称 | 优先级 | 栈大小 | 周期 | 功能描述 |
|---|---|---|---|---|
i2c0_ahtxx_task |
5 | 4096 | 5秒 | AHT30温湿度采集 |
i2c0_bh1750_task |
5 | 4096 | 5秒 | BH1750光照采集 |
mq135_task |
5 | 4096 | 5秒 | MQ135空气质量采集 |
mqtt_publish_task |
5 | 4096 | 3/50秒 | MQTT数据发布 |
peripheral_control_task |
5 | 4096 | 100ms | 外设控制执行 |
alarm_clock_main_task |
5 | 8192 | 1秒 | 闹钟时间检查 |
time_period_task |
5 | 4096 | 10秒 | 时间段智能控制 |
cooling_mode_task |
5 | 4096 | 5秒 | 降温模式监控 |
ventilation_mode_task |
5 | 4096 | 5秒 | 通风模式监控 |
uart_rx_task |
24 | 4096 | 事件驱动 | UART按键接收 |
同步机制
为防止数据竞争,系统使用4个互斥锁保护共享资源:
| 互斥锁 | 保护对象 | 用途 |
|---|---|---|
xSensorDataMutex |
g_sensor_data |
保护传感器数据读写 |
xMqttMessageMutex |
g_device_message |
保护MQTT消息构建 |
xTimePeriodMutex |
g_day_period, g_night_period |
保护时间段配置 |
xControlFlagMutex |
所有控制标志 | 保护设备控制状态 |
功能特性
1. 环境监测
AHT30 温湿度传感器
- 采集周期: 5秒
- 温度范围: -40°C ~ 85°C (精度±0.3°C)
- 湿度范围: 0% ~ 100% (精度±2%)
- 错误处理: 初始化失败时自动重试,标记数据无效
BH1750 光照传感器
- 采集周期: 5秒
- 测量模式: 连续测量,1lux分辨率
- 数据范围: 1 ~ 65535 lux
- 光强状态判断:
BRIGHT(光照充足): > 500 luxMODERATE(光照适中): 200-500 luxDIM(光照不足): < 200 lux
MQ135 空气质量传感器
- 采集方式: ADC1 12位采样
- 测量原理: Rs/R0 = 116.602 × ppm^(-2.769)
- 动态校准: 启动后50次采样平均计算R0值
- 数据范围: 1.0 ~ 1000.0 ppm
- 空气质量等级:
范围 等级 颜色 ≤ 20 ppm 优秀 (Excellent) 绿色 21-100 ppm 良好 (Good) 黑色 101-300 ppm 轻度污染 (Moderate) 橙色 > 300 ppm 中重度污染 (High) 红色
2. 智能自动控制
时间段智能控制
系统根据当前时间段和环境光强自动控制窗帘和照明:
白天模式 (默认 6:00-18:00):
- 光照充足 (>500 lux): 关窗帘 + 关灯
- 光照不足 (<200 lux): 开窗帘 + 开灯(亮度80%)
- 光照适中 (200-500 lux): 开窗帘(利用自然光) + 关灯
晚上模式 (默认 18:00-6:00):
- 自动关闭窗帘
- 开启照明(亮度50%)
特性:
- NVS持久化时间段配置
- 支持跨天时间段配置(如18:00-6:00)
- 10秒检查周期,快速响应光强变化
- 手动控制检测,避免冲突
降温模式
根据室内温度自动控制风扇:
- 温度阈值: 默认28°C (可通过MQTT配置,范围10-40°C)
- 控制逻辑:
- 温度 > 阈值: 自动开启风扇
- 温度 < (阈值-1°C): 自动关闭风扇 (1°C滞后防止抖动)
- 高温提醒:
- 温度 > 35°C: 触发蜂鸣器 + MQTT推送 "温度过高请注意通风"
- 温度恢复正常: 自动关闭提醒
- 配置: NVS持久化温度阈值
自动通风模式
根据空气质量自动通风:
- 空气质量阈值: 50 ppm
- 控制逻辑:
- 空气质量 > 50 ppm: 开启风扇 + 蜂鸣器短促提示(200ms)
- 空气质量 < 40 ppm: 关闭风扇 (10ppm滞后)
- 提醒机制: MQTT推送 "卧室需要通风" (仅推送一次)
3. 闹钟系统
多闹钟支持
- 闹钟数量: 3个独立闹钟
- 时间格式: HH:MM:SS
- 触发机制: ESP定时器每秒检查时间
- 持续时间: 蜂鸣器响5秒后自动关闭
温和唤醒功能
闹钟1特有功能: 提前3分钟自动打开窗帘,让自然光温和唤醒用户
- 前提: 闹钟已启用
- 触发时间: 闹钟时间前3分钟
- 动作: 舵机转到开窗帘位置(195°)
- 标志: 设置
curtain_opened标志防止重复
配置管理
- NVS自动保存闹钟时间和开关状态
- 支持MQTT远程设置闹钟
- 支持独立启用/禁用每个闹钟
4. 设备控制
窗帘控制
- 执行器件: SG90舵机
- 控制方式: LEDC定时器0, 50Hz PWM
- 角度范围: 30°(关) ~ 195°(开)
- 校准: 支持自定义校准值
LED照明控制
- 控制方式: UART1发送给副MCU
- 亮度范围: 0-100%
- 控制协议:
帧头: 0x55 命令: 0x01 (LED控制) 数据: 亮度值 (0-100)
风扇控制
- 控制方式: GPIO1直接高低电平
- 状态: 开/关
- 应用: 降温模式、通风模式、手动控制
蜂鸣器控制
- 控制方式: UART1发送给副MCU
- 控制协议:
帧头: 0x55 命令: 0x02 (蜂鸣器控制) 数据: 0(关)/1(开) - 应用场景: 闹钟、高温提醒、空气质量提醒
屏幕背光控制
- 控制方式: GPIO6直接高低电平
- 特性: 根据在家状态自动控制
5. MQTT通信
连接配置
- Broker: mqtt://beihong.wang:1883
- 认证: 用户名/密码认证
- 客户端ID: esp32_+MAC后3位
- QoS: 发布QoS0, 订阅QoS2
主题设计
| 方向 | 主题 | 说明 |
|---|---|---|
| 发布 | topic/sensor/esp32_iothome_001 |
传感器数据上报 |
| 订阅 | topic/control/esp32_iothome_001 |
控制命令接收 |
上报频率
- 在家模式: 3秒周期
- 离家模式: 50秒周期
6. 本地显示
LVGL图形界面
- LCD: ST7735S, 160x80分辨率
- 颜色格式: RGB565 (16位色)
- 刷新率: 约30FPS (33ms)
- 特性: 双缓冲,提高流畅度
界面页面
时间页面 (默认):
- 日期和星期
- 时间 (HH:MM:SS)
- 大字体显示
传感器页面:
- 温度 (保留2位小数)
- 湿度 (保留2位小数)
- 光照强度 (保留2位小数)
- 空气质量指数 + 颜色分级
页面切换
- 触发: UART按键6 (0xAA 0x06 0x55)
- 显示: 默认时间页面,按键切换到传感器页面
7. MCU间通信
UART协议
- 波特率: 230400
- 数据位: 8
- 停止位: 1
- 校验: 无
接收协议 (副MCU → ESP32)
- 格式: AA [01-06] 55 (3字节)
- 按键映射:
按键 命令 功能 按键1 0x01 LED开关 按键2 0x02 风扇开关 按键3 0x03 窗帘开关 按键4 0x04 蜂鸣器开关 按键5 0x05 屏幕背光 按键6 0x06 页面切换
8. 时间同步
SNTP配置
- 时区: 北京时间 (CST-8)
- NTP服务器:
- cn.pool.ntp.org
- ntp1.aliyun.com
- 协议: NTP v4 (UDP 123端口)
- 自动同步: 启动后自动同步
快速开始
环境准备
安装ESP-IDF
# 克隆ESP-IDF仓库
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
# 切换到v5.5.2版本
git checkout v5.5.2
git submodule update --init --recursive
# 安装依赖
./install.sh esp32c3
# 激活环境
source ./export.sh
依赖组件
本项目使用以下managed components,会自动下载:
espp__wifi: Wi-Fi连接示例组件- LVGL相关组件: 图形界面库
编译与烧录
1. 编译项目
cd /home/beihong/esp_projects/iot-home
idf.py build
2. 烧录到设备
idf.py flash
3. 监控串口输出
idf.py monitor
4. 一键烧录+监控
idf.py flash monitor
首次启动流程
系统上电启动详细流程
┌─────────────────────────────────────────────────────────────────────┐
│ ESP32-C3 上电启动 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 1. 系统初始化 (app_main) │
│ - 设置日志级别 │
│ - 初始化NVS(非易失性存储) │
│ - 创建事件循环 │
│ - 初始化ESP-NETIF │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. Wi-Fi连接 │
│ - 配置Wi-Fi参数 (SSID/Password) │
│ - 扫描并连接到AP │
│ - 最多重试6次 │
│ - 打印AP信息 (MAC, RSSI, 信道) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. 硬件外设初始化 │
│ - I2C总线初始化 (100kHz, SCL=GPIO5, SDA=GPIO4) │
│ - 舵机初始化 (GPIO10, LEDC定时器0, 50Hz) │
│ - GPIO输出初始化 (风扇GPIO1) │
│ - UART1初始化 (230400 baud, TX=GPIO21, RX=GPIO20) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. LVGL图形界面初始化 │
│ - SPI总线配置 (40MHz, SPI2_HOST) │
│ - LCD驱动初始化 (ST7735S, 160x80) │
│ - LVGL库初始化 │
│ - 创建UI组件 (时间页面、传感器页面) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. 串口通信初始化 │
│ - serial_mcu_init() │
│ - 配置UART1接收中断 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. MQTT客户端启动 │
│ - 配置MQTT连接参数 │
│ - 启动MQTT客户端 │
│ - 等待连接建立 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 7. 互斥锁创建 │
│ - xSensorDataMutex (传感器数据保护) │
│ - xMqttMessageMutex (MQTT消息保护) │
│ - xTimePeriodMutex (时间段配置保护) │
│ - xControlFlagMutex (控制标志保护) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 8. NVS配置加载 │
│ - 从NVS加载降温模式配置 (温度阈值) │
│ - 从NVS加载时间段配置 (白天/晚上模式) │
│ - 从NVS加载闹钟配置 (3个闹钟时间和状态) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 9. 创建FreeRTOS任务 │
│ 按5级优先级依次创建以下10个任务: │
│ │
│ 优先级24 (最高): │
│ ├─ uart_rx_task [4096字节] 事件驱动 │
│ │
│ 优先级5: │
│ ├─ i2c0_ahtxx_task [4096字节] 5秒周期 │
│ ├─ i2c0_bh1750_task [4096字节] 5秒周期 │
│ ├─ mq135_task [4096字节] 5秒周期 (预热期短) │
│ ├─ mqtt_publish_task [4096字节] 3/50秒周期 │
│ ├─ peripheral_control_task [4096字节] 100ms周期 │
│ ├─ alarm_clock_main_task [8192字节] 1秒周期 │
│ ├─ time_period_task [4096字节] 10秒周期 │
│ ├─ cooling_mode_task [4096字节] 5秒周期 │
│ └─ ventilation_mode_task [4096字节] 5秒周期 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 10. 主循环启动 │
│ 主任务进入while(1)循环,定期打印传感器数据 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ 系统运行状态 │
│ (所有任务并行) │
└─────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌──────────┐
│传感器采集 │ │ 自动控制 │ │MQTT通信 │
│ 任务组 │ │ 任务组 │ │ 任务组 │
└─────────┘ └──────────┘ └──────────┘
各任务启动后执行流程
1. AHT30温湿度采集任务 (i2c0_ahtxx_task)
启动 → 初始化I2C → 等待AHT30就绪 → 读取温湿度数据
↓ (每5秒)
更新g_sensor_data → 更新LVGL显示 → 互斥锁保护 → 循环
2. BH1750光照采集任务 (i2c0_bh1750_task)
启动 → 初始化I2C → 配置连续测量模式 → 读取光照数据
↓ (每5秒)
更新g_sensor_data → 更新LVGL显示 → 判断光强状态 → 循环
3. MQ135空气质量采集任务 (mq135_task)
启动 → 初始化ADC → 预热阶段(100次采样,约8分钟)
↓
校准阶段(100次采样,计算R0) → 温湿度补偿 → 滑动平均滤波
↓ (每5秒)
计算Rs/R0 → 应用MQ135公式 → 异常检测 → 更新数据 → 循环
4. MQTT发布任务 (mqtt_publish_task)
启动 → 等待MQTT连接 → 检查在家/离家状态
↓
在家模式: 每3秒发布传感器数据
离家模式: 每50秒发布传感器数据
↓
构建JSON消息 → 互斥锁保护 → 发布到Broker → 循环
5. 外设控制任务 (peripheral_control_task)
启动 → 读取当前控制标志 → 检测状态变化
↓ (每100ms)
状态变化 → 执行硬件控制 (舵机/风扇/蜂鸣器/LED)
↓
更新遥测数据 → 上报状态 → 记录上次状态 → 循环
6. 闹钟主任务 (alarm_clock_main_task)
启动 → 初始化SNTP → 从NVS加载3个闹钟配置
↓
创建定时器 (每1秒检查) → 等待定时器回调
↓ (每1秒)
检查当前时间 → 对比闹钟时间
├─ 匹配闹钟1: 提前3分钟开窗帘 → 时间到触发蜂鸣器
├─ 匹配闹钟2: 直接触发蜂鸣器
└─ 匹配闹钟3: 直接触发蜂鸣器
↓
更新闹钟触发状态 → 循环
7. 时间段智能控制任务 (time_period_task)
启动 → 获取当前时间 → 判断白天/晚上模式
↓ (每10秒)
读取光照强度 → 判断光强状态 (充足/适中/不足)
↓
根据模式和光强决定控制策略
├─ 白天+光照充足: 关窗帘+关灯
├─ 白天+光照不足: 开窗帘+开灯(80%)
├─ 白天+光照适中: 开窗帘+关灯
└─ 晚上: 关窗帘+开灯(50%)
↓
检查手动控制冲突 → 互斥锁保护 → 执行控制 → 上报状态 → 循环
8. 降温模式任务 (cooling_mode_task)
启动 → 从NVS加载温度阈值 → 初始化高温提醒标志
↓ (每5秒)
读取当前温度 → 与阈值比较
├─ 温度 > 阈值: 开启风扇
├─ 温度 < (阈值-1°C): 关闭风扇 (滞后防抖)
└─ 温度 > 35°C: 触发高温提醒 (蜂鸣器+MQTT推送)
↓
互斥锁保护 → 执行控制 → 更新标志 → 循环
9. 通风模式任务 (ventilation_mode_task)
启动 → 初始化空气质量阈值 → 初始化提醒标志
↓ (每5秒)
读取当前空气质量 → 与阈值比较
├─ 质量 > 50ppm: 开启风扇 + 蜂鸣器短促提示
│ 发送MQTT提醒 "卧室需要通风"
└─ 质量 < 40ppm: 关闭风扇 (滞后防抖) + 重置提醒标志
↓
互斥锁保护 → 执行控制 → 更新标志 → 循环
10. UART接收任务 (uart_rx_task)
启动 → 等待副MCU按键数据
↓ (事件驱动)
接收完整帧 (AA cmd 55)
├─ 0x01: LED开关 → 翻转light_source_control_flag
├─ 0x02: 风扇开关 → 翻转fan_control_flag
├─ 0x03: 窗帘开关 → 翻转servo_control_flag
├─ 0x04: 蜂鸣器开关 → 翻转buzzer_control_flag
├─ 0x05: 背光开关 → 翻转led_backlight_on
└─ 0x06: 页面切换 → 调用ui_toggle_page()
↓
互斥锁保护 → 更新状态 → 上报MQTT → 继续等待
MQTT事件处理流程
MQTT事件回调
│
├─ MQTT_EVENT_CONNECTED:
│ └─ 订阅控制主题 → 准备接收远程命令
│
├─ MQTT_EVENT_DATA:
│ └─ 接收到控制命令JSON
│ │
│ ├─ 解析设备ID和类型 (验证是否匹配)
│ ├─ 解析message_type
│ │
│ └─ 根据controls执行操作:
│ ├─ fan_state: open/close → 设置风扇
│ ├─ curtain_state: open/close → 设置窗帘
│ ├─ led_state: open/close + led_power → 设置LED
│ ├─ buzzer_state: open/close → 设置蜂鸣器
│ ├─ alarm1_time/enable → 配置闹钟1
│ ├─ alarm2_time/enable → 配置闹钟2
│ ├─ alarm3_time/enable → 配置闹钟3
│ ├─ day_period_start/end → 配置白天时间段
│ ├─ night_period_start/end → 配置晚上时间段
│ └─ temperature_threshold → 配置降温阈值
│
└─ MQTT_EVENT_DISCONNECTED:
└─ 等待自动重连
系统状态同步流程
本地操作 (按键/自动控制)
│
↓
更新控制标志 (互斥锁保护)
│
├─ → 外设控制任务检测到变化
│ ↓
│ 执行硬件控制 (GPIO/UART/PWM)
│ ↓
│ 更新遥测数据
│
└─ → MQTT发布任务周期性上报
↓
发送传感器数据到云端
↓
远程端(小程序/服务器)接收状态
│
↓
用户查看/控制
│
↓
发送MQTT控制命令
│
↓
ESP32接收并执行
│
└─ 循环
传感器数据流向
┌──────────┐
│ AHT30 │ → 温度/湿度 → g_sensor_data → LVGL显示 + MQTT上报
└──────────┘
┌──────────┐
│ BH1750 │ → 光照强度 → g_sensor_data → LVGL显示 + 时间段控制
└──────────┘
┌──────────┐
│ MQ135 │ → 空气质量 → g_sensor_data → LVGL显示 + 通风控制
│ (预热期)│ → 校准R0 → 温湿度补偿 → 滑动平均滤波
└──────────┘
数据存储与恢复
配置保存 (NVS存储):
- 降温模式温度阈值 (cooling_mode_namespace)
- 时间段配置 (day_period, night_period)
- 闹钟配置 (3个闹钟的时间和开关状态)
配置加载:
- 启动时自动从NVS读取
- MQTT可远程修改并自动保存
- 断电后配置自动恢复
配置说明
Wi-Fi配置
编辑 sdkconfig:
CONFIG_EXAMPLE_WIFI_SSID="Your_WiFi_SSID"
CONFIG_EXAMPLE_WIFI_PASSWORD="Your_WiFi_Password"
CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY=6
MQTT配置
编辑 main/main.c:
// MQTT Broker地址
#define MQTT_BROKER_URL "mqtt://your-broker.com:1883"
// 认证信息
#define MQTT_USERNAME "your_username"
#define MQTT_PASSWORD "your_password"
// 设备标识
#define MQTT_CLIENT_ID "esp32_your_device_id"
// 主题配置
#define MQTT_PUBLISH_TOPIC_QOS0 "topic/sensor/esp32_your_device_id"
#define MQTT_NOTIFY_TOPIC "topic/control/esp32_your_device_id"
GPIO引脚分配
// I2C总线 (传感器)
I2C_SCL: GPIO5
I2C_SDA: GPIO4
// SPI总线 (LCD屏幕)
SPI_CLK: GPIO2
SPI_MOSI: GPIO3
LCD_CS: GPIO7
LCD_DC: GPIO8
LCD_RST: GPIO9
LCD_BL: GPIO6
// PWM (舵机)
SERVO_PWM: GPIO10
// GPIO控制
FAN_CONTROL: GPIO1
// ADC (空气质量传感器)
MQ135_ADC: ADC1_CH0 (GPIO34)
// UART1 (副MCU通信)
UART_TX: GPIO21
UART_RX: GPIO20
LVGL显示配置
// LCD分辨率
#define EXAMPLE_LCD_H_RES 160
#define EXAMPLE_LCD_V_RES 80
// SPI配置
#define EXAMPLE_LCD_SPI_NUM SPI2_HOST
#define EXAMPLE_LCD_PIXEL_CLK_HZ (40 * 1000 * 1000) // 40MHz
#define EXAMPLE_LCD_BITS_PER_PIXEL 16
// 绘图缓冲
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT 50
自动控制阈值
编辑 main/main.c:
// 降温模式
float g_temperature_threshold = 28.0f; // 温度阈值
const float HIGH_TEMP_THRESHOLD = 35.0f; // 高温提醒阈值
// 通风模式
#define AIR_QUALITY_THRESHOLD 50.0f // 空气质量阈值
// 光照判断阈值
#define LIGHT_BRIGHT_THRESHOLD 500.0f // 光照充足阈值
#define LIGHT_DIM_THRESHOLD 200.0f // 光照不足阈值
时间段默认配置
// 白天模式 (默认6:00-18:00)
time_period_config_t g_day_period = {
.start_hour = 6,
.start_minute = 0,
.end_hour = 18,
.end_minute = 0,
.enabled = true
};
// 晚上模式 (默认18:00-6:00)
time_period_config_t g_night_period = {
.start_hour = 18,
.start_minute = 0,
.end_hour = 6,
.end_minute = 0,
.enabled = true
};
API文档
MQTT消息格式
传感器数据上报
发布主题: topic/sensor/esp32_iothome_001
{
"type": "device_message",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"timestamp": 1701234567890,
"message_type": "sensor_data",
"data": {
"state": {
"online": true,
"current_mode": "day_mode",
"standby_mode": false,
"error_code": 0
},
"telemetry": {
"temperature": 25.50,
"humidity": 60.30,
"light_intensity": 350.00,
"air_quality": 45.00,
"curtain_state": "open",
"led_state": "close",
"led_power": 0,
"fan_state": "close",
"buzzer_state": "close"
}
}
}
控制命令接收
订阅主题: topic/control/esp32_iothome_001
{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"fan_state": "open|close",
"curtain_state": "open|close",
"led_state": "open|close",
"led_power": 0-100,
"buzzer_state": "open|close",
"alarm1_time": "HH:MM:SS",
"alarm1_enable": "on|off",
"alarm2_time": "HH:MM:SS",
"alarm2_enable": "on|off",
"alarm3_time": "HH:MM:SS",
"alarm3_enable": "on|off",
"day_period_start": "HH:MM",
"day_period_end": "HH:MM",
"night_period_start": "HH:MM",
"night_period_end": "HH:MM",
"temperature_threshold": 28.0
}
}
}
MQTT命令示例
控制风扇
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"fan_state": "open"
}
}
}'
控制窗帘
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"curtain_state": "close"
}
}
}'
设置LED亮度
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"led_state": "open",
"led_power": 80
}
}
}'
设置闹钟
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"alarm1_time": "07:30:00",
"alarm1_enable": "on"
}
}
}'
设置降温阈值
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"temperature_threshold": 26.0
}
}
}'
设置时间段
mosquitto_pub -h beihong.wang -t topic/control/esp32_iothome_001 -m \
'{
"type": "control_command",
"device_id": "esp32_bedroom_001",
"device_type": "bedroom_controller",
"message_type": "device_control",
"data": {
"controls": {
"day_period_start": "07:00",
"day_period_end": "19:00",
"night_period_start": "19:00",
"night_period_end": "07:00"
}
}
}'
本地按键控制
通过副MCU的物理按键控制:
| 按键 | 功能 | 说明 |
|---|---|---|
| 按键1 | LED开关 | 切换照明灯开关 |
| 按键2 | 风扇开关 | 切换风扇开关 |
| 按键3 | 窗帘开关 | 切换窗帘开/合 |
| 按键4 | 蜂鸣器开关 | 切换蜂鸣器开关 |
| 按键5 | 背光开关 | 切换屏幕背光 |
| 按键6 | 页面切换 | 切换时间/传感器页面 |
监听传感器数据
mosquitto_sub -h beihong.wang -t topic/sensor/esp32_iothome_001
故障排查
传感器初始化失败
现象: 日志显示 "AHTxx初始化失败" 或 "BH1750初始化失败"
解决方案:
- 检查I2C接线 (SCL=GPIO5, SDA=GPIO4)
- 确认I2C总线上有上拉电阻 (通常4.7kΩ)
- 检查I2C地址冲突 (AHT30: 0x38, BH1750: 0x23)
- 确认传感器供电 (3.3V)
- 使用I2C扫描工具检测设备
MQTT连接失败
现象: 日志显示 "MQTT_EVENT_ERROR"
解决方案:
- 检查Wi-Fi连接状态
- 验证Broker地址和端口 (mqtt://beihong.wang:1883)
- 检查用户名密码是否正确
- 确认防火墙允许1883端口
- 使用
mosquitto_sub测试Broker连接
显示异常
现象: 屏幕无显示或花屏
解决方案:
- 检查SPI接线 (CLK, MOSI, CS, DC, RST, BL)
- 验证LCD供电 (3.3V或5V,根据模块规格)
- 检查背光控制GPIO6连接
- 确认LCD型号为ST7735S
- 检查SPI时钟频率 (40MHz可能过高,尝试降低到20MHz)
舵机不工作
现象: 窗帘无法开合
解决方案:
- 检查GPIO10连接
- 确认舵机供电 (需要5V, ESP32的3.3V可能驱动不足)
- 检查PWM配置 (50Hz, 脉宽1-2ms)
- 校准角度范围 (30°-195°)
- 确认舵机型号为SG90或兼容型号
风扇不工作
现象: 风扇无法开启
解决方案:
- 检查GPIO1连接
- 确认风扇供电 (通常5V或12V)
- 检查风扇驱动电路 (可能需要晶体管驱动)
- 使用万用表测试GPIO1电平变化
- 确认风扇控制逻辑 (高电平开/低电平关)
MQ135读数异常
现象: 空气质量读数过大或过小
解决方案:
- 确认传感器预热时间 (MQ135需要预热24-48小时)
- 检查ADC连接 (ADC1_CH0 / GPIO34)
- 确认负载电阻RL=10kΩ连接正确
- 在干净空气中重启设备进行R0校准
- 调整初始R0值 (代码中的R0变量)
时间同步失败
现象: 时间显示不正确
解决方案:
- 检查网络连接
- 确认NTP服务器可访问 (cn.pool.ntp.org)
- 检查防火墙是否允许UDP 123端口
- 查看日志中的SNTP同步结果
- 手动设置时区代码 (当前为CST-8)
NVS存储失败
现象: 配置无法保存或启动时丢失
解决方案:
- 检查分区表是否包含NVS分区
- 使用
idf.py erase-flash擦除Flash后重新烧录 - 检查NVS分区大小 (至少需要4KB)
- 查看日志中的NVS初始化信息
- 使用
nvs_partition_generator工具重新生成NVS分区
技术栈
| 类别 | 技术栈 | 说明 |
|---|---|---|
| 芯片平台 | ESP32-C3 | RISC-V架构,160MHz |
| 操作系统 | FreeRTOS | 实时操作系统 |
| 开发框架 | ESP-IDF 5.5.2 | 乐鑫官方开发框架 |
| 通信协议 | MQTT 3.1.1 | 物联网通信协议 |
| 网络协议 | TCP/IP (LwIP) | 轻量级TCP/IP协议栈 |
| 无线协议 | Wi-Fi 802.11 b/g/n | 2.4GHz无线网络 |
| 时间同步 | SNTP (NTP v4) | 网络时间协议 |
| 图形库 | LVGL 9.4.0 | 轻量级图形库 |
| 数据格式 | JSON (cJSON库) | 数据交换格式 |
| 存储 | NVS | 非易失性存储 |
| 编译器 | GCC (RISC-V) | RISC-V交叉编译器 |
| 构建系统 | CMake + Ninja | 跨平台构建系统 |
项目结构
iot-home/
├── main/ # 主程序目录
│ ├── main.c # 主程序文件 (3025行)
│ ├── CMakeLists.txt # 构建配置
│ └── idf_component.yml # 组件依赖
├── components/ # 自定义组件
│ ├── lvgl_st7735s_use/ # LVGL显示组件
│ ├── serial_mcu/ # 串口通信组件
│ ├── ahtxx/ # 温湿度传感器组件
│ ├── bh1750/ # 光照传感器组件
│ └── iot_servo/ # 舵机控制组件
├── managed_components/ # 管理组件 (自动下载)
│ └── espp__wifi/ # Wi-Fi连接组件
├── build/ # 编译输出目录
├── sdkconfig # ESP-IDF配置文件
├── partitions.csv # 分区表
└── README.md # 本文档
许可证
MIT License
作者
beihong.wang
更新日志
v1.0 (2026-01-19)
- 初始版本发布
- 完整的智能家居控制功能
- MQTT远程控制
- LVGL本地显示
- 多闹钟系统
- 自动通风和降温模式
贡献
欢迎提交Issue和Pull Request!
联系方式
如有问题或建议,请通过以下方式联系:
- 提交Issue
- 发送邮件
文档生成时间: 2026年2月7日 文档版本: 1.0