跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

基于 STM32 的智能家居环境监测系统

一个基于 STM32F103C8T6 微控制器的智能家居环境监测系统。系统集成了 DHT11 温湿度、MQ-2 烟雾、MQ-7 一氧化碳、MQ-135 空气质量及光照传感器,并通过 ESP8266 模块接入机智云云平台。硬件包含 0.96 OLED 显示屏、步进电机(模拟窗户)、风扇及声光报警器。软件支持手动与自动双模式,可根据预设阈值自动触发报警或通风,也可通过 App 远程操控。代码展示了传感器数据采集、阈值判断逻辑及外设控制流程,适合嵌入式学习与 IoT 项目开发参考。

女王发布于 2026/4/6更新于 2026/8/2353 浏览
基于 STM32 的智能家居环境监测系统

一、设计背景和意义

1.1 设计背景

随着物联网(IoT)、嵌入式系统和云计算等技术的飞速发展,智能家居系统正在逐渐改变人们的生活方式。智能家居不仅仅是简单的远程开关控制,而是向着环境感知、自主判断、智能决策的方向不断演进。特别是在城市化进程加快、生活节奏加快的背景下,用户对生活便捷性、家庭安全性和环境舒适度的要求不断提高,这对智能家居系统的综合感知、智能响应能力提出了更高的要求。

当前市面上的智能家居产品多以分立模块存在,系统功能较为单一,往往只能实现某一方面的控制,比如智能照明、温湿度调节、安防监控等,缺乏整体化的环境监测与多条件联动控制能力。同时,许多系统依赖厂商封闭协议,用户扩展性差,缺乏灵活性与个性化调整能力。另外,一些传统系统虽然具备远程控制功能,但仍停留在手动控制层面,无法基于环境数据自主做出决策,自动响应潜在的安全风险。

1.2 设计意义

系统不仅支持用户远程手动控制,如开关窗户(由步进电机模拟)、控制声光报警和照明设备,还具备自动模式,可依据传感器数据智能决策。例如,一旦检测到烟雾或一氧化碳超标,系统会立即启动报警器并自动开窗通风,有效降低安全隐患;在夜晚或光照不足时,系统可自动点亮灯光,提升家庭舒适度。这种以数据驱动控制逻辑的智能响应机制,真正实现了从'被动控制'向'主动管理'的转变。

本课题融合了嵌入式系统、物联网通信、自动控制与人机交互等多个知识点,能够全面锻炼学生在软硬件开发、系统集成与工程实践方面的能力。通过对 STM32 开发平台、传感器数据采集处理、WiFi 模块通信协议、云平台接入与 APP 交互控制等技术的综合应用,提升了理论知识向实际工程转化的能力。

二、实物效果展示

2.1 实物图片

文章配图

2.2 实物演示视频

【开源】基于 STM32 的智能家居环境监测系统

三、硬件功能简介

3.1 项目功能详解

1)传感器检测:烟雾浓度、空气质量、一氧化碳、温湿度、光照 2)数据显示:0.96OLED 屏幕 3)执行机构:步进电机(窗户、风扇) 4)云平台:通过 ESP8266 WIFI 联网后,接入机智云平台 5)App 监控:App 远程监控数据,控制执行机构 6)数据设定:按键或 APP 设定阈值,切换模式 7)手动模式:通过手机 App 实现控制窗户、风扇开关 8)自动模式:根据设定的烟雾、一氧化碳、空气质量阈值等超过阈值自动开启声光报警、打开窗户通风

3.2 元器件清单

  1. 主控 STM32F103C8T6
  2. 0.96OLED 显示屏幕
  3. ESP8266 联网 WiFi
  4. DHT11 温湿度传感器
  5. MQ-2 烟雾传感器
  6. MQ-7 一氧化碳传感器
  7. MQ-135 空气质量传感器
  8. 光敏电阻
  9. 风扇
  10. 步进电机
  11. 蜂鸣器声光报警

