news 2026/9/10 23:17:46

【STM32开源项目】智能家居

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【STM32开源项目】智能家居

目录

一、项目概述

二、实现功能

1、功能详解:

2、项目清单:

3、演示视频:

三、硬件介绍

1、原理图:

2、PCB硬件设计:

四、程序设计

五、项目成品效果图

六、项目总结

七、包含资料



一、项目概述

本项目基于STM32F103C8T6核心处理器,设计了一套集多环境参数监测、本地自动联动与云端远程控制于一体的智能家居环境管理系统。系统集成DHT11、MQ-2、MQ-7、MQ-135、光敏传感器及BMP280,实时采集温湿度、烟雾、一氧化碳、空气质量、光照和气压6项数据,并本地OLED显示。用户可先通过按键设定各传感器触发阈值,再通过模式切换按键选择自动或手动工作模式。自动模式下,异常超标自动蜂鸣报警并开窗通风,光照不足自动补光;手动模式下,用户可通过按键独立控制电机与灯光。借助ESP8266-01S接入机智云平台,用户通过手机APP即可远程查看实时数据、切换模式、控制设备及调整阈值,实现"感知-决策-执行-远程交互"的完整物联网闭环,适用于家庭、车库、仓库等需要环境监控与自动响应的场景。

二、实现功能

  • 1、功能详解:

  • 检测功能:采集温湿度、烟雾、一氧化碳、空气质量、光照、气压共6项环境参数

  • 显示功能:检测数据实时显示于OLED屏幕

  • 阈值调节:通过按键调节各传感器的触发阈值,断电保存

  • 模式切换:一键切换自动/手动模式,OLED显示当前模式

  • 自动模式:烟雾/CO/空气质量超标时蜂鸣报警并开窗通风;光照不足自动开灯

  • 手动模式:通过按键独立控制步进电机和照明灯开关。

  • 机智云APP:通过ESP8266-01S接入云端,实现数据上报与远程控制(模式切换、设备控制、阈值修改)

  • 2、项目清单:

  • STM32F103C8T6最小系统板

  • OLED显示屏

  • DHT11温湿度传感器

  • 光敏传感器

  • MQ-2烟雾传感器

  • MQ-7一氧化碳传感器

  • MQ-135空气质量传感器

  • ESP8266-01S(WIFI模块)

  • BMP280气压传感器、

  • 步进电机

  • 有源蜂鸣器

  • 按键开关

  • 3、演示视频:

  • 哔哩哔哩视频链接点击观看: https://www.bilibili.com/video/BV1dfM76NErm/?share_source=copy_web&vd_source=f4437c8e4429101e5bf1054c39d5474f

三、硬件介绍​​​​​​​

  • 1、PCB硬件设计:

四、程序设计

