Smart Granary Code

基于 ESP-IDF 的智能粮仓监测与联动控制固件,运行于 ESP32-S3。项目集成了光照、温湿度、气体、火焰、人体/门磁、重量等多类传感器,支持本地 UI、语音交互SU-03T以及 MQTT 远程上报与控制。

1. 项目概览

1.1 核心能力

  • 多传感器采集BH1750、AHT30、MQ-2、JW01、火焰传感器、HX711、人体/门磁
  • 本地显示LVGL + ST7789
  • 两种控制模式:manual(手动)/auto(自动联动)
  • 四路继电器执行:风扇、照明、制冷、加热
  • 语音模块SU-03T 查询与告警播报
  • 网络能力Wi-Fi AP 配网 + STA 联网 + MQTT 双向通信

1.2 默认运行行为

  • 上电默认 manual 模式
  • MQTT 上报周期1 秒
  • 门未关告警阈值60 秒
  • 粮食“变质”判定阈值:co2 >= 1500 ppm
  • 火焰危险阈值:fire_percent >= 35%

2. 硬件连接说明

以下为当前代码中的实际引脚定义。

2.1 I2C 设备

BH1750 与 AHT30 共享同一 I2C 总线:

设备 SCL SDA
BH1750 GPIO1 GPIO2
AHT30 GPIO1 GPIO2

2.2 继电器4 路)

继电器编号 功能 GPIO
1 风扇 GPIO12
2 照明灯 GPIO11
3 制冷片 GPIO10
4 加热器 GPIO9

2.3 ADC 传感器

设备 GPIO 说明
火焰传感器 GPIO3 百分比采样 + 危险判定
MQ-2 GPIO8 有害气体/烟雾百分比

2.4 UART 设备

设备 UART TX RX 波特率
JW01TVOC/HCHO/CO2 UART0 GPIO43 GPIO44 9600
SU-03T语音 UART2 GPIO42 GPIO41 115200

2.5 IO 输入

设备 GPIO 说明
HC-SR312 人体感应 GPIO16 高电平表示检测到人体
门磁开关 GPIO17 低电平表示门关闭

2.6 称重模块

设备 SCK DOUT
HX711 GPIO13 GPIO14

3. 软件架构

3.1 主要任务

  • sensor_task:周期读取多传感器并更新共享环境数据
  • ui_task:驱动 UI 刷新与界面变量更新
  • status_task:人体/门磁状态与开门超时告警
  • relay_status_task:同步继电器状态到 UI 与上报数据
  • hx711_task:称重采样、滤波、去皮与稳定显示
  • mqtt_publish_task:每秒打包 JSON 并发布 MQTT
  • su03t_auto_alert_task:语音告警节流上报(默认 3 分钟)
  • sntp_task:联网后 SNTP 对时

3.2 模式逻辑

  • manual:接收 MQTT 下发的继电器开关命令,自动联动逻辑不接管
  • auto:按阈值自动控制制冷/制热/风扇,照明不参与自动控制

4. 开发环境要求

4.1 基础要求

  • Linux 开发环境
  • ESP-IDF建议与当前工程一致版本需包含 idf.py
  • USB 驱动与串口权限正常

4.2 目标芯片与分区

  • Targetesp32s3
  • Flash Size16MB工程当前配置
  • 分区表:自定义 partitions.csv

partitions.csv 当前配置:

  • nvs0x9000, 0x6000
  • phy_init0xF000, 0x1000
  • factory0x10000, 4M

5. 快速开始

5.1 拉起工程

idf.py set-target esp32s3
idf.py build

5.2 烧录并查看日志

idf.py -p /dev/ttyUSB0 flash monitor

如果你使用的是 USB Serial/JTAG可根据实际端口替换 -p 参数。

5.3 VS CodeESP-IDF 插件)建议流程

  1. 先执行 Build
  2. 再执行 Flash
  3. 最后打开 Monitor 查看日志

6. menuconfig 关键配置

idf.py menuconfig

6.1 Wi-Fi 连接参数

菜单位置:WiFi 连接

配置项 说明 默认值
WIFI_CONNECT_CONNECT_TIMEOUT_SEC 连接超时(秒) 30
WIFI_CONNECT_MAX_SCAN_RESULTS 扫描结果上限 20
WIFI_CONNECT_AP_MAX_CONNECTIONS 配网 AP 最大连接数 4

6.2 MQTT 参数

菜单位置:MQTT 配置参数

配置项 说明 默认值
AGRI_ENV_MQTT_BROKER_URI MQTT 服务器地址
AGRI_ENV_MQTT_USERNAME MQTT 用户名
AGRI_ENV_MQTT_PASSWORD MQTT 密码
AGRI_ENV_MQTT_CLIENT_ID 客户端 ID agri-env-monitor
AGRI_ENV_MQTT_PUBLISH_TOPIC 发布主题 agri/env/data
AGRI_ENV_MQTT_SUBSCRIBE_TOPIC 订阅主题 agri/env/cmd

