基于STM32的智能环境监测系统设计

张开发
2026/4/9 9:18:14 15 分钟阅读

分享文章

基于STM32的智能环境监测系统设计
一、系统概述设计以STM32F103C8T6Cortex-M372MHz为核心集成多传感器模块、无线通信、数据显示和云端交互实现环境参数实时监测温湿度、光照、空气质量、噪声等、数据存储、阈值报警和远程监控。系统支持本地显示与手机APP/Web端远程查看适用于智能家居、农业大棚、工业环境监测等场景。二、系统架构2.1 整体框图┌─────────────────────────────────────────────────────────────┐ │ 智能环境监测系统 │ ├─────────────┬─────────────┬─────────────┬─────────────┤ │ 传感器层 │ 控制层 │ 通信层 │ 应用层 │ ├─────────────┼─────────────┼─────────────┼─────────────┤ │ 温湿度 │ STM32F103 │ WiFi/4G │ 本地显示 │ │ 光照强度 │ (主控) │ (ESP8266) │ (OLED/LCD) │ │ 空气质量 │ │ 蓝牙 │ 手机APP │ │ 噪声 │ │ (HC-05) │ Web平台 │ │ 气压/海拔 │ │ LoRa │ 云端存储 │ │ 土壤湿度 │ │ (SX1278) │ 数据分析 │ └─────────────┴─────────────┴─────────────┴─────────────┘2.2 核心组件选型模块型号/参数功能说明主控STM32F103C8T664KB Flash20KB RAM传感器数据采集、处理、通信控制温湿度DHT22AM2302数字单总线温度-4080℃±0.5℃湿度0100%RH±2%光照BH1750I2C数字输出光照强度0~65535 lux1 lux分辨率空气质量MQ-135模拟输出ADC检测CO2、苯、氨等有害气体0~5V模拟量噪声MAX9814模拟输出ADC环境噪声检测20~20kHz带AGC气压/海拔BMP280I2C/SPI数字输出气压3001100hPa海拔-5009000m土壤湿度FC-28模拟输出ADC土壤湿度检测0~100%RH显示0.96寸OLEDI2CSSD1306实时显示环境参数128×64像素无线通信ESP8266WiFiAT指令连接云平台阿里云/腾讯云MQTT协议存储AT24C02I2C EEPROM2KB存储报警阈值、校准参数报警蜂鸣器LED红/绿超阈值声光报警温湿度、空气质量、噪声三、硬件设计3.1 硬件连接表传感器/模块STM32引脚通信方式说明DHT22PA0单总线GPIO温湿度数据线需4.7kΩ上拉BH1750PB6SCLPB7SDAI2C光照强度传感器MQ-135PA1ADC1_CH1空气质量模拟量0~3.3VMAX9814PA2ADC1_CH2噪声模拟量0~3.3VBMP280PB6SCLPB7SDAI2C气压/海拔传感器共用I2CFC-28PA3ADC1_CH3土壤湿度模拟量0~3.3VOLEDPB6SCLPB7SDAI2C显示模块共用I2CESP8266PA9TXPA10RXUART1WiFi模块AT指令AT24C02PB6SCLPB7SDAI2CEEPROM共用I2C蜂鸣器PB8GPIO报警输出低电平触发LEDPB9红PB10绿GPIO状态指示红报警绿正常四、软件设计STM32 HAL库4.1 开发环境IDESTM32CubeIDE 1.13.0库STM32Cube_FW_F1_V1.8.0HAL库通信协议MQTT云平台、JSON数据格式4.2 核心模块驱动4.2.1 DHT22温湿度传感器单总线#includedht22.h// DHT22数据读取返回湿度、温度单位%RH、℃HAL_StatusTypeDefDHT22_Read(float*humidity,float*temperature){uint8_tdata[5]{0};uint8_ti,j;// 主机拉低18ms然后拉高20~40μsHAL_GPIO_WritePin(DHT22_GPIO_Port,DHT22_Pin,GPIO_PIN_RESET);HAL_Delay(18);HAL_GPIO_WritePin(DHT22_GPIO_Port,DHT22_Pin,GPIO_PIN_SET);delay_us(30);// 延时30μs// 从机响应拉低80μs然后拉高80μsif(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_RESET);// 等待从机拉高while(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_SET);// 等待从机拉低// 读取40位数据16位湿度16位温度8位校验和for(i0;i5;i){for(j0;j8;j){while(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_RESET);// 等待50μs低电平delay_us(40);// 延时40μs后判断高电平持续时间if(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_SET){data[i]|(1(7-j));// 高电平持续40μs表示1while(HAL_GPIO_ReadPin(DHT22_GPIO_Port,DHT22_Pin)GPIO_PIN_SET);// 等待高电平结束}}}// 校验和验证if(data[4](data[0]data[1]data[2]data[3])){*humidity(float)((data[0]8)|data[1])/10.0f;*temperature(float)((data[2]8)|data[3])/10.0f;returnHAL_OK;}}returnHAL_ERROR;}4.2.2 BH1750光照传感器I2C#includebh1750.h// BH1750初始化连续高分辨率模式1 lux分辨率voidBH1750_Init(void){uint8_tcmdBH1750_POWER_ON;HAL_I2C_Master_Transmit(hi2c1,BH1750_ADDR,cmd,1,100);cmdBH1750_CONTINUOUS_HIGH_RES_MODE;HAL_I2C_Master_Transmit(hi2c1,BH1750_ADDR,cmd,1,100);}// 读取光照强度单位luxfloatBH1750_ReadLight(void){uint8_tdata[2]{0};HAL_I2C_Master_Receive(hi2c1,BH1750_ADDR,data,2,100);return(float)((data[0]8)|data[1])/1.2f;// 转换公式lux raw/1.2}4.2.3 MQ-135空气质量传感器ADC#includeadc.h// MQ-135读取返回PPM浓度floatMQ135_ReadPPM(void){uint32_tadc_value0;floatvoltage,rs,ratio,ppm;// 读取ADC值12位0~4095HAL_ADC_Start(hadc1);HAL_ADC_PollForConversion(hadc1,100);adc_valueHAL_ADC_GetValue(hadc1);HAL_ADC_Stop(hadc1);// 计算电压0~3.3Vvoltageadc_value*3.3f/4095.0f;// 计算传感器电阻RL10kΩrs(3.3f-voltage)*10000.0f/voltage;// 计算气体浓度需根据校准曲线调整参数ratiors/7600.0f;// 在洁净空气中Rs/R0≈1R07.6kΩppm116.602f*pow(ratio,-2.769f);// 苯类气体近似公式returnppm;}4.2.4 ESP8266 WiFi模块MQTT上传#includeesp8266.h// ESP8266初始化连接WiFi配置MQTTvoidESP8266_Init(void){charcmd[100];// 重启模块HAL_UART_Transmit(huart1,(uint8_t*)ATRST\r\n,8,1000);HAL_Delay(2000);// 连接WiFisprintf(cmd,ATCWJAP\%s\,\%s\\r\n,WIFI_SSID,WIFI_PASSWORD);HAL_UART_Transmit(huart1,(uint8_t*)cmd,strlen(cmd),1000);HAL_Delay(5000);// 连接MQTT服务器以阿里云为例sprintf(cmd,ATMQTTUSERCFG0,1,\NULL\,\%s%s\,\%s\,0,0,\\\r\n,DEVICE_NAME,PRODUCT_KEY,DEVICE_SECRET);HAL_UART_Transmit(huart1,(uint8_t*)cmd,strlen(cmd),1000);HAL_Delay(1000);sprintf(cmd,ATMQTTCONN0,\%s.iot-as-mqtt.cn-shanghai.aliyuncs.com\,1883,1\r\n,PRODUCT_KEY);HAL_UART_Transmit(huart1,(uint8_t*)cmd,strlen(cmd),1000);HAL_Delay(2000);}// 上传环境数据JSON格式voidESP8266_UploadData(floattemp,floathum,floatlight,floatair,floatnoise){charjson[200],topic[100],cmd[300];// 构建JSON数据sprintf(json,{\Temperature\:%.1f,\Humidity\:%.1f,\Light\:%.0f,\AirQuality\:%.1f,\Noise\:%.1f},temp,hum,light,air,noise);// 构建MQTT主题sprintf(topic,/sys/%s/%s/thing/event/property/post,PRODUCT_KEY,DEVICE_NAME);// 发送MQTT消息sprintf(cmd,ATMQTTPUB0,\%s\,\%s\,1,0\r\n,topic,json);HAL_UART_Transmit(huart1,(uint8_t*)cmd,strlen(cmd),1000);}4.2.5 主程序框架FreeRTOS任务#includemain.h#includecmsis_os.h// 全局变量环境参数floattemperature0,humidity0,light0,air_quality0,noise0;// 任务1传感器数据采集每2秒一次voidSensorTask(voidconst*argument){while(1){// 读取所有传感器DHT22_Read(humidity,temperature);lightBH1750_ReadLight();air_qualityMQ135_ReadPPM();noiseMAX9814_ReadNoise();// 类似MQ-135的ADC读取// 阈值报警检测if(temperatureTEMP_MAX||temperatureTEMP_MIN||humidityHUM_MAX||humidityHUM_MIN||air_qualityAIR_MAX||noiseNOISE_MAX){HAL_GPIO_WritePin(BUZZER_GPIO_Port,BUZZER_Pin,GPIO_PIN_SET);// 蜂鸣器报警HAL_GPIO_WritePin(LED_RED_GPIO_Port,LED_RED_Pin,GPIO_PIN_SET);// 红灯亮}else{HAL_GPIO_WritePin(BUZZER_GPIO_Port,BUZZER_Pin,GPIO_PIN_RESET);HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,GPIO_PIN_SET);// 绿灯亮}osDelay(2000);// 2秒间隔}}// 任务2数据显示OLED刷新每1秒一次voidDisplayTask(voidconst*argument){charbuffer[32];while(1){OLED_Clear();sprintf(buffer,Temp:%.1fC Hum:%.1f%%,temperature,humidity);OLED_ShowString(0,0,buffer);sprintf(buffer,Light:%.0flux,light);OLED_ShowString(0,16,buffer);sprintf(buffer,Air:%.1fppm,air_quality);OLED_ShowString(0,32,buffer);sprintf(buffer,Noise:%.1fdB,noise);OLED_ShowString(0,48,buffer);osDelay(1000);// 1秒刷新}}// 任务3数据上传每10秒一次voidUploadTask(voidconst*argument){ESP8266_Init();// 初始化WiFi模块while(1){ESP8266_UploadData(temperature,humidity,light,air_quality,noise);osDelay(10000);// 10秒上传一次}}// 主函数FreeRTOS初始化intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_ADC1_Init();MX_USART1_UART_Init();// 创建FreeRTOS任务osThreadDef(SensorTask,SensorTask,osPriorityNormal,0,128);osThreadCreate(osThread(SensorTask),NULL);osThreadDef(DisplayTask,DisplayTask,osPriorityNormal,0,128);osThreadCreate(osThread(DisplayTask),NULL);osThreadDef(UploadTask,UploadTask,osPriorityNormal,0,256);osThreadCreate(osThread(UploadTask),NULL);osKernelStart();// 启动RTOS内核while(1){}}参考代码 基于stm32智能环境监测系统www.youwenfan.com/contentcst/182687.html五、云端平台对接以阿里云IoT为例5.1 设备接入配置创建产品登录阿里云IoT平台创建“智能环境监测”产品选择“数据格式”为JSON。添加设备为每个监测节点创建设备获取ProductKey、DeviceName、DeviceSecret。定义物模型添加属性温度、湿度、光照、空气质量、噪声和报警事件。5.2 数据可视化Web端使用阿里云IoT Studio创建可视化大屏实时显示环境数据曲线。手机APP通过阿里云IoT SDK开发Android/iOS APP或使用现成应用如“云智能”。六、关键问题与解决方案6.1 传感器数据稳定性问题模拟传感器MQ-135、FC-28受温度、湿度影响读数漂移。解决软件滤波采用滑动平均滤波取10次采样平均值定期校准在洁净空气中校准MQ-135的R0值上电预热24小时。6.2 多I2C设备冲突问题BH1750、BMP280、OLED、AT24C02共用I2C总线地址冲突。解决地址区分BH17500x23/0x5C、BMP2800x76/0x77、AT24C020xA0分时复用每个设备操作后释放总线避免长时间占用。6.3 低功耗设计问题7×24小时运行功耗较高。解决休眠模式STM32进入Stop模式定时唤醒RTC闹钟传感器断电通过MOSFET控制传感器电源采样时上电。七、系统测试7.1 功能测试测试项方法预期结果温湿度对比温湿度计±2℃/±5%RH误差±1℃/±3%RH光照对比照度计0~2000 lux误差±5%空气质量对比CO2检测仪400~2000 ppm误差±10%无线传输距离测试室内/室外室内30m稳定丢包率1%报警功能模拟超阈值如温度40℃蜂鸣器响红灯亮APP推送报警7.2 性能指标采样频率传感器2秒/次上传10秒/次显示刷新OLED 1秒/次无线传输WiFiESP8266支持802.11 b/g/n供电5V/2A DC或锂电池太阳能板工作温度-20~60℃。八、总结系统基于STM32F103实现了多参数环境监测核心是多传感器数据融合、实时显示与云端交互。通过模块化设计可灵活扩展更多传感器如PM2.5、甲醛、本地存储SD卡和边缘计算异常检测算法。

更多文章