目录
一、项目概述
本项目基于STM32F103C8T6最小系统板设计了一款智能窗户控制器,旨在实现窗户的智能化监测与自动控制。系统集成了多种环境检测模块,包括DHT11温湿度传感器、MQ135空气质量传感器、光电红外传感器和雨量传感器,可实时采集室内外环境数据,并通过OLED显示屏进行本地显示。
在控制方面,系统支持自动与手动两种工作模式。自动模式下,可根据预设时间定时开关窗户,并结合外界温湿度、空气质量、雨水及人体闯入情况智能判断是否关窗;手动模式下,用户可通过按键直接控制窗户开关。此外,系统还支持按键设置时间与各参数阈值,并可连接蓝牙APP实现远程信息查看与控制指令下发,提升了系统的实用性与便捷性。
二、实现功能
1、功能详解:
1)主控单元:STM32F103C8T6最小系统板作为主控单元。
2)检测模块:DHT11检测温湿度,MQ135检测空气质量,光电红外检测是否有人闯入,雨量传感器检测是否下雨。
3)显示模块:OLED显示屏实时显示所有检测信息。
4)控制模块:自动模式下定时开关窗户并根据外界情况判断是否关窗;手动模式下按键控制窗户开关。
5)设置与交互模块:按键设置时间与各参数阈值,可切换模式;连接蓝牙APP远程查看信息与控制下发
2、项目清单:
STM32F103C8T6单片机
OLED显示屏
DHT11温湿度传感器
MQ135空气质量传感器
光电红外传感器
雨量传感器
步进电机
有源蜂鸣器
LED灯
BT04A蓝牙模块
3、演示视频:
哔哩哔哩视频链接点击观看:https://www.bilibili.com/video/BV1sNNv6sEXW/?share_source=copy_web&vd_source=f4437c8e4429101e5bf1054c39d5474f
三、硬件介绍
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 "timer.h"
#include "uln2003.h"
#include "esp8266.h"
#include "aliyun.h"
//函数声明
void OLED_Show_OnePage(); //第一屏显示内容
void OLED_Show_TwoPage(); //第二屏显示内容
void OLED_Show_ThreePage(); //第三屏显示内容
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 hum_door = 60; //湿度阈值
int mq135_door = 1000; //烟雾阈值
int auto_mode = 0; //自动模式开关 0关闭 1开启
int led_status = 0; //照明开关状态
int keu_num = 0; //按键
int page_num = 1; //界面
int option = 0; //选项
int Uln2003_flag=0; //窗户标志位
int Uln2003_status=0; //窗户状态
uint8_t net_flag=1;
int main(void)
{
delay_init(); //系统延时函数初始化
OLED_Init(); //屏幕初始化
uart3_init(115200); //串口3初始化,波特率9600
uart1_init(115200); //串口1初始化,波特率115200
uart2_init(9600); //串口2初始化,波特率9600
KEY_Init(); //按键初始化
DHT11_Init(); //DHT11温湿度初始化
Adc_Init(); //烟雾,一氧化碳初始化
IoData_Init(); //火焰传感器、人体传感器
Control_Init(); //声光报警,风扇、水泵初始化
Uln2003_Init();
TIME_Config();
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)
{
if(Time_Period[0]>1000){
Time_Period[0]=0;
Mqtt_Publiash_Aliyun();
get_all_sensor_data();
}
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();
}
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){
page_num=2;
OLED_Clear(); // 屏幕清楚
option=0;
}else if(page_num==2){
page_num=3;
OLED_Clear(); // 屏幕清楚
option=0;
}else if(page_num==3){
page_num=1;
OLED_Clear(); // 屏幕清楚
option=0;
}
break;
case 2: //按键2按下
if(page_num==2){
option++;
if(option>3){
option=0;
}
}else if(page_num==3){
option++;
if(option>1){
option=0;
}
}
break;
case 3: //按键3按下
if(page_num==1){
auto_mode=1;
}else if(page_num==2){
if(option==1)temp_door++;
else if(option==2)hum_door++;
else if(option==3)mq135_door+=25;
}else if(page_num==3){
if(option==1){
Uln2003_flag=1; //开启风扇
Uln2003_status=1; //状态
}
}
break;
case 4: //按键4按下
if(page_num==1){
auto_mode=0;
}else if(page_num==2){
if(option==1)temp_door--;
else if(option==2)hum_door--;
else if(option==3)mq135_door-=25;
}else if(page_num==3){
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_MQ135_Value(&MQ135_Value); //采集烟雾阈值(get)采集 value(数值)
Get_rain_Value(&rain_Value); //检测雨滴状态(Fire)(status)状态
Get_Body_Value(&body_status);
}
void Sensor_Data_Handle() //传感器的采集数据的处理
{
if(auto_mode==1){
if(DHT_temp>temp_door||DHT_hum>hum_door||MQ135_Value>mq135_door){
if(rain_Value==1 || body_status==1){
if(body_status==1){
Beep = 1;
}else{
Beep = 0;
}
if(Uln2003_status==1){
Uln2003_status=0;
Stepper_RotateByLoop(Uln2003_status,1,1);
}
}else{
if(Uln2003_status==0){
Uln2003_status=1;
Stepper_RotateByLoop(Uln2003_status,1,1);
}
Beep = 0;
}
}else{
if(Uln2003_status==1){
Uln2003_status=0;
Stepper_RotateByLoop(Uln2003_status,1,1);
}
Beep = 0;
}
}else {
Beep = 0;
}
if(Uln2003_flag==1){
Uln2003_flag=0;
Stepper_RotateByLoop(Uln2003_status,1,1);
}
}
void OLED_Show_OnePage()
{
// OLED_ShowChinese(16*0,16*0,0,16,1); //温
// OLED_ShowChinese(16*1,16*0,54,16,1); //度
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_ShowChinese(16*0,16*0,1,16,1); //湿
// OLED_ShowChinese(16*1,16*0,2,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,12,16,1);//空
OLED_ShowChinese(16*1,16*1,13,16,1);//气
OLED_ShowChinese(16*2,16*1,14,16,1);//质
OLED_ShowChinese(16*3,16*1,15,16,1);//量
OLED_ShowChar(16*4,16*1,':',16,1);// 字符
OLED_ShowNum(16*4+8,16*1,MQ135_Value,4,16,1);// 采集的空气阈值、ShowNum(显示数值)
OLED_ShowChinese(16*0,16*2,43,16,1);//人
OLED_ShowChinese(16*1,16*2,44,16,1);//体
OLED_ShowChar(16*2,16*2,':',16,1);// 字符
if(body_status==1)OLED_ShowChinese(16*2+8,16*2,20,16,1); //有
else OLED_ShowChinese(16*2+8,16*2,21,16,1); //无
OLED_ShowChinese(16*0,16*3,60,16,1);//降
OLED_ShowChinese(16*1,16*3,13,16,1);//雨
OLED_ShowChar(16*2,16*3,':',16,1);// 字符
if(rain_Value==1){
OLED_ShowChinese(16*2+8,16*3,20,16,1); //有
OLED_ShowChinese(16*3+8,16*3,58,16,1); //雨
}
else{ OLED_ShowChinese(16*2+8,16*3,21,16,1); //无
OLED_ShowChinese(16*3+8,16*3,58,16,1); //雨
}
if(auto_mode==0){
OLED_ShowChinese(16*7,16*2,31,16,1); //手
OLED_ShowChinese(16*7,16*3,32,16,1); //动
}else{
OLED_ShowChinese(16*7,16*2,30,16,1); //自
OLED_ShowChinese(16*7,16*3,32,16,1); //动
}
OLED_Refresh();
}
void OLED_Show_TwoPage()
{
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,54,16,1); //度
OLED_ShowChinese(16*2,16*0,22,16,1);//阈
OLED_ShowChinese(16*3,16*0,23,16,1);//值
OLED_ShowChar(16*4,16*0,':',16,1);//字符
OLED_ShowNum(16*5,16*0,temp_door,3,16,a);// 温度数值
OLED_ShowChinese(16*0,16*1,1,16,1);//湿
OLED_ShowChinese(16*1,16*1,2,16,1); //度
OLED_ShowChinese(16*2,16*1,22,16,1);//阈
OLED_ShowChinese(16*3,16*1,23,16,1);//值
OLED_ShowChar(16*4,16*1,':',16,1);//字符
OLED_ShowNum(16*5,16*1,hum_door,3,16,b);// 温度数值
OLED_ShowChinese(16*0,16*2,12,16,1); //空
OLED_ShowChinese(16*1,16*2,13,16,1); //气
OLED_ShowChinese(16*2,16*2,22,16,1); //阈
OLED_ShowChinese(16*3,16*2,23,16,1); //值
OLED_ShowChar(16*4,16*2,':',16,1);
OLED_ShowNum(16*5,16*2,mq135_door,4,16,c);//数值
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,28,16,1); //窗
OLED_ShowChinese(16*1,16*0,29,16,1); //户
OLED_ShowChar(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 = 61;
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();
}
五、项目成品效果图

六、项目总结
本项目以STM32F103C8T6为核心,结合多传感器融合与蓝牙通信技术,完成了一套功能完整的智能窗户控制系统。系统实现了环境信息采集、OLED实时显示、自动/手动窗户控制、阈值设置及远程蓝牙控制等功能,涵盖了从数据采集、逻辑判断到执行控制的完整闭环。通过本项目,可有效提升家居环境的舒适性与安全性,同时也为嵌入式系统学习与物联网应用开发提供了一个典型的实战案例。
七、包含资料
本资料免费分享,获取全套资料请看主页,并将告诉助手需要资料的项目编号,助手收到消息后,会发送资料给你。
资料获取:查看主页介绍"充哥单片机设计"
文章若对你有所帮助,期待点赞收藏,后续会持续分享各类单片机实战案例。
内容仅作为学习参考,有任何不妥之处,欢迎大家一起探讨!