7. 配网说明

工程内置 AP 配网 + HTTP 控制台 + DNS 劫持流程:

  1. 设备启动 APSTA开启配网热点
  2. 手机连接热点后访问 http://192.168.4.1
  3. 页面扫描附近 Wi-Fi提交 SSID + 密码
  4. 设备连上路由后,页面可显示分配到的 STA IP

配网页面 API

  • GET /api/scan:扫描 AP 列表
  • POST /api/connect:提交联网参数
  • GET /api/status:查询连接状态
  • POST /api/clear:清除保存的 Wi-Fi 配置
  • GET /api/sysinfo:查看运行时信息

8. MQTT 协议说明(上位机对接)

8.1 协议与连接行为

  • MQTT 协议版本MQTT v3.1
  • 连接成功后自动订阅 AGRI_ENV_MQTT_SUBSCRIBE_TOPIC
  • 若 Broker URI 无协议头,内部会补全为 mqtt://,默认端口 1883
  • 当前发布参数QoS=0Retain=0每秒上报一次

8.2 主题定义

方向 主题 用途
设备 -> 上位机 agri/env/data 周期上报环境数据、状态、阈值
上位机 -> 设备 agri/env/cmd 模式切换、阈值更新、手动控制

8.3 上报 JSON 字段agri/env/data