#include "delay.h" #include "sys.h" #include "usart.h" #include "key.h" #include "stdio.h" #include "control.h" #include "oled.h" #include "adc.h" #include "dht11.h" #include "IoData.h" #include "pwm.h" #include "timer.h" #include "uln2003.h" #include "bmp280.h" #include "aliyun.h" #include "esp8266.h" // 0-连接GND-电平为0V // 1-电平为3.3V // 5V - 电阻 - Led(正)-led(负)- PC13 - 0V // 条件为真 - True - 1 // 条件为假 - False - 0 //extern //函数声明 void OLED_Show_OnePage(); //第一屏显示内容 void OLED_Show_TwoPage(); //第二屏显示内容 void OLED_Show_ThreePage(); //第三屏显示内容 void OLED_Show_FourPage(); //第四屏显示内容 void net_page(); void get_all_sensor_data(); // 传感器采集的函数 void Key_event_handle(void); //按键功能函数 void All_Pin_Init(void); //系统初始化函数 void Sensor_Data_Handle(); //不同模式下控制效果 int temp_door = 35; //温度阈值 int mq2_door = 3000; //烟雾阈值 int mq7_door = 3000; //液化气阈值 int mq135_door=3000; //空气阈值 int Light_door=2000; //光照阈值 int BMP280_door=2000; //气压阈值 int auto_mode = 0; //自动模式开关 0关闭 1开启 int Uln2003_flag=0; //窗户标志位 int Uln2003_status=0; //窗户状态 uint8_t keu_num = 0; //按键 uint8_t page_num = 1; //界面 uint8_t option = 0; //选项 uint8_t net_flag = 1; void All_Pin_Init() { delay_init(); //系统延时函数初始化 OLED_Init(); //屏幕初始化 KEY_Init(); //按键初始化 uart3_init(115200); //串口3初始化,波特率9600 uart1_init(115200); //串口1初始化,波特率115200 uart2_init(9600); //串口2初始化,波特率9600 DHT11_Init(); //DHT11温湿度初始化 Adc_Init(); //烟雾,一氧化碳初始化 Control_Init(); //声光报警,风扇、水泵初始化 TIME_Config(); //定时器,每秒采集一次传感器数值 Uln2003_Init(); //步进电机模拟初始化 BMP280Init(); //气压初始化 } int main(void) { All_Pin_Init(); net_page(); while(net_flag){ keu_num = KEY_Scan(0); //按键扫描赋值 if(keu_num==1){net_flag=0;} else if(keu_num==2){net_flag=0;ESP8266_Init();} } OLED_Clear(); while(1) { // delay_ms(100); Key_event_handle(); //按键监测 if(page_num == 1){ //屏幕更新 OLED_Show_OnePage(); }else if(page_num == 2){ OLED_Show_TwoPage(); }else if(page_num == 3){ OLED_Show_ThreePage(); }else if(page_num==4){ OLED_Show_FourPage(); } if(Time_Period[0]>1000) { Time_Period[0] = 0; Mqtt_Publiash_Aliyun(); get_all_sensor_data(); } Sensor_Data_Handle(); } } void Key_event_handle(void) //(Key)按键 event(事情、逻辑)handle(处理) { keu_num = KEY_Scan(0); //按键=扫描赋值 switch(keu_num) { case 1: //按键1按下 if(page_num==1){ // option=0; page_num=2; // }else if(page_num==2){ // option=0; page_num=3; // OLED_Clear(); // }else if(page_num==3){ // option=0; page_num=4; // OLED_Clear(); //// }else if(page_num==4){ option=0; page_num=1; OLED_Clear(); } break; case 2: //按键2按下 if(page_num==3) { option++; // if(option>4){ // option=0; / } }else if(page_num==4){ option++; if(option>1){ option=0; } } break; case 3: //按键3按下 if(page_num==1){ //页面1 auto_mode=1; //开启自动 }else if(page_num==3){ //页面3 if(option==1)temp_door++; //第一选项 温度阈值增加1 else if(option==2)mq2_door+=25; //第二选项,烟雾阈值增加25 else if(option==3)mq135_door+=25;//第三选项,空气阈值增加25 else if(option==4)mq7_door+=25;//第四选项,一氧化碳阈值增加25 }else if(page_num==4){ //页面4 if(option==1){ ///第一选项 Uln2003_flag=1; //开启风扇 Uln2003_status=1; //状态 } } break; case 4: //按键4按下 if(page_num==1){ //页面1 auto_mode=0; //关闭自动 }else if(page_num==3){ //页面3 if(option==1)temp_door--; //第一选项 温度阈值减1 else if(option==2)mq2_door-=25; //第二选项 烟雾阈值减25 else if(option==3)mq135_door-=25; //第三选项,空气阈值减25 else if(option==4)mq7_door-=25; //第四选项,一氧化碳阈值减25 }else if(page_num==4){ //页面4 if(option==1){ ///第一选项 Uln2003_flag=1; //关闭 Uln2003_status=0; //状态 } } break; } } void get_all_sensor_data() //获取所有传感器数据 { DHT11_Read_Data(&DHT_temp,&DHT_hum); // 获取温度(temp),湿度数据(hum) DHT代码传感器名称_代表连接 Get_MQ2_Value(&MQ2_Value); //采集烟雾阈值(get)采集 value(数值) Get_MQ7_Value(&MQ7_Value); //采集一氧化碳阈值 Get_MQ135_Value(&MQ135_Value); //检测空气数值 Get_Light_Value(&Light_Value); //检测光照数值 BMP280GetData(&bmp280_press,&bmp280,&bmp280); //获取气压数值 bmp280_data = bmp280_press; //获取气压数值 } void Sensor_Data_Handle() //传感器的采集数据的处理 { if(auto_mode==1){ if(MQ2_Value>mq2_door||MQ7_Value>mq7_door||MQ135_Value>mq135_door){ //烟雾、一氧化碳、空气大于阈值 Beep=1; //报警 }else{ Beep=0; //关闭报警 } if(MQ2_Value>mq2_door||MQ7_Value>mq7_door||MQ135_Value>mq135_door){ //烟雾、一氧化碳、空气大于阈值 if(Uln2003_status==0){ Uln2003_status=1; Stepper_RotateByLoop(1,1,1); } }else{ if(Uln2003_status==1){ Uln2003_status=0; Stepper_RotateByLoop(0,1,1); } } }else{ Beep=0; } if(Uln2003_flag==1){ Uln2003_flag=0; Stepper_RotateByLoop(Uln2003_status,1,1); } } void OLED_Show_OnePage() { OLED_ShowString(16*0,16*0,"T:",16,1); //温度 OLED_ShowNum(16*1,16*0,DHT_temp,2,16,1); //数值 OLED_ShowChinese(16*2,16*0,3,16,1); OLED_ShowString(16*4,16*0,"H:",16,1); //湿度 OLED_ShowNum(16*5,16*0,DHT_hum,2,16,1); //数值 OLED_ShowString(16*6,16*0,"%RH",16,1); OLED_ShowChinese(16*0,16*1,8,16,1); //烟 OLED_ShowChinese(16*1,16*1,9,16,1); //雾 OLED_ShowChinese(16*2,16*1,10,16,1); //浓 OLED_ShowChinese(16*3,16*1,11,16,1); //度 OLED_ShowString(16*4,16*1,":",16,1); OLED_ShowNum(16*4+8,16*1,MQ2_Value,4,16,1); //数值 OLED_ShowChinese(16*0,16*2,57,16,1); //光 OLED_ShowChinese(16*1,16*2,58,16,1); //照 OLED_ShowChinese(16*2,16*2,59,16,1); //强 OLED_ShowChinese(16*3,16*2,60,16,1); //度 OLED_ShowString(16*4,16*2,":",16,1); OLED_ShowNum(16*4+8,16*2,Light_Value,4,16,1);//数值 OLED_ShowChinese(16*0,16*3,61,16,1); //大 OLED_ShowChinese(16*1,16*3,62,16,1); //气 OLED_ShowChinese(16*2,16*3,63,16,1); //压 OLED_ShowChinese(16*3,16*3,59,16,1); //强 OLED_ShowString(16*4,16*3,":",16,1); OLED_ShowNum(16*4+8,16*3,bmp280_press,4,16,1); //数值 if(auto_mode==1){OLED_ShowChinese(16*7,16*2,30,16,1); //自 OLED_ShowChinese(16*7,16*3,32,16,1); //动 }else if(auto_mode==0){OLED_ShowChinese(16*7,16*2,31,16,1); //手 OLED_ShowChinese(16*7,16*3,32,16,1); //动 } OLED_Refresh(); } void OLED_Show_TwoPage() { OLED_ShowString(16*0,16*0,"CO",16,1); //一氧化碳 OLED_ShowChinese(16*1,16*0,10,16,1); //浓 OLED_ShowChinese(16*2,16*0,11,16,1); //度 OLED_ShowString(16*3,16*0,":",16,1); OLED_ShowNum(16*3+8,16*0,MQ7_Value,4,16,1); //数值 OLED_ShowChinese(16*0,16*1,66,16,1); //空 OLED_ShowChinese(16*1,16*1,62,16,1); //气 OLED_ShowChinese(16*2,16*1,14,16,1); //质 OLED_ShowChinese(16*3,16*1,15,16,1); //量 OLED_ShowString(16*4,16*1,":",16,1); OLED_ShowNum(16*4+8,16*1,MQ135_Value,4,16,1); //数 OLED_Refresh(); } void OLED_Show_ThreePage() { uint8_t a,b,c,d; if(option==1){a=0;b=1;c=1;d=1;} else if(option==2){a=1;b=0;c=1;d=1;} else if(option==3){a=1;b=1;c=0;d=1;} else if(option==4){a=1;b=1;c=1;d=0;} else{a=1;b=1;c=1;d=1;} OLED_ShowChinese(16*0,16*0,0,16,1); //温 OLED_ShowChinese(16*1,16*0,2,16,1); //度 OLED_ShowChinese(16*2,16*0,22,16,1); //阈 OLED_ShowChinese(16*3,16*0,23,16,1); //值 OLED_ShowString(16*4,16*0,":",16,1); OLED_ShowNum(16*5,16*0,temp_door,2,16,a); //阈值 OLED_ShowChinese(16*0,16*1,8,16,1); //烟 OLED_ShowChinese(16*1,16*1,9,16,1); //雾 OLED_ShowChinese(16*2,16*1,22,16,1); //阈 OLED_ShowChinese(16*3,16*1,23,16,1); //值 OLED_ShowString(16*4,16*1,":",16,1); OLED_ShowNum(16*5,16*1,mq2_door,4,16,b); //阈值 OLED_ShowChinese(16*0,16*2,66,16,1); //空 OLED_ShowChinese(16*1,16*2,62,16,1); //气 OLED_ShowChinese(16*2,16*2,22,16,1); //阈 OLED_ShowChinese(16*3,16*2,23,16,1); //值 OLED_ShowString(16*4,16*2,":",16,1); OLED_ShowNum(16*5,16*2,mq135_door,4,16,c); //阈值 OLED_ShowString(16*0,16*3,"CO",16,1); //一氧化碳 OLED_ShowChinese(16*1,16*3,22,16,1); //阈 OLED_ShowChinese(16*2,16*3,23,16,1); //值 OLED_ShowString(16*3,16*3,":",16,1); OLED_ShowNum(16*4,16*3,mq7_door,4,16,d); //阈值 OLED_Refresh(); } void OLED_Show_FourPage() { uint8_t a,b,c,d; if(option==1){a=0;b=1;c=1;d=1;} else if(option==2){a=1;b=0;c=1;d=1;} else if(option==3){a=1;b=1;c=0;d=1;} else if(option==4){a=1;b=1;c=1;d=0;} else{a=1;b=1;c=1;d=1;} OLED_ShowChinese(16*0,16*0,36,16,1); //通 OLED_ShowChinese(16*1,16*0,37,16,1); //风 OLED_ShowString(16*2,16*0,":",16,1); if(Uln2003_status==1) OLED_ShowChinese(16*3,16*0,24,16,a); //开 else OLED_ShowChinese(16*3,16*0,25,16,a); //关 OLED_Refresh(); } void net_page(){ uint8_t a,b,c,d,i; if(option==1){a=0;b=1;c=1;d=1;} else if(option==2){a=1;b=0;c=1;d=1;} else if(option==3){a=1;b=1;c=0;d=1;} else {a=1;b=1;c=1;d=1;} i = 69; OLED_ShowChinese(16*2,16,i,16,1); // “是” OLED_ShowChinese(16*3,16,i+1,16,1); // “否” OLED_ShowChinese(16*4,16,i+2,16,1); // “配” OLED_ShowChinese(16*5,16,i+3,16,1); // “网” OLED_ShowChar(16*6,16,'?',16,1); // “:” OLED_ShowString(16*0,32,"KEY1 KEY2",16,1); OLED_ShowChinese(16*0,48,i+4,16,1); // “跳” OLED_ShowChinese(16*1,48,i+5,16,1); // “过” OLED_ShowChinese(16*6,48,i+6,16,1); // “确” OLED_ShowChinese(16*7,48,i+7,16,1); // “认” OLED_Refresh(); }