四、主框图与软件流程图

主框图

文章配图

流程图

文章配图

五、硬件 PCB 展示

文章配图

文章配图

六、软件程序设计

u32 STM32_xx0=0X4E4C4A; u32 STM32_xx1=0X364B1322; u32 STM32_xx2=0X132D13 ; 
#define FLASH_SAVE_ADDR 0x08010000 
u8 buff[30]; //参数显示缓存数组 
u8 count; 
dataPoint_t currentDataPoint; //云端数据点 
u8 wifi_sta; //wifi 连接状态标志 
u8 mode=0; //模式控制自动和手动 
u8 NTP_sta=0; //网络时间获取状态 
u8 display_contrl=0; 
u8 curtain_flag=0; 
u8 last_curtain_flag=0; 
extern u8 DHT11_Temp,DHT11_Hum; //温湿度 
u16 Pre; //气压检测值 
u16 gz_value; //光照检测值 
u16 m2_value; //烟雾检测值 
u16 m7_value; //一氧化碳检测值 
u16 m135_value; //空气质量检测值 
u16 A_DHT11_Temp=35; //温度阈值 高于阈值时报警 
u16 A_DHT11_Hum=20; //湿度阈值 低于阈值时报警 
u16 A_pre=1500; //气压阈值 低于阈值时报警 
u16 A_gz_value=1000; //光照强度阈值 低于阈值时打开窗帘和照明灯 
u16 A_m2_value=4000; //烟雾阈值 高于阈值时报警 
u16 A_m7_value=4000; //一氧化碳阈值 高于阈值时报警 
u16 A_m135_value=1500; //空气质量阈值 低于阈值时报警 
void Gizwits_Init(void) { 
    TIM3_Int_Init(9,7199); //1MS 系统定时 
    usart3_init(9600); //WIFI 初始化 
    memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t)); //设备状态结构体初始化 
    gizwitsInit(); //缓冲区初始化 
} 
//数据采集 
void userHandle(void) { 
    currentDataPoint.valueLED=!LED0; 
    currentDataPoint.valueCurtain=curtain_flag; 
    currentDataPoint.valueTemp=DHT11_Temp; 
    currentDataPoint.valueHum=DHT11_Hum; 
    currentDataPoint.valuePre=Pre; 
    currentDataPoint.valueGZ_Value=gz_value; 
    currentDataPoint.valueMQ2_Value=m2_value; 
    currentDataPoint.valueMQ7_Value=m7_value; 
    currentDataPoint.valueMQ135_Value=m135_value; 
} 
void Get_Data(u16 count); //获取传感器数据 
void WIFI_Contection(u8 key); //WiFi 连接控制 
void Canshu_Change(u8 key); //系统参数调节 
void Mode_Change(u8 key); //模式切换 
void BUJING_Cotrol(u8 mode,u16 time,u16 count); 
int main(void) { 
    u8 t=0; 
    int key_value; 
    uart_init(115200); //串口初始化为 115200 
    delay_init(); //延时函数初始化 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组 2:2 位抢占优先级,2 位响应优先级 
    Adc1_Channe_Init(); //ADC 通道初始化 
    KEY_Init(); //按键引脚初始化 
    bmp280Init(); 
    while(DHT11_Init()); 
    LED_Init(); //初始化与 LED 连接的硬件接口 
    OLED_Init(); //OLED 初始化 
    OLED_Clear(); //OLED 清屏 
    Gizwits_Init(); 
    BEEP = 0; 
    while(1) { 
        Get_Data(0); 
        if(gz_value<=A_gz_value&&mode==0) { 
            LED0=0;curtain_flag=0; 
        }else if(gz_value>A_gz_value&&mode==0){ 
            LED0=1;curtain_flag=1; 
        } 
        if(last_curtain_flag!=curtain_flag&&mode==0) { 
            BUJING_Cotrol(curtain_flag,3,270); 
            last_curtain_flag = curtain_flag; 
        } 
        if(last_curtain_flag!=currentDataPoint.valueCurtain&&mode==1) { 
            BUJING_Cotrol(currentDataPoint.valueCurtain,3,270); 
            curtain_flag = currentDataPoint.valueCurtain; 
            last_curtain_flag = currentDataPoint.valueCurtain; 
        } 
        if(mode==1) { 
            LED0=!currentDataPoint.valueLED; 
        } 
        if(DHT11_Temp>=A_DHT11_Temp||DHT11_Hum<=A_DHT11_Hum||Pre>=A_pre||m135_value<=A_m135_value||m2_value>=A_m2_value||m7_value>=A_m7_value){ 
            //BEEP=!BEEP; 
        }else BEEP = 0; 
        key_value = KEY_Scan(0); 
        if(key_value==4) { 
            display_contrl++; 
        } 
        if(display_contrl%2==0&&t>=10) { 
            OLED_ShowCHinese(0,0,0); 
            OLED_ShowCHinese(16,0,2); 
            sprintf((char*)buff,":%2dC",DHT11_Temp); 
            OLED_ShowString(32,0,buff,16); //显示温度 
            OLED_ShowCHinese(64,0,1); 
            OLED_ShowCHinese(82,0,2); 
            sprintf((char*)buff,":%2d%%",DHT11_Hum); 
            OLED_ShowString(96,0,buff,16);//显示湿度 
            OLED_ShowCHinese(0,2,3); 
            OLED_ShowCHinese(16,2,4); 
            sprintf((char*)buff,":%2dhpa ",Pre); 
            OLED_ShowString(32,2,buff,16);//显示气压 
            OLED_ShowCHinese(0,4,5); 
            OLED_ShowCHinese(16,4,6); 
            OLED_ShowCHinese(32,4,7); 
            OLED_ShowCHinese(48,4,8); 
            sprintf((char*)buff,":%4dppm",gz_value); 
            OLED_ShowString(64,4,buff,16);//显示光照强度 
            OLED_ShowCHinese(0,6,21); 
            OLED_ShowCHinese(16,6,22); 
            OLED_ShowCHinese(32,6,23); 
            OLED_ShowCHinese(48,6,24); 
            //sprintf((char*)buff,":%4dppm",m135_value); 
            //OLED_ShowString(64,6,buff,16);//显示空气质量 
            OLED_ShowString(64,6,":",16); 
        }else if(display_contrl%2==1&&t>=10) { 
            OLED_ShowCHinese(0,0,13); 
            OLED_ShowCHinese(16,0,14); 
            OLED_ShowCHinese(32,0,15); 
            OLED_ShowCHinese(48,0,16); 
            sprintf((char*)buff,":%4dppm",m2_value); 
            OLED_ShowString(64,0,buff,16);//显示 M2 数据 
            OLED_ShowCHinese(0,2,17); 
            OLED_ShowCHinese(16,2,18); 
            OLED_ShowCHinese(32,2,19); 
            OLED_ShowCHinese(48,2,20); 
            sprintf((char*)buff,":%4dppm",m7_value); 
            OLED_ShowString(64,2,buff,16);//显示 M7 数据 
            OLED_ShowCHinese(0,4,5); 
            OLED_ShowCHinese(16,4,6); 
            OLED_ShowCHinese(32,4,7); 
            OLED_ShowCHinese(48,4,8); 
            sprintf((char*)buff,":%4dppm",gz_value); 
            OLED_ShowString(64,4,buff,16);//显示光照强度 
            OLED_ShowCHinese(0,6,21); 
            OLED_ShowCHinese(16,6,22); 
            OLED_ShowCHinese(32,6,23); 
            OLED_ShowCHinese(48,6,24); 
        } 
        if(t>10){ 
            if(m135_value>100){ 
                OLED_ShowCHinese(80,6,23); //有人 
                OLED_ShowCHinese(96,6,24); 
                BEEP=!BEEP; //报警 
            }else{ 
                OLED_ShowCHinese(80,6,25); //无人 
                OLED_ShowCHinese(96,6,24); 
                BEEP = 0; 
            } 
        } 
        userHandle(); //用户数据采集 
        WIFI_Contection(key_value); //WiFi 连接控制 
        gizwitsHandle((dataPoint_t *)&currentDataPoint); //机智云协议处理 
        Canshu_Change(key_value); 
        t++; 
        delay_ms(100); 
    } 
} 
void WIFI_Contection(u8 key)//WiFi 连接控制 
{ 
    if(key==2) { 
        printf("WIFI 进入 AirLink 连接模式\r\n"); 
        gizwitsSetMode(WIFI_AIRLINK_MODE); //Air-link 模式接入 
    } 
    if(key==3) { 
        printf("WIFI 复位,请重新配置连接\r\n"); 
        gizwitsSetMode(WIFI_RESET_MODE); //WIFI 复位 
    } 
} 
void Canshu_Change(u8 key) 
{ 
    u8 obj=7; 
    if(key==1) { 
        BEEP=0;OLED_Clear(); 
        while(1){ 
            key = KEY_Scan(0); 
            if(key==1){ 
                obj++; 
                if(obj>=8)obj=0; 
            } 
            sprintf((char *)buff,"Working md:%4d",mode); 
            OLED_ShowString(8,0,buff,12); 
            sprintf((char *)buff,"A_Temp :%4d",A_DHT11_Temp); 
            OLED_ShowString(8,1,buff,12); 
            sprintf((char *)buff,"A_Hum :%4d",A_DHT11_Hum); 
            OLED_ShowString(8,2,buff,12); 
            sprintf((char *)buff,"A_pre :%4d",A_pre); 
            OLED_ShowString(8,3,buff,12); 
            sprintf((char *)buff,"A_gz_val :%4d",A_gz_value); 
            OLED_ShowString(8,4,buff,12); 
            sprintf((char *)buff,"A_m2_val :%4d",A_m2_value); 
            OLED_ShowString(8,5,buff,12); 
            sprintf((char *)buff,"A_m7_val :%4d",A_m7_value); 
            OLED_ShowString(8,6,buff,12); 
            sprintf((char *)buff,"A_m135_val:%4d",A_m135_value); 
            OLED_ShowString(8,7,buff,12); 
            if(obj==0){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1,">",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==1){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2,">",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==2){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3,">",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==3){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4,">",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==4){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5,">",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==5){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6,">",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==6){ 
                OLED_ShowString(0,0," ",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7,">",12); 
            } 
            if(obj==7){ 
                OLED_ShowString(0,0,">",12);OLED_ShowString(0,1," ",12); 
                OLED_ShowString(0,2," ",12);OLED_ShowString(0,3," ",12); 
                OLED_ShowString(0,4," ",12);OLED_ShowString(0,5," ",12); 
                OLED_ShowString(0,6," ",12);OLED_ShowString(0,7," ",12); 
            } 
            if(obj==0){ 
                if(key==3)A_DHT11_Temp+=1; 
                if(key==2)A_DHT11_Temp-=1; 
            } 
            if(obj==1){ 
                if(key==3)A_DHT11_Hum+=1; 
                if(key==2)A_DHT11_Hum-=1; 
            } 
            if(obj==2){ 
                if(key==3)A_pre+=20; 
                if(key==2)A_pre-=20; 
            } 
            if(obj==3){ 
                if(key==3)A_gz_value+=50; 
                if(key==2)A_gz_value-=50; 
            } 
            if(obj==4){ 
                if(key==3)A_m2_value+=50; 
                if(key==2)A_m2_value-=50; 
            } 
            if(obj==5){ 
                if(key==3)A_m7_value+=50; 
                if(key==2)A_m7_value-=50; 
            } 
            if(obj==6){ 
                if(key==3)A_m135_value+=50; 
                if(key==2)A_m135_value-=50; 
            } 
            if(obj==7){ 
                if(key==3)mode+=1; 
                if(key==2)mode-=1; 
                if(mode >= 2) mode = 0; 
            } 
            if(key==4){ 
                OLED_Clear(); 
                break; 
            } 
        } 
    } 
} 
void Get_Data(u16 count)//获取传感器数据 
{ 
    static float bmp280_press,bmp280; //气压 
    DHT11_Read_Data(&DHT11_Temp,&DHT11_Hum); 
    bmp280GetData(&bmp280_press,&bmp280,&bmp280); 
    Pre = bmp280_press; 
    gz_value = 4096 - get_Adc_Value(0x04); 
    m2_value = get_Adc_Value(0x07); 
    m7_value = get_Adc_Value(0x05); 
    m135_value = 4096 - get_Adc_Value(0x06); 
} 
void BUJING_Cotrol(u8 mode,u16 time,u16 count) 
{ 
    if(mode==0) { 
        while(count--) { 
            BUJ1=1; BUJ2=0; BUJ3=0;BUJ4=0; 
            delay_ms(time); 
            BUJ1=0; BUJ2=1; BUJ3=0;BUJ4=0; 
            delay_ms(time); 
            BUJ1=0; BUJ2=0; BUJ3=1;BUJ4=0; 
            delay_ms(time); 
            BUJ1=0; BUJ2=0; BUJ3=0;BUJ4=1; 
            delay_ms(time); 
        } 
    } 
    if(mode==1) { 
        while(count--) { 
            BUJ1=0; BUJ2=0; BUJ3=0;BUJ4=1; 
            delay_ms(time); 
            BUJ1=0; BUJ2=0; BUJ3=1;BUJ4=0; 
            delay_ms(time); 
            BUJ1=0; BUJ2=1; BUJ3=0;BUJ4=0; 
            delay_ms(time); 
            BUJ1=1; BUJ2=0; BUJ3=0;BUJ4=0; 
            delay_ms(time); 
        } 
    } 
}

