基于STM32的智能窗户仿真设计


本设计包含原理图+PCB+程序代码+器件清单

📚开发环境

程序编译器:keil 5
编程语言:C语言
设计编号:C0006

📚功能说明

1.智能模式:传感器采集的风力、雨水、温度、湿度、PM2.5值、外界烟雾、 外界有毒气体。检测超标时,实现智能关窗;当所有条件满足时系统又 会实现智能开窗;
2.电机控制:开、关窗,并且开窗之后不可以在开窗,关窗后不可以在关窗;
3.安全:外界烟雾、有毒气体超标实现警报,OLED显示危险;
4.安防:有外界物体、人员闯入窗户时实现警报,OLED显示危险;
5.按键:修改温度、湿度关窗阈值、OLED显示内容切换,同时按键可以控制 开窗、关窗(最高优先级,当按键控制关窗后,传感器检测的值就不进 行判断了,需要按键再次按下开窗后,传感器检测恢复智能控制);
6.自动模式:由按键开启后,实现白天开窗、晚上关窗循环模式(开启后传 感器检测的值就不进行判断,关闭后恢复智能控制);
7.手机APP:手机端控制窗户:开窗、关窗、自动模式;
8.OLED显示:显示温度、湿度、PM2.5、风力,窗子的状态(开窗、关窗) 以及初始温度、初始湿度的更改显示。

📚PCB

在这里插入图片描述

📚原理图

在这里插入图片描述

📚源程序

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "bluetooth.h"
#include "buzzer.h"
#include "humiture.h"
#include "key.h"
#include "motor.h"
#include "oled.h"
#include "photosensitive.h"
#include "pm2_5.h"
#include "raindrops.h"
#include "smog.h"

/* 温湿度 */
rt_uint8_t my_temp = 0;    //读取到的温度值
rt_uint8_t my_humidity = 0;//读取到的湿度值

/* 风速和码盘格数 */
float wind_velocity = 0;   //读取到的风速值,码盘半径(25.75mm = 2.575cm = 0.02575m),码盘格数20,周长(3.14 * 0.02575m = 0.080855m),风速(key_type.pulse_count(1s内码盘的格数) * 0.080855m / 20 = x m/s)

/* PM2.5 */
float my_pm = 0;//细颗粒物值

/* 定时器1相关 */
static void timeout1(void* parameter);//定时器1超时回调函数

/* 定时器2相关 */
struct rt_timer timer2;               //定时器2句柄
static void timeout2(void* parameter);//定时器2超时回调函数

/* 静态线程1相关 */
static struct rt_thread thread1;         //静态线程1的句柄
ALIGN(4) static char thread1_stack[2048];//静态线程1的缓存区大小
static void thread1_entry(void *param);  //静态线程1入口函数

/* 外部调用字库数组 */
extern const unsigned char chinese[][16];

/* 函数声明 */
void main_interface(void);          //主界面
void humiture_interface(void);      //温湿度界面
void pm_wind_interface(void);       //PM2.5和风力界面
static void pulse_init(void);       //脉冲初始化
static void pulse_input(void *args);//脉冲输入回调函数