五、项目成品效果图

六、项目总结

本系统成功实现了多传感器融合感知、本地智能联动控制与云端远程交互的有机结合。实际测试表明,传感器数据采集稳定,自动模式下联动响应迅速(报警与开窗动作在阈值超标后2秒内触发),APP远程控制延迟控制在1秒以内。阈值调节功能配合EEPROM存储,增强了现场适应性。项目开发过程中,重点解决了多路ADC采样滤波、MQ系列传感器预热校准、ESP8266与机智云协议对接等关键技术问题。整体软件采用模块化状态机设计,便于后续扩展更多传感器和执行器。本方案成本可控、功能完整,可作为物联网智能家居入门及进阶开发的实用参考范例。

七、包含资料

1)本资料免费分享,获取全套资料请看主页,并将告诉助手需要资料的项目编号,助手收到消息后,会发送百度网盘链接。每人限领两份开源资料。

2)需要实物或者定制的小伙伴可以添加工作室微信,发送项目需求,可以按照需求定制项目。定制包含源码、原理图、全套实物、模块参考资料、更详细的参考资料。

3)重点!!!在本工作室定制的项目,提供一年的技术支持和答疑服务,定制功能范围内的代码和原理图工程师一对一解疑答惑!

资料获取:查看主页介绍“充哥单片机设计”


