本设计包含原理图+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);
}
}

📚器件清单

📚资料清单

3万+

被折叠的 条评论
为什么被折叠?