int main(void)
{
	rt_err_t res = -RT_ERROR;
	rt_size_t recv_size = 0;
	char str[16] = {0};
	
	buzzer_init();        //蜂鸣器初始化
	dht11_init();         //DHT11温湿度传感器初始化
	motor_init();         //电机驱动模块初始化
	oled_init();          //OLED显示屏初始化
	photosensitive_init();//光敏电阻传感器初始化(现为红外循迹模块)
	pm2_5_init();         //PM2.5初始化
	raindrops_init();     //雨滴模块初始化
	key_init();           //按键初始化
	
	oled_show_16x16(1, 20, 24, chinese);                       //显示"基"
	oled_show_16x16(1, 36, 25, chinese);                       //显示"于"
	oled_show_6x8_8x16(1, 52, 1, (const rt_uint8_t *)"STM32"); //显示"STM32"
	oled_show_16x16(1, 92, 26, chinese);                       //显示"的"
	oled_show_16x16(4, 16, 27, chinese);
	oled_show_16x16(4, 32, 28, chinese);
	oled_show_16x16(4, 48, 29, chinese);
	oled_show_16x16(4, 64, 30, chinese);
	oled_show_16x16(4, 80, 31, chinese);
	oled_show_16x16(4, 96, 32, chinese);
	
	rt_thread_mdelay(1500);
	
	oled_cls();         //OLED开启
	
	rt_thread_mdelay(150);
	
	main_interface();   //主界面
	pm_wind_interface();//PM2.5和风力界面

	
	/* 静态线程1 */
	res = rt_thread_init(&thread1,             //静态线程1句柄
	                     "thread1",            //静态线程1名称
	                     thread1_entry,        //静态线程1入口函数
	                     RT_NULL,              //静态线程1入口函数参数
	                     &thread1_stack[1],    //静态线程1栈起始地址
	                     sizeof(thread1_stack),//静态线程1栈大小
	                     16,                   //静态线程1优先级
	                     20);                  //静态线程1时间片大小
	if(res != RT_EOK)
		rt_kprintf("thread1 init NG!\r\n");
	else
		rt_thread_startup(&thread1);           //启动线程
	
	/* 启动定时器2 */
	res = rt_timer_start(&timer2);
	if(res != RT_EOK)
		rt_kprintf("timer2 start NO!\r\n");
	
	/* 电机停转 */
	motor_stop();
    while(1)
    {
		/* 判断显示标志,为0可以正常串口蓝牙接收,为1说明进入了设置温湿度界面,防止在设置过程中蓝牙控制开关窗 */
		if(key_type.show_flag == 0)
		{
			/* 扫描蓝牙串口接收 */
			recv_size = rt_device_read(usart1_serial, 0, (char *)str, 16);
			if(recv_size != 0)
			{
				rt_kprintf("recv_size = %d\r\n", recv_size);
				
				rt_kprintf("str = %s\r\n", str);
				
				/* 开窗 */
				if(str[0] == 'K')
				{
					if(key_type.switch_window_flag != 0x01 && key_type.motor_flag == 1)//防止重复开窗
					{
						rt_device_write(usart1_serial, 0, "Open Windows OK!", 64);//回发到蓝牙模块的提示信息
						
						key_type.switch_window_flag = 0x01;
						key_type.motor_flag = 1;
						
						oled_show_16x16(2, 86, 9, chinese);  //显示"开"
						oled_show_16x16(2, 102, 11, chinese);//显示"窗"
						
						/* 电机逆时针转动(开窗) */
						motor_control(1);
						rt_thread_mdelay(3000);
						motor_stop();
						rt_thread_mdelay(100);
						
						key_type.motor_flag = 0;
						
						key_type.key_flag = 0;
					}
					else
						rt_device_write(usart1_serial, 0, "Open Windows NG!", 64);//回发到蓝牙模块的提示信息
				}
				
				/* 关窗 */
				if(str[0] == 'G')
				{
					if(key_type.switch_window_flag != 0x02 && key_type.motor_flag == 1)//防止重复关窗
					{
						rt_device_write(usart1_serial, 0, "Close Windows OK!", 64);//回发到蓝牙模块的提示信息
						
						key_type.switch_window_flag = 0x02;
						key_type.motor_flag = 1;
						
						oled_show_16x16(2, 86, 10, chinese); //显示"关"
						oled_show_16x16(2, 102, 11, chinese);//显示"窗"
						
						/* 电机顺时针转动(关窗) */
						motor_control(0);       	 //开启电机
						rt_thread_mdelay(3000);
						motor_stop();
						rt_thread_mdelay(100);		//停止电机
						
						key_type.motor_flag = 0;  //电机标志位开启
						
						key_type.key_flag = 1;   //关窗标志位
					}
					else
						rt_device_write(usart1_serial, 0, "Close Windows NG!", 64);//回发到蓝牙模块的提示信息
				}
				
				/* 模拟早上开窗,晚上关窗 */
				if(str[0] == 'M')
					key_type.simulation_flag = 5;
				
				memset(str, 0, sizeof(str));
				
				recv_size = 1;
			}
			
			/* 防盗报警扫描 */
			if(get_photosensitive_status() == 0 || get_smog_status() == 0)
			{
				if(key_type.alarm_flag == 0)
				{
					key_type.alarm_flag = 1;
					
					oled_show_16x16(2, 86, 37, chinese); //显示"危"
					oled_show_16x16(2, 102, 38, chinese);//显示"险"
					
					/* 启动定时器1 */
					res = rt_timer_start(&timer1);
					if(res != RT_EOK)
						rt_kprintf("timer1 start NO!\r\n");
				}
			}
			
			/* 烟雾开窗 */
			if(get_smog_status() == 1)
			{
				if(key_type.switch_window_flag != 0x02 && key_type.motor_flag == 0)
				{
					key_type.switch_window_flag = 0x02;
					key_type.motor_flag = 1;
					
					oled_show_16x16(2, 86, 10, chinese); //显示"关"
					oled_show_16x16(2, 102, 11, chinese);//显示"窗"
					
					/* 电机顺时针转动(关窗) */
					motor_control(0);
					rt_thread_mdelay(3000);
					motor_stop();
					rt_thread_mdelay(100);
					
					key_type.motor_flag = 0;
				}
			}
			
			/* 大雨关窗 */
			if(get_raindrops_status() == 0)
			{
				if(key_type.switch_window_flag != 0x02 && key_type.motor_flag == 0)
				{
					key_type.switch_window_flag = 0x02;
					key_type.motor_flag = 1;
					
					oled_show_16x16(2, 86, 10, chinese); //显示"关"
					oled_show_16x16(2, 102, 11, chinese);//显示"窗"
					
					/* 电机顺时针转动(关窗) */
					motor_control(0);
					rt_thread_mdelay(3000);
					motor_stop();
					rt_thread_mdelay(100);
					
					key_type.motor_flag = 1;
				}
			}
			
			/* 大风关窗 */
			if(key_type.pulse_flag)
			{
				if(key_type.switch_window_flag != 0x02 && key_type.motor_flag == 0)
				{
					key_type.switch_window_flag = 0x02;
					key_type.motor_flag = 1;
					
					oled_show_16x16(2, 86, 10, chinese); //显示"关"
					oled_show_16x16(2, 102, 11, chinese);//显示"窗"
					
					/* 电机顺时针转动(关窗) */
					motor_control(0);
					rt_thread_mdelay(3000);
					motor_stop();
					rt_thread_mdelay(100);
					
					key_type.motor_flag = 0;
				}
				key_type.pulse_flag = 1;
			}
			
			/* 大于关窗温度或大于关窗湿度关窗 */
			if((my_temp > key_type.temp_value) || (my_humidity > key_type.humidity_value))
			{
				if(key_type.switch_window_flag != 0x02 && key_type.motor_flag == 0)
				{
					key_type.switch_window_flag = 0x02;
					key_type.motor_flag = 1;
					
					oled_show_16x16(2, 86, 10, chinese); //显示"关"
					oled_show_16x16(2, 102, 11, chinese);//显示"窗"
					
					/* 电机顺时针转动(关窗) */
					motor_control(0);
					rt_thread_mdelay(3000);
					motor_stop();
					rt_thread_mdelay(100);
					
					key_type.motor_flag = 0;
				}
			}
			
			/* 将关窗置为最高优先级,当所有关窗条件失效,才能开窗 */
			if((key_type.pulse_flag != 1) && (my_temp <= key_type.temp_value) && (my_humidity <= key_type.humidity_value)  && (key_type.key_flag == 0))
			{
				if(key_type.switch_window_flag != 0x01 && key_type.motor_flag == 1)
				{
					key_type.switch_window_flag = 0x01;
					key_type.motor_flag = 1;
					
					oled_show_16x16(2, 86, 9, chinese);  //显示"开"
					oled_show_16x16(2, 102, 11, chinese);//显示"窗"
					
					/* 电机逆时针转动(开窗) */
					motor_control(1);
					rt_thread_mdelay(3000);
					motor_stop();
					rt_thread_mdelay(100);
					
					key_type.motor_flag = 0;
				}
			}
			
			/* 模拟早上开窗,晚上关窗 */
			while(key_type.simulation_flag!=0)
			{
				key_type.switch_window_flag = 0x01;
				key_type.motor_flag = 1;
				
				oled_show_16x16(2, 86, 9, chinese);  //显示"开"
				oled_show_16x16(2, 102, 11, chinese);//显示"窗"
				
				/* 电机逆时针转动(开窗) */
				motor_control(1);
				rt_thread_mdelay(3000);
				motor_stop();
				rt_thread_mdelay(10000);
				
				oled_show_16x16(2, 86, 10, chinese); //显示"关"
				oled_show_16x16(2, 102, 11, chinese);//显示"窗"
				
				/* 电机顺时针转动(关窗) */
				motor_control(0);
				rt_thread_mdelay(3000);
				motor_stop();
				rt_thread_mdelay(10000);
				
				oled_show_16x16(2, 86, 9, chinese);  //显示"开"
				oled_show_16x16(2, 102, 11, chinese);//显示"窗"
				
				/* 电机逆时针转动(开窗) */
				motor_control(1);
				rt_thread_mdelay(3000);
				motor_stop();
				rt_thread_mdelay(10000);
				

			}
		}
		
		/* 按键扫描 */
		Button_Process();
		
		/* 延时25ms(不可删除) */
		rt_thread_mdelay(25);
    }
}

在这里插入图片描述

📚器件清单

在这里插入图片描述

📚资料清单

在这里插入图片描述

📚资料下载链接

https://docs.qq.com/doc/DS2dSVXNNWWVyZ291(可点击)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值