如果需要项目源码与配套工程文件,欢迎大家在评论区留言交流~
文章若对你有所帮助,期待点赞收藏,后续会持续分享各类单片机实战案例。
内容仅作为学习参考,有任何不妥之处,欢迎大家一起探讨!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 23:17:42

PROFIBUS GSD文件详解:安川变频器通讯配置核心指南

简介:本资源为安川电机GA700、GA500、CH700、A1000及U1000全系列变频器通用GSD文件,面向工业自动化工程师、PLC系统集成人员及现场调试技术人员,解决PROFIBUS-DP等现场总线环境下变频器与上位控制系统(如西门子S7、倍福TwinCAT&am…

作者头像 李华
网站建设 2026/9/10 23:15:58

量子退火算法在TSP问题中的Python实现与优化

1. 量子退火算法与传统TSP求解的困境 旅行商问题(Traveling Salesman Problem, TSP)作为组合优化领域的经典NP难问题,在物流路径规划、芯片布线、DNA测序等实际场景中具有广泛应用。传统计算方法在面对大规模TSP问题时往往面临以下挑战&#…

作者头像 李华
网站建设 2026/9/10 23:13:01

STM32 HAL库实现CANopen PDO数据改变触发:从对象字典到总线验证

简介:YSF4_HAL_CANopen-002围绕CANopen协议中的PDO数据改变触发机制展开,面向STM32嵌入式开发者与工业自动化通信方向学习者,重点解决在STM32 HAL库框架下配置TPDO/RPDO、映射对象字典并实现数据变化自动发送的工程问题。资源共1401个文件&am…

作者头像 李华
网站建设 2026/9/10 23:12:25

Java全栈技术栈下的RAG系统构建与优化实践

1. 从UGC到RAG的技术演进全景图2018年我在某内容平台第一次接触用户生成内容(UGC)系统时,日均处理量还停留在百万级。而今天,我们团队构建的RAG智能助手每天要处理上亿次知识检索请求。这场技术跃迁背后,是Java全栈技术…

作者头像 李华
网站建设 2026/9/10 23:10:20

SQL IFNULL()函数详解与应用实践

1. 深入理解SQL IFNULL()函数IFNULL()是SQL中最基础却最容易被忽视的函数之一。我在处理企业级数据库的十年间,见过无数因为对这个函数理解不透彻而导致的业务逻辑错误。这个函数看似简单,但实际应用中藏着不少门道。IFNULL()的核心功能可以用一句话概括…

作者头像 李华