# 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