若该文为原创文章,转载请注明原文出处。
1. 项目背景
随着物联网(IoT)技术的飞速发展和人们生活水平的提高,对家居环境的舒适性、安全性和智能化提出了更高的要求。传统的家居环境管理依赖人工感知和调节,效率低下且不精确。温湿度、空气质量(如PM2.5、CO)、光照强度等因素直接影响居住者的健康与舒适度。
因此,本项目旨在设计并实现一个基于STM32单片机的智能家居环境监控系统。该系统能够实时、自动地采集多种环境参数,通过本地显示和远程云平台(Onenet )双路传输数据至用户APP,并提供超限自动报警与联动控制功能,从而构建一个智能化、网络化、自动化的现代家居环境管理解决方案。
2. 硬件功能
本系统的硬件部分主要由以下模块组成:
主控制器 (MCU):采用STM32F103C8T6单片机(内核Cortex-M3),作为系统的控制核心,负责数据采集、处理、逻辑判断、外设控制及通信协调。
传感器模块:
温湿度传感器:DHT11或DHT22,用于采集环境温度和湿度。
光照强度传感器:BH1750(数字输出,I2C接口),用于采集环境光强。
一氧化碳(CO)传感器:MQ-7(模拟输出),用于检测一氧化碳气体浓度。
PM2.5浓度传感器:GP2Y1014AU0F(模拟输出)或攀藤PMS5003(串口输出),用于检测空气中PM2.5颗粒物浓度。
执行器与报警模块:
继电器模块:用于控制风扇、灯等220V用电设备。
LED灯与蜂鸣器:用于组成声光报警装置。
显示模块:0.96寸或1.3寸OLED显示屏(I2C接口)或LCD1602液晶屏,用于本地实时显示所有环境参数和设置阈值。
通信模块:ESP-01S ESP8266 WIFI模块,通过UART与STM32通信,负责将数据上传至Onenet IoT平台。
电源模块:AMS1117-3.3V稳压芯片,为STM32及外围模块提供稳定的3.3V电源。执行器部分可采用外部电源供电。
其他:STM32最小系统电路(晶振、复位电路等)、按键(用于设置阈值)。
3. 系统框架图
下图描述了系统的整体硬件框架和数据流:
数据流说明:
上行:传感器数据 -> STM32 -> (通过WIFI) ->Onenet -> APP。
下行:APP设置指令 -> Onenet -> (通过WIFI) -> STM32。
本地控制:STM根据预设逻辑和阈值,直接控制执行器。
4. 软件设计
软件程序在Keil MDK或STM32CubeIDE环境中使用C语言开发,基于HAL库或标准库。程序采用模块化设计,主要包括:
主程序模块:初始化外设,调度各任务。
传感器驱动模块:DHT11、BH1750、ADC(用于MQ-7/GP2Y10)等的读写驱动程序。
执行器控制模块:GPIO控制继电器、LED、蜂鸣器。
显示模块:OLED/LCD的显示驱动程序。
通信模块:UART驱动与ESP8266的AT指令解析,MQTT协议对接Onenet 。
业务逻辑模块:实现数据判断、报警逻辑、设备联动。
5. 软件流程图
6. 关键代码片段
6.1 主循环逻辑
6. 关键代码片段(示例)
6.1 主循环逻辑(伪代码风格)
c
int main(void) {
// 初始化所有外设
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init(); // For ESP8266
MX_I2C1_Init(); // For BH1750 & OLED
MX_ADC1_Init(); // For MQ-7
// ... 其他初始化
// 连接Onenet
ESP8266_Init();
ALIYUN_MQTT_Connect();
while (1) {
// 1. 读取传感器
temperature = DHT11_ReadTemperature();
humidity = DHT11_ReadHumidity();
light_intensity = BH1750_ReadLight();
co_ppm = MQ7_ReadPPM(); // 通过ADC读取并转换
pm25 = PM25_ReadValue();
// 2. 本地显示
OLED_ShowData(temperature, humidity, light_intensity, co_ppm, pm25);
// 3. 上传云平台
ALIYUN_MQTT_Publish("topic/temp", temperature);
// ... 发布其他数据
// 4. 检查阈值并控制设备
if (temperature > temp_max_threshold) {
HAL_GPIO_WritePin(FAN_Relay_GPIO_Port, FAN_Relay_Pin, GPIO_PIN_SET); // 打开风扇
if (!isAlarming) Buzzer_Alarm_ON(); // 启动报警
} else {
HAL_GPIO_WritePin(FAN_Relay_GPIO_Port, FAN_Relay_Pin, GPIO_PIN_RESET);
}
// ... 检查其他传感器阈值
// 5. 处理云平台下发的指令(在串口中断或循环中解析)
ALIYUN_MQTT_ProcessLoop(); // 例如处理`/sys/xxx/thing/service/property/set`消息
HAL_Delay(2000); // 延时2秒
}
}
6.2 MQTT回调函数(处理云端下发指令)
c
// 当从MQTT主题收到消息时回调
void messageArrived(char* topic, byte* payload, unsigned int length) {
char json[100];
memcpy(json, payload, length);
json[length] = '\0';
// 解析JSON,示例: {"method":"thing.service.property.set", "id":"123", "params":{"temp_max":30}, "version":"1.0.0"}
cJSON* root = cJSON_Parse(json);
cJSON* params = cJSON_GetObjectItem(root, "params");
if (params) {
cJSON* new_temp_max = cJSON_GetObjectItem(params, "temp_max");
if (new_temp_max) {
temp_max_threshold = new_temp_max->valuedouble; // 更新温度阈值
// 可以将新阈值保存到Flash,防止掉电丢失
}
// ... 解析其他参数如 light_min, co_max等
}
cJSON_Delete(root);
}
6.3 ADC读取MQ-7(简化版)
c
#define MQ7_ADC_CHANNEL ADC_CHANNEL_0
uint32_t MQ7_ReadADC() {
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = MQ7_ADC_CHANNEL;
sConfig.Rank = 1;
HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 假设hadc1已初始化
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 50);
return HAL_ADC_GetValue(&hadc1);
}
float MQ7_ReadPPM() {
uint32_t adc_value = MQ7_ReadADC();
float voltage = (adc_value / 4095.0) * 3.3; // 假设12位ADC,3.3V参考电压
// 根据传感器特性曲线将电压值转换为PPM值 (简化计算,需校准)
float ppm = (voltage - 0.2) * 1000.0 / (0.8); // 示例公式,切勿直接使用
return ppm;
}
6.2 MQTT回调函数(处理云端下发指令)
// 当从MQTT主题收到消息时回调
void messageArrived(char* topic, byte* payload, unsigned int length) {
char json[100];
memcpy(json, payload, length);
json[length] = '\0';
// 解析JSON,示例: {"method":"thing.service.property.set", "id":"123", "params":{"temp_max":30}, "version":"1.0.0"}
cJSON* root = cJSON_Parse(json);
cJSON* params = cJSON_GetObjectItem(root, "params");
if (params) {
cJSON* new_temp_max = cJSON_GetObjectItem(params, "temp_max");
if (new_temp_max) {
temp_max_threshold = new_temp_max->valuedouble; // 更新温度阈值
// 可以将新阈值保存到Flash,防止掉电丢失
}
// ... 解析其他参数如 light_min, co_max等
}
cJSON_Delete(root);
}
6.3 ADC读取MQ-7
#define MQ7_ADC_CHANNEL ADC_CHANNEL_0
uint32_t MQ7_ReadADC() {
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = MQ7_ADC_CHANNEL;
sConfig.Rank = 1;
HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 假设hadc1已初始化
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 50);
return HAL_ADC_GetValue(&hadc1);
}
float MQ7_ReadPPM() {
uint32_t adc_value = MQ7_ReadADC();
float voltage = (adc_value / 4095.0) * 3.3; // 假设12位ADC,3.3V参考电压
// 根据传感器特性曲线将电压值转换为PPM值 (简化计算,需校准)
float ppm = (voltage - 0.2) * 1000.0 / (0.8); // 示例公式,切勿直接使用
return ppm;
}
7.调试结果
经过上述软硬件测试,本系统可以实现预设的相关功能。
第一,在监控方面。本系统能对所处环境中的温湿度、室内光照强度、PM2.5和CO浓度进行实时监控并显示结果。其中温度测量范围为±0~50℃(存在±2%的误差),光照强度测量范围0~99%,湿度测量范围为10~90%RH(存在±5%RH的误差),PM2.5浓度监测灵敏度为0.5V/(0.1mg/m3)。CO浓度监控范围为0~99%。在检测PM2.5和CO浓度时,测量值会与程序内设置的三组范围进行比较。本系统可以控制电灯、报警灯、排气扇,,报警器的开关,报警模块中的LED灯和蜂鸣器也可以按照正确指令启动。综上所述,本系统基本达到了预设的效果。
第二,在人机交互情况。本系统不仅能在OLED上显示采集环境数值的结果,还可以利用ESP8266WIFI模块与手机进行通讯。这样方便用户在手机上实时观察到环境数据。配备的按键可以设置报警阈值的加减。
8. 总结
本项目成功设计并实现了一个功能完备的智能家居环境监控系统。该系统以高性能、低成本的STM32单片机为核心,集成多种传感器,实现了对环境参数的全面采集、本地显示和远程云平台监控。通过Onenet IoT平台和手机APP,用户可以实现远程实时监控和个性化阈值设置。系统具备自动报警和设备联动功能,显著提升了家居环境的智能化水平和安全性。
如有侵权,或需要完整代码,请及时联系博主。