字段 类型 说明
time string 设备本地时间,格式 YYYY-MM-DD HH:MM:SS
lux number 光照lux
temp number 温度(摄氏度)
humidity number 湿度(%RH
gas_percent number MQ-2 百分比(%
tvoc number JW01 TVOC
hcho number JW01 HCHO
co2 number JW01 CO2ppm
ice_weight number HX711 重量g
fire_percent number 火焰百分比(%
fire_danger boolean 火焰危险判定
human_present boolean 人体存在
door_closed boolean 门是否关闭true=关)
door_alarm boolean 门未关超时告警
door_open_seconds number 连续开门时长(秒)
fan_on boolean 风扇继电器状态
light_on boolean 照明继电器状态
cool_on boolean 制冷继电器状态
hot_on boolean 制热继电器状态
su03t_last_msgno number SU-03T 最近消息号
su03t_rx_count number SU-03T 累计收包次数
mode string automanual
th_temp_h number 制冷阈值
th_temp_l number 制热阈值
th_hum_h number 湿度阈值
th_gas_h number 气体阈值
ip_address string 当前 IP
food_status string good / spoilage
uptime_s number 运行时长(秒)
free_heap_kb number 剩余堆内存KB

上报示例:

{
  "time": "2026-04-22 16:24:39",
  "lux": 5,
  "temp": 30.8,
  "humidity": 65.4,
  "gas_percent": 9.7,
  "tvoc": 0,
  "hcho": 0,
  "co2": 350,
  "ice_weight": 0,
  "fire_percent": 0,
  "fire_danger": false,
  "human_present": false,
  "door_closed": false,
  "door_alarm": false,
  "door_open_seconds": 4,
  "fan_on": false,
  "light_on": false,
  "cool_on": false,
  "hot_on": false,
  "su03t_last_msgno": 0,
  "su03t_rx_count": 0,
  "mode": "manual",
  "th_temp_h": 35,
  "th_temp_l": 15,
  "th_hum_h": 70,
  "th_gas_h": 20,
  "ip_address": "192.168.1.12",
  "food_status": "good",
  "uptime_s": 1234,
  "free_heap_kb": 182
}

8.4 下发命令agri/env/cmd

字段按需携带,未携带字段保持原值。

字段 类型 说明
mode string auto / manual
th_temp_h number 更新制冷阈值
th_temp_l number 更新制热阈值
th_hum_h number 更新湿度阈值
th_gas_h number 更新气体阈值
fan boolean 手动控制风扇
light boolean 手动控制照明
cool boolean 手动控制制冷
hot boolean 手动控制制热

下发示例(自动模式):

{
  "mode": "auto",
  "th_temp_h": 28.5,
  "th_temp_l": 16.0,
  "th_hum_h": 65.0,
  "th_gas_h": 18.0
}

下发示例(手动模式):

{
  "mode": "manual",
  "fan": true,
  "cool": true,
  "hot": false,
  "light": false
}

8.5 SU-03T 语音命令协议

说明:

  • 串口为 UART2RX=GPIO41TX=GPIO42115200 波特率。
  • 语音模块上报命令时,固件按 msgno 匹配语义并立即回包。
  • 数值类回包使用 8 字节 little-endian double 作为参数区。
  • 状态类回包使用“仅 msgno、无参数”格式。

8.5.1 查询命令映射(模块 -> 设备)

命令词label key 请求 msgno
温度是多少 ask_temp 0x00
湿度是多少 ask_humi 0x01
光照强度是多少 ask_lux 0x02
烟雾浓度是多少 ask_mq2 0x03
二氧化碳浓度是多少 ask_co2 0x04
粮食重量是多少 ask_weight 0x05
有人在吗 ask_hum 0x06
门磁状态 ask_door 0x07
风扇继电器状态 ask_fan 0x08
照明继电器状态 ask_light 0x09
制冷继电器状态 ask_cool 0x0A
制热继电器状态 ask_hot 0x0B
当前控制模式 ask_control 0x0C
粮食状态 ask_rice 0x0D

8.5.2 回包映射(设备 -> 模块)

场景 回包 msgno 参数
温度查询返回 0x01 double温度
湿度查询返回 0x02 double湿度
光照查询返回 0x03 doublelux
烟雾查询返回 0x04 doublegas_percent
CO2 查询返回 0x05 doubleco2
重量查询返回 0x06 doubleice_weight
人体状态:有人 0x1A 无参数
人体状态:无人 0x1B 无参数
门磁状态:关门 0x0D 无参数
门磁状态:开门 0x0C 无参数
风扇:开 0x14 无参数
风扇:关 0x15 无参数
照明:开 0x20 无参数
照明:关 0x21 无参数
制冷:开 0x16 无参数
制冷:关 0x17 无参数
制热:开 0x18 无参数
制热:关 0x19 无参数
控制模式:自动 0x1C 无参数
控制模式:手动 0x1D 无参数
粮食状态:良好 0x1E 无参数
粮食状态:变质 0x1F 无参数

8.5.3 主动告警(设备周期上报)

说明:语音主动告警任务每 1 秒检查一次条件,同一类告警最小间隔为 180 秒。

触发条件 告警 msgno 参数
temp >= th_temp_h 0x10 double当前温度
humidity >= th_hum_h 0x11 double当前湿度
fire_danger = true 0x12 无参数
door_closed = false 0x13 无参数

9. 自动联动规则

仅在 mode=auto 时生效:

  • 制冷:temp >= th_temp_h 时开,否则关
  • 制热:temp <= th_temp_l 时开,否则关
  • 风扇:humidity >= th_hum_hgas_percent >= th_gas_h 时开,否则关
  • 照明:当前自动逻辑不控制照明

上电默认值:

  • mode = manual
  • th_temp_h = 35.0
  • th_temp_l = 15.0
  • th_hum_h = 70.0
  • th_gas_h = 20.0
  • door_open_alarm_seconds = 60

10. 目录结构(核心)

.
├── main/
│   └── main.cpp                # 系统入口与任务编排
├── components/
│   ├── wifi-connect/           # AP 配网、HTTP 控制台、STA 联网
│   ├── agri_env/               # MQTT 封装
│   ├── bh1750/                 # 光照传感器
│   ├── MQ-2/                   # 气体传感器
│   ├── JW01/                   # TVOC/HCHO/CO2 传感器
│   ├── fire_sensor/            # 火焰传感器
│   ├── human_door/             # 人体/门磁检测
│   ├── relay_ctrl/             # 四路继电器控制
│   ├── su-03t/                 # 语音模块协议
│   ├── lvgl_st7789_use/        # LCD + LVGL 显示
│   └── ui/                     # UI 页面与变量绑定
├── partitions.csv              # 分区表
├── sdkconfig                   # 当前工程配置
└── update_sdkconfig.sh         # 常用 sdkconfig 修补脚本

11. 常见问题与排障

11.1 设备始终无法联网

  • 检查是否连上设备热点并访问了 http://192.168.4.1
  • 检查路由器频段ESP32-S3 常用 2.4GHz
  • 在串口日志中观察 wifi_connect 状态机输出

11.2 MQTT 无法上报

  • 确认 AGRI_ENV_MQTT_BROKER_URI 是否有效
  • 确认设备已获取 STA IP且可访问 Broker
  • 检查鉴权参数(用户名/密码/Client ID

11.3 JW01 与日志冲突

JW01 使用 UART0GPIO43/44建议保持控制台输出为 USB Serial/JTAG避免 UART0 日志与传感器数据冲突。

11.4 HX711 波动大

  • 检查供电稳定性与接线
  • 系统已内置去皮、低通与稳定锁定逻辑,仍异常时优先排查硬件噪声

12. 开发建议

  • 新增组件时先补齐 components/<name>/include 对外接口,再在 main.cpp 挂接任务
  • MQTT 字段建议保持向后兼容:新增字段不删除旧字段
  • 上位机建议以 agri/env/data 最新数据作为控制确认(当前无独立 ACK 主题)

13. 许可证

当前仓库未提供独立 LICENSE 文件,如需对外发布,请补充开源许可证并在此处声明。

Description
智能粮仓的代码
Readme 23 MiB
Languages
C 75.4%
C++ 24.5%