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

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

一款基于 STM32 的智能家居环境监测系统。系统利用 DHT11、MQ 系列传感器采集温湿度、烟雾及空气质量数据,通过 ESP8266 接入机智云平台实现远程监控。硬件包含 OLED 显示与步进电机控制,软件支持手动与自动模式切换,可根据环境阈值自动报警或调节设备。项目涵盖嵌入式开发、物联网通信及云平台交互技术。

云间漫步发布于 2026/4/5更新于 2026/9/878 浏览
基于 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. 六、软件程序设计

更多推荐文章

查看全部
  • 渐进式 AIGC 聚合系统:多模型私有化部署与 Agent 工作流
  • Arduino BLDC 机器人 IMU 角度读取与 PID 互补滤波控制
  • 本地 AI 智能体 OpenClaw 功能特性与常用指令详解
  • 滑动窗口算法实战:最大连续 1 的个数 III 与将 x 减到 0 的最小操作数
  • Xilinx FPGA 开发:Vivado 流与 Vitis 流深度解析
  • SQL Server 安装与基础使用指南
  • Flutter 使用 sanitize_html 库防御 XSS 注入风险(OpenHarmony 适配)
  • 二分查找实战:旋转排序数组最小值与缺失数字
  • MiniOneRec 框架解析:基于 LLM 的生成式推荐系统实践
  • 如何成为一名黑客
  • ComfyUI ControlNet 模型推荐清单(2025 版)
  • 25 个实用 Prompt 技巧:有效降低 AI 生成内容检测率
  • Docker 镜像仓库基础与实战
  • C++红黑树设计与实现详解
  • Python 基于 Transformer 的时序数据建模与实现详解
  • C++ 继承进阶:友元、静态成员与菱形继承解析
  • OpenClaw 为何爆火?AI Agent 从技术圈走向大众场景的真相
  • 基于 Go 的 AI 临床副驾驶:电子病历智能助手与 HIS 对接实战
  • Figma + Claude + Weavy AI:构建高效设计工作流
  • 深入解析单点登录(SSO)的架构与实现

相关免费在线工具

  • 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

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online