七、项目资料包内容

文章配图

目录

  1. 一、设计背景和意义
  2. 1.1 设计背景
  3. 1.2 设计意义
  4. 二、实物效果展示
  5. 2.1 实物图片
  6. 2.2 实物演示视频
  7. 三、硬件功能简介
  8. 3.1 项目功能详解
  9. 3.2 元器件清单
  10. 四、主框图与软件流程图
  11. 五、硬件 PCB 展示
  12. 六、软件程序设计
  13. 七、项目资料包内容
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • TRAE AI 智能体实现 Vue 3 + Node.js + MySQL 全栈项目实战
  • HivisionIDPhotos:开源离线 AI 证件照工具,兼顾隐私与效率
  • 使用飞书 AI 知识库搭建个人技术文档系统
  • 2023 年十大前景看好的编程语言
  • Web 应用架构与安全漏洞体系梳理
  • Flask 工厂模式与蓝图设计:构建可扩展大型应用架构
  • 基于 OpenClaw 搭建 QQ AI 办公机器人并配置邮件发送
  • LLaMA-Factory 本地部署与安装配置指南
  • 使用 LLaMA Factory 快速测试不同数据集的微调效果
  • 本地 AI 图像抠图工具:支持 JPG/PNG/WebP 一键处理
  • ExoPlayer 播放缓存进度监听方案实现
  • Linux 进程控制:进程终止与等待及 waitpid 参数解析
  • AI 对话应用接口开发:同步、SSE 流式与智能体前端对接
  • C++26 契约编程新特性:利用静态与动态检查提升代码健壮性
  • AI 驱动接口测试全流程自动化实践
  • AIGC 检测模型训练:基于 Python 爬虫构建高质量文本数据集
  • C++ STL list 容器实现详解
  • 提示工程、微调与 RAG 技术对比及选型指南
  • 插入排序原理及 Java 实现详解
  • Java 浮点数精度陷阱与 BigDecimal 最佳实践

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online