这个基于STM32F103C8T6的空气质量检测系统是我最近完成的一个嵌入式项目,它能够实时监测室内环境的温湿度、一氧化碳、甲醛和PM2.5浓度。当检测到有害物质超标时,系统会自动触发声光报警并启动通风设备。整套系统成本控制在200元以内,非常适合DIY爱好者或者需要监测室内空气质量的家庭用户。
我在设计这个系统时主要考虑了三个核心需求:首先是检测的全面性,要能覆盖常见的室内空气污染物;其次是响应速度,从检测到报警的延迟要控制在1秒以内;最后是操作的便捷性,支持本地按键和手机APP两种控制方式。
选择STM32F103C8T6作为主控芯片主要基于以下几点考虑:
实际使用中发现,这款芯片的ADC参考电压稳定性很好,在不同环境温度下测量值波动不超过±0.1V,这对气体浓度检测的准确性很关键。
选用DHT11主要看中它的单总线接口和免校准特性。接线时需要注意:
实测数据显示,在25℃环境下,温度测量误差±1℃,湿度误差±3%RH,完全满足室内监测需求。
一氧化碳检测使用MQ-7传感器,它的预热时间需要特别注意:
甲醛检测选用三合一VOC传感器,使用时发现:
PM2.5传感器选用GP2Y1010AU0F,安装时要注意:
电源部分采用两级稳压:
继电器驱动电路加入了光耦隔离,防止风扇启停时对MCU造成干扰。实际测试发现,不加光耦时系统偶尔会死机,加上后就完全稳定了。
使用Keil MDK5开发时有几个关键配置:
系统上电后的初始化顺序很重要:
主循环采用状态机设计,包含以下几个状态:
每个状态都有严格的超时机制,防止某个环节卡死导致系统崩溃。
采用滑动平均滤波结合中值滤波:
c复制#define FILTER_SIZE 5
float filterData(float newData) {
static float buffer[FILTER_SIZE] = {0};
static uint8_t index = 0;
buffer[index] = newData;
index = (index + 1) % FILTER_SIZE;
// 中值滤波
float temp[FILTER_SIZE];
memcpy(temp, buffer, sizeof(buffer));
bubbleSort(temp, FILTER_SIZE);
// 取中间3个值做平均
return (temp[1] + temp[2] + temp[3]) / 3;
}
报警触发采用滞后比较算法,防止临界值附近频繁切换:
c复制bool checkAlarm(float value, float threshold) {
static bool alarmState = false;
if(alarmState) {
// 只有低于阈值的95%才解除报警
if(value < threshold * 0.95) {
alarmState = false;
}
} else {
// 超过阈值立即报警
if(value > threshold) {
alarmState = true;
}
}
return alarmState;
}
气体传感器需要定期校准,我总结了一套简易校准方法:
校准周期建议:
通过以下措施将待机功耗从120mA降到35mA:
ESP8266模块经常掉线的问题通过以下方法解决:
修改后的网络连接代码:
c复制void wifiConnect() {
uint8_t retry = 0;
while(retry < 3) {
sendATCommand("AT+CWJAP=\"SSID\",\"PASSWORD\"", 10000);
if(strstr(response, "OK")) {
break;
}
delay(5000);
retry++;
}
if(retry == 3) {
systemReset();
}
}
根据三个月的实际使用经验,给出以下建议:
安装位置选择:
系统维护:
功能扩展方向:
这个项目从设计到调试完成总共花了约80个小时,最大的收获是学会了如何平衡系统性能和成本。比如最初想用STM32F4系列,但发现F103已经完全够用;OLED屏也考虑过更大尺寸的,但功耗和成本都会大幅增加。