1. 项目概述与设计思路
这个基于STM32的教室环境监测系统是我在嵌入式开发领域的一次完整实践。作为一名长期从事物联网开发的工程师,我发现很多学校的教室环境管理仍停留在人工巡检阶段,存在响应滞后、管理粗放等问题。这个项目正是为了解决这些痛点而设计的。
系统采用STM32F103C8T6作为主控芯片,这是一款性价比极高的Cortex-M3内核MCU,72MHz主频完全能满足实时性要求。通过集成DHT11温湿度传感器、光敏电阻、PM2.5传感器和雨滴检测模块,实现了对教室环境的全方位监测。特别值得一提的是,系统设计了双模控制机制——既可以根据预设阈值自动调节环境设备,也支持手动干预,这种灵活性在实际应用中非常重要。
2. 硬件设计详解
2.1 核心电路设计
主控电路采用经典的STM32最小系统设计:
- 电源部分使用AMS1117-3.3V稳压芯片,为MCU和部分外设提供稳定电压
- 复位电路采用10kΩ电阻搭配0.1μF电容的典型配置
- 8MHz晶振配合内部PLL实现72MHz系统时钟
特别注意:ESP8266模块必须使用3.3V供电,直接接5V会立即烧毁模块。我在初期调试时就因此损失了两个WIFI模块。
2.2 传感器接口设计
各传感器接口设计有其特点:
- DHT11温湿度传感器:单总线协议,DATA线需要接10kΩ上拉电阻
- 光敏电阻:与10kΩ固定电阻组成分压电路,接入STM32的ADC1通道0
- PM2.5传感器:选用夏普GP2Y1010AU0F,需要特别注意其LED驱动信号时序
- 雨滴检测:简单的模拟电压检测,潮湿时输出电压降低
传感器布局建议:
- 温湿度传感器避免靠近窗户或空调出风口
- 光敏传感器应安装在教室内光线最具代表性的位置
- PM2.5传感器要远离粉尘源(如粉笔槽)
3. 软件架构与关键实现
3.1 主程序流程
系统采用典型的前后台架构:
c复制int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
MX_ADC1_Init();
sensors_init();
oled_init();
wifi_init();
while (1) {
read_sensors();
process_data();
update_display();
check_mode();
handle_control();
wifi_process();
key_scan();
HAL_Delay(100);
}
}
3.2 数据采集优化
传感器数据采集采用了多重滤波算法:
- 滑动平均滤波:对ADC采集的模拟量进行10次采样取平均
- 中值滤波:对DHT11的数字量采集进行异常值剔除
- 阈值限幅:防止因干扰导致的突变值
以光照采集为例:
c复制#define SAMPLE_NUM 10
uint16_t read_light_sensor(void) {
uint32_t sum = 0;
uint16_t samples[SAMPLE_NUM];
for(int i=0; i<SAMPLE_NUM; i++) {
samples[i] = HAL_ADC_GetValue(&hadc1);
HAL_Delay(5);
}
// 中值滤波
bubble_sort(samples, SAMPLE_NUM);
// 取中间6个值做平均
for(int i=2; i<SAMPLE_NUM-2; i++) {
sum += samples[i];
}
return sum/(SAMPLE_NUM-4);
}
4. 控制逻辑实现
4.1 自动控制策略
系统预设了智能控制策略:
- 温度控制:
-
28°C:启动风扇
- <18°C:启动加热片
-
- 光照控制:
- <300lux:开启补光灯
- 空气质量:
- PM2.5>75μg/m³:触发报警
- 窗户控制:
- 检测到降雨:自动关窗
这些阈值都可以通过按键调整,适应不同季节需求。
4.2 手动控制实现
手动模式下,通过6个独立按键控制:
- 模式切换键:自动/手动模式切换
- 风扇控制键
- 加热控制键
- 灯光控制键
- 窗户控制键
- 阈值设置键(长按进入设置模式)
按键处理采用状态机实现,有效消除了抖动干扰:
c复制typedef enum {
KEY_IDLE,
KEY_DEBOUNCE,
KEY_PRESSED,
KEY_LONG_PRESS
} KeyState;
void key_scan(void) {
static KeyState state = KEY_IDLE;
static uint32_t press_time = 0;
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) {
switch(state) {
case KEY_IDLE:
state = KEY_DEBOUNCE;
press_time = HAL_GetTick();
break;
case KEY_DEBOUNCE:
if(HAL_GetTick() - press_time > 20) {
state = KEY_PRESSED;
}
break;
case KEY_PRESSED:
if(HAL_GetTick() - press_time > 1000) {
state = KEY_LONG_PRESS;
// 长按处理
}
break;
}
} else {
if(state == KEY_PRESSED) {
// 短按处理
}
state = KEY_IDLE;
}
}
5. 无线通信实现
5.1 ESP8266配置
使用AT指令配置ESP8266:
- 设置为STA模式:AT+CWMODE=1
- 连接WiFi:AT+CWJAP="SSID","password"
- 启用多连接:AT+CIPMUX=1
- 连接机智云服务器:AT+CIPSTART=0,"TCP","api.gizwits.com",80
实际测试发现,ESP8266在复杂WiFi环境下可能出现断连。我们的解决方案是:
- 增加心跳包机制(每30秒发送一次)
- 断线后自动重连
- 重要数据本地缓存
5.2 机智云接入
机智云平台接入关键步骤:
- 在开发者中心创建新产品
- 定义数据点(温度、湿度等)
- 生成设备密钥
- 实现通信协议:
- 数据上报格式:{devid};
- 指令接收格式:{cmd}:
示例数据上报代码:
c复制void report_to_cloud(float temp, float humi) {
char buffer[64];
sprintf(buffer, "{\"temp\":%.1f,\"humi\":%.1f}", temp, humi);
uart_send("AT+CIPSEND=0,%d\r\n", strlen(buffer));
HAL_Delay(100);
uart_send(buffer);
}
6. 系统优化与调试
6.1 功耗优化
虽然教室有持续供电,但我们仍做了低功耗设计:
- 传感器采用间歇工作模式(采集后进入休眠)
- OLED屏幕设置15秒无操作自动降低亮度
- ESP8266在无数据传输时进入轻睡眠模式
实测整机工作电流:
- 全速运行:约120mA
- 优化后:平均85mA
6.2 抗干扰措施
在教室环境中遇到的主要干扰:
- WiFi信号拥堵
- 日光灯频闪影响光敏传感器
- 人员走动导致的温湿度波动
解决方案:
- 为ESP8266配置专用天线
- 光敏传感器增加遮光罩
- 温湿度传感器增加机械防护
- 所有信号线使用双绞线
7. 实际应用效果
经过三个月实地测试(安装在某中学高二3班),系统表现:
- 温度控制精度:±1.5°C
- 湿度控制精度:±5%RH
- 光照控制响应时间:<3秒
- WiFi通信稳定性:98.7%
用户反馈:
- 老师特别赞赏自动关窗功能,雨季再也不用担心雨水潲入
- 管理人员通过手机APP就能查看多个教室环境状况
- 学生反映补光及时,晚自习眼睛更舒适
成本核算(单套):
- STM32F103C8T6:¥12
- 传感器组:¥45
- ESP8266:¥15
- 其他元器件:¥28
- 总成本:约¥100
8. 常见问题解决
在实际部署中遇到的典型问题:
-
DHT11偶尔读取失败
- 检查接线是否松动
- 增加读取超时重试机制
- 必要时更换传感器
-
OLED显示残影
- 降低刷新频率
- 使用官方驱动库的清屏函数
- 避免长时间显示静态内容
-
ESP8266连接不稳定
- 检查天线安装
- 尝试更换WiFi信道
- 更新AT固件到最新版本
-
继电器误动作
- 在控制端增加光耦隔离
- 线圈两端并联续流二极管
- 避免与大功率设备共用电源
这个项目从构思到实现历时两个月,期间经历了多次方案调整和优化。最大的收获是认识到嵌入式系统开发中"细节决定成败"——一个10kΩ的上拉电阻没接好,就可能导致整个系统不稳定。建议初学者在类似项目中:
- 先搭建最小系统,逐步添加功能
- 重要信号线一定要加保护措施
- 留足调试接口(如串口打印)
- 文档记录每个修改和发现的问题