Files
Wang Beihong a0febb1e5b feat: 智能家居控制系统 v1.0 初始版本
- 环境监测:温湿度/光照/空气质量传感器采集
- 智能控制:时间段/降温/通风三种自动模式
- 闹钟系统:3个闹钟+温和唤醒功能
- 远程控制:MQTT双向通信
- 本地显示:LVGL图形界面
- 双MCU架构,FreeRTOS 10任务并行
- 完整的1250行README文档
2026-02-07 23:04:28 +08:00

1251 lines
41 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IoT-Home 智能家居控制系统
[![ESP-IDF](https://img.shields.io/badge/ESP--IDF-5.5.2-blue.svg)](https://github.com/espressif/esp-idf)
[![ESP32-C3](https://img.shields.io/badge/Chip-ESP32--C3-green.svg)](https://www.espressif.com/zh-hans/products/socs/esp32-c3)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-1.0-orange.svg)](VERSION)
一个基于 ESP32-C3 的完整智能家居控制系统集成了环境传感器采集、智能自动控制、远程MQTT通信、本地可视化显示等功能。
---
## 目录
- [项目简介](#项目简介)
- [硬件清单](#硬件清单)
- [系统架构](#系统架构)
- [功能特性](#功能特性)
- [快速开始](#快速开始)
- [配置说明](#配置说明)
- [API文档](#api文档)
- [故障排查](#故障排查)
- [技术栈](#技术栈)
---
## 项目简介
### 基本信息
- **项目名称**: IoT-Home 智能家居控制系统
- **目标芯片**: ESP32-C3 (RISC-V 单核 160MHz)
- **开发框架**: ESP-IDF 5.5.2
- **项目类型**: 智能家居控制系统
- **作者**: beihong.wang
- **版本**: 1.0
- **创建日期**: 2026-01-19
### 功能概述
本项目是一个功能完善的智能家居控制系统,主要特性包括:
1. **环境监测**: 集成温湿度、光照强度、空气质量三种传感器
2. **智能控制**: 根据时间段和环境数据自动控制窗帘、照明、风扇
3. **闹钟系统**: 支持多闹钟,具备温和唤醒功能(提前开窗帘)
4. **远程控制**: 基于MQTT协议的云端双向通信
5. **本地显示**: LVGL图形界面实时显示环境数据
6. **双MCU架构**: ESP32主控 + 副MCU扩展控制能力
7. **持久化配置**: 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~85°C湿度0~100% |
| **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 lux
- `MODERATE` (光照适中): 200-500 lux
- `DIM` (光照不足): < 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
```bash
# 克隆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. 编译项目
```bash
cd /home/beihong/esp_projects/iot-home
idf.py build
```
#### 2. 烧录到设备
```bash
idf.py flash
```
#### 3. 监控串口输出
```bash
idf.py monitor
```
#### 4. 一键烧录+监控
```bash
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`:
```ini
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`:
```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引脚分配
```c
// 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显示配置
```c
// 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`:
```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 // 光照不足阈值
```
### 时间段默认配置
```c
// 白天模式 (默认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`
```json
{
"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`
```json
{
"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命令示例
#### 控制风扇
```bash
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"
}
}
}'
```
#### 控制窗帘
```bash
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亮度
```bash
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
}
}
}'
```
#### 设置闹钟
```bash
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"
}
}
}'
```
#### 设置降温阈值
```bash
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
}
}
}'
```
#### 设置时间段
```bash
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 | 页面切换 | 切换时间/传感器页面 |
### 监听传感器数据
```bash
mosquitto_sub -h beihong.wang -t topic/sensor/esp32_iothome_001
```
---
## 故障排查
### 传感器初始化失败
**现象**: 日志显示 "AHTxx初始化失败" 或 "BH1750初始化失败"
**解决方案**:
1. 检查I2C接线 (SCL=GPIO5, SDA=GPIO4)
2. 确认I2C总线上有上拉电阻 (通常4.7kΩ)
3. 检查I2C地址冲突 (AHT30: 0x38, BH1750: 0x23)
4. 确认传感器供电 (3.3V)
5. 使用I2C扫描工具检测设备
### MQTT连接失败
**现象**: 日志显示 "MQTT_EVENT_ERROR"
**解决方案**:
1. 检查Wi-Fi连接状态
2. 验证Broker地址和端口 (mqtt://beihong.wang:1883)
3. 检查用户名密码是否正确
4. 确认防火墙允许1883端口
5. 使用 `mosquitto_sub` 测试Broker连接
### 显示异常
**现象**: 屏幕无显示或花屏
**解决方案**:
1. 检查SPI接线 (CLK, MOSI, CS, DC, RST, BL)
2. 验证LCD供电 (3.3V或5V根据模块规格)
3. 检查背光控制GPIO6连接
4. 确认LCD型号为ST7735S
5. 检查SPI时钟频率 (40MHz可能过高尝试降低到20MHz)
### 舵机不工作
**现象**: 窗帘无法开合
**解决方案**:
1. 检查GPIO10连接
2. 确认舵机供电 (需要5V, ESP32的3.3V可能驱动不足)
3. 检查PWM配置 (50Hz, 脉宽1-2ms)
4. 校准角度范围 (30°-195°)
5. 确认舵机型号为SG90或兼容型号
### 风扇不工作
**现象**: 风扇无法开启
**解决方案**:
1. 检查GPIO1连接
2. 确认风扇供电 (通常5V或12V)
3. 检查风扇驱动电路 (可能需要晶体管驱动)
4. 使用万用表测试GPIO1电平变化
5. 确认风扇控制逻辑 (高电平开/低电平关)
### MQ135读数异常
**现象**: 空气质量读数过大或过小
**解决方案**:
1. 确认传感器预热时间 (MQ135需要预热24-48小时)
2. 检查ADC连接 (ADC1_CH0 / GPIO34)
3. 确认负载电阻RL=10kΩ连接正确
4. 在干净空气中重启设备进行R0校准
5. 调整初始R0值 (代码中的R0变量)
### 时间同步失败
**现象**: 时间显示不正确
**解决方案**:
1. 检查网络连接
2. 确认NTP服务器可访问 (cn.pool.ntp.org)
3. 检查防火墙是否允许UDP 123端口
4. 查看日志中的SNTP同步结果
5. 手动设置时区代码 (当前为CST-8)
### NVS存储失败
**现象**: 配置无法保存或启动时丢失
**解决方案**:
1. 检查分区表是否包含NVS分区
2. 使用 `idf.py erase-flash` 擦除Flash后重新烧录
3. 检查NVS分区大小 (至少需要4KB)
4. 查看日志中的NVS初始化信息
5. 使用 `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