作为一名嵌入式开发工程师,我最近完成了一个基于STM32的环境监测系统项目。这个系统的核心功能是实时监测环境中的温湿度、空气质量以及多种有害气体浓度,并通过WiFi将数据上传到OneNet物联网平台。在实际开发过程中,我发现这类系统在智能家居、工业监测等领域有着广泛的应用前景。
STM32F103RCT6作为主控芯片有几个明显优势:
选择OneNet平台主要考虑:
整个系统采用分层架构:
code复制传感器层 → 主控层 → 通信层 → 云平台层 → 应用层
具体实现上:
提示:在设计初期就要考虑传感器采样频率和网络通信频率的平衡。采样太快会导致数据冗余,太慢又可能错过异常情况。经过实测,5秒一次的采样间隔对大多数场景都适用。
| 模块 | 型号 | 关键参数 | 用途 |
|---|---|---|---|
| 主控 | STM32F103RCT6 | 72MHz, 256KB Flash | 系统控制核心 |
| WiFi模块 | ESP8266-01S | 支持802.11 b/g/n | 数据上传 |
| 温湿度 | DHT11 | 20-90%RH ±5%, 0-50℃ ±2℃ | 环境监测 |
| 空气质量 | MQ135 | 检测NH3/NOx/CO2等 | 空气污染监测 |
| 可燃气体 | MQ2 | 检测LPG/丙烷/氢气等 | 燃气泄漏监测 |
| 一氧化碳 | MQ7 | 检测CO 20-2000ppm | 中毒风险预警 |
| 显示 | 1.44寸LCD | 128x128 SPI接口 | 本地数据显示 |
| 报警 | 有源蜂鸣器 | 5V 85dB | 异常报警 |
所有MQ系列传感器都采用类似的接口电路:
c复制// 典型MQ传感器电路
VCC ----[10KΩ]----|---- AIN
| |
GND [RL]
其中:
系统采用USB 5V供电,需要注意:
plaintext复制开始
├─ 硬件初始化
│ ├─ GPIO
│ ├─ ADC
│ ├─ USART(ESP8266)
│ └─ SPI(LCD)
├─ WiFi连接
│ ├─ AT+CWMODE=1
│ ├─ AT+CWJAP="SSID","PWD"
│ └─ AT+CIPSTART="TCP","183.230.40.39",6002
├─ MQTT连接
│ ├─ 生成三元组
│ └─ 发送CONNECT包
└─ 主循环
├─ 读取传感器
├─ LCD显示
├─ 判断阈值
│ ├─ 超标 → 蜂鸣器报警
│ └─ 正常 → 继续
└─ 上传OneNet(每5秒)
OneNet要求特殊的密码生成算法:
c复制// 基于三元组生成密码
void generate_password(char *product_id, char *device_name, char *access_key, char *output) {
char temp[256];
sprintf(temp, "products/%s/devices/%s", product_id, device_name);
unsigned char hmac[32];
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
(unsigned char *)access_key, strlen(access_key),
(unsigned char *)temp, strlen(temp),
hmac);
// Base64编码
mbedtls_base64_encode((unsigned char *)output, 64, NULL, hmac, 32);
}
MQ传感器需要温度补偿:
c复制float get_corrected_gas_value(float raw_adc, float temp, float humidity) {
// 基础转换
float rs_ro_ratio = (1023.0 - raw_adc) / raw_adc;
// 温湿度补偿
float compensation = 1.0 + 0.05*(temp-20.0) + 0.002*(humidity-65.0);
return rs_ro_ratio / compensation;
}
建议为每个传感器创建单独的数据流:
OneNet的可视化编辑器支持多种组件:
初期遇到WiFi频繁断开的问题,解决方案:
c复制bool send_at_command(const char *cmd, const char *expect, int retry) {
while(retry--) {
uart_send(cmd);
if(wait_response(expect, 1000)) {
return true;
}
}
return false;
}
MQ传感器需要定期校准:
c复制float ppm = a * pow(rs_ro_ratio, b); // a,b为校准系数
如果使用电池供电,可以:
这个基础系统可以进一步扩展:
我在实际部署中发现,将系统安装在离地面1.5米高度(呼吸带高度)能获得最有参考价值的数据。同时,避免将设备安装在通风口附近,防止传感器读数受到干扰。