基于STM32的智能窗帘系统设计

🤞🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是智能窗帘系统

设计的详细功能见网盘中的文章《18、基于STM32的智能窗帘系统设计》:

链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132

提取码:5132

目录

1、设计要求

2、系统功能

3、演示视频和实物

4、系统设计框图

5、软件设计流程图

6、原理图

7、主程序

8、总结

1、设计要求

智能窗帘控制系统的硬件设计:单片机和显示模块,语音识别模块,光照强度采集模块,一氧化碳传感器和烟雾传感器电路,DHT11温湿度电路,电动机控制电路,报警电路。

2、系统功能

本设计是基于STM32单片机的智能窗帘控制系统设计,主要内容如下:

1、语音识别模块。语音识别模块核心芯片采LD3320芯片,是一种非特定人“语音识别”专用芯片。通“开窗”和“关窗”等关键语句实现对窗帘的语音控制。

2、光控模块。利用光控模块,可以根据日常需求自行设定室内光照度,通过光敏电阻实时监测室外光照度,单片机控制窗帘开合实现室内恒照度控制。窗帘实现光照度自动控制,天亮窗帘自动打开,室外光照度超过设定值自动关闭,天黑窗帘自动关闭。

3、DHT11温湿度模块,系统内置温湿度传感器,能够实时监测室内温湿度。当室内温度过高或过低时,系统会触发窗帘升降,实现通风散热或保温功能。

4、MQ_2烟雾传感器和MQ_7一氧化碳传感器,分别用来监测室内的烟雾和CO浓度,当发送着火等情况用来报警。

5、步进电动机驱动模块。单片机控制步进电动机驱动模块给电动机输入一系列脉冲信号,控制电动机连续转动,带动窗帘运行。当步进驱动器接收到一个脉冲信号时,它就驱动步进电动机按设定的方向转动,通过输出连续脉冲信号控制窗帘的连续移动。

6、时钟模块。利用时钟振荡电路产生时钟信号。单片机时钟可以提供一个固定的时钟频率,用于同步和控制各个模块的操作。通过时钟信号的控制,可以确保单片机系统中各个模块按照一定的时间序列进行操作,从而实现定时功能。

7.OLED显示模块。OLED显示模块采用0.96寸液晶显示屏,该模块用来实时显示室外光照度数据及窗帘工作状态

8、按键模块。按键模块用来控制模式选择和控制窗帘的开启与关闭(手动控制)。

9、蜂鸣器模块。检测到危险气体和烟雾自动报警,设备出现故障用来报警。

10、ESP8266-01S模块,用来连接云平台,这样手机就可以远程通过云平台接收传感器数据和下发指令,控制窗帘。

3、演示视频和实物

基于STM32的语音远程智能窗帘设计

4、系统设计框图

5、软件设计流程图

6、原理图

7、主程序

#include "sys.h"     //有定制和购买的,可以联系VX:lwfw123456789
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "Serial2.h"
#include "dht11.h"
/***********************************************************************************************
同学好!我们是5132单片机设计,定制单片机设计,实物和说明书均可定制,欢迎大家咨询。VX:lwfw123456789
其他项目演示视频和说明请大家移步哔哩哔哩、CSDN和公众号等。
哔哩哔哩:5132单片机设计
CSDN:    5132单片机设计
公众号:  5132单片机设计
抖音  :  5132单片机设计
小红书:  5132单片机设计
咸鱼:    5132单片机设计
************************************************************************************************/
#define Num_i 256                             //电机步数,用来控制步进电机

extern uint32_t bufe[10];                     //存储传感器采集的数据
uint16_t AD0, AD1, AD4, AD5, AD6;             //存储5路ADC值
uint32_t GuangYu_Shang = 70;                  //光照强度阈值上限
uint32_t GuangYu_Xia = 30;                    //光照强度阈值下限
uint32_t TempYu_Shang = 35;
uint32_t TempYu_Xia = 15 ;
uint32_t HumiYu_Shang = 70;
uint32_t HumiYu_Xia = 20;
uint32_t YanYu = 80;
uint32_t COYu = 80;

u8 temp, humi;                                //存放温湿度
u8 state, state2 = 2, state2_1, state3;       //按键状态标志
u8 t = 0;                                     //传感器读取时间间隔
uint8_t KeyNum;                               //存储按键值
u8 Flag_dakai = 0;                            //窗户状态标志
u16 ii = 0;                                   //步进电机循环
extern u8 flag;                               //远程控制标志
u8 flag2 = 0, flag1, flag3;

uint16_t RTC_Time[] = {0, 0, 0};

uint16_t RTC_Time1[] = {7, 0, 0};    //定时时间---开
uint16_t RTC_Time2[] = {19, 0, 0};   //定时时间---关

u8 T_state, T_state1, qingping = 1, state_dingshi_yu_guan, state_dingshi_yu_kai, state_dingshi_yu_switch, state3_1;

extern void TimeSet(void);
extern void TimeRead(void);
void DingShiMoShi(void);

void MY_Gizwits_Init(void)              //机智云初始化函数
{
    TIM3_Int_Init(9, 7199); //1MS系统定时
    usart3_init(9600);//WIFI初始化
    memset((uint8_t *)&currentDataPoint, 0, sizeof(dataPoint_t)); //设备状态结构体初始化
    gizwitsInit();//环形缓冲区初始化
    gizwitsSetMode(2);   //设置模式
    userInit();
}

void close_curtain(void)
{
    for (ii = 0; ii < Num_i; ii++)   //一个周期步进电机转角为0.70312,256个就是179.99872
    {
        Motorcw_angle(1, 3);
        MotorStop();
    }
    Flag_dakai = 0;     // 窗户打开了
    OLED_ShowChinese(1, 1, 14); //  显示屏显示-关
}

void open_curtain(void)
{
    for (ii = 0; ii < Num_i; ii++)
    {
        Motorccw_angle(1, 3);
        MotorStop();
    }
    Flag_dakai = 1;
    OLED_ShowChinese(1, 1, 12);
}

void YuYingMode()   //先说小杰唤醒,然后说打开窗户和关闭窗户
{
    if (Serial2_RxFlag == 1)        //串口接收到数据包的标志位,若是收到数据包,会置1
    {
        if ((strcmp(Serial2_RxPacket, "LIAN_OFF") == 0) && (Flag_dakai == 1)) //比较接收到的字符串是否和对应指令的字符串相等。(需要增加string头文件)
        {
            close_curtain();
        }
        else if ((strcmp(Serial2_RxPacket, "LIAN_ON") == 0) && (Flag_dakai == 0))
        {
            open_curtain();
        }
        Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
    }
    TimeSet();
}
void shoudong()
{
    TimeRead();
    if (KeyNum == 2)        //按键PB0控制窗户开关
    {
        delay_ms(20);
        if (KeyNum == 2)
        {
            state2++;
            if (state2 > 1)
            {
                state2 = 0;
            }
        }
    }
    if (state2 == 0)
    {
        if (Flag_dakai == 0)
        {
            open_curtain();
        }

    }
    if (state2 == 1)
    {
        if (Flag_dakai == 1)
        {
            close_curtain();
        }
    }
}
void zhidong()
{
    TimeRead();
    if (KeyNum == 5)                          //自动模式下PB0按键控制阈值切换
    {
        flag1 = 0;
        flag3 = 0;
        delay_ms(20);
        if (KeyNum == 5)
        {
            state2_1++;
            if (state2_1 > 1)
            {
                state2_1 = 0;
            }
        }
    }
    if (state2_1 == 1)
    {
        flag2 = 1; //传感器阈值
        if (KeyNum == 2)                          //自动模式下PB0按键控制阈值切换
        {
            delay_ms(20);
            if (KeyNum == 2)
            {
                state3++;
                if (state3 > 8)
                {
                    state3 = 0;
                }
            }
        }
        if (state3 == 1)
        {
            if (KeyNum == 3)GuangYu_Shang++;
            if (KeyNum == 4)GuangYu_Shang--;
        }
        if (state3 == 0)
        {
            if (KeyNum == 3)GuangYu_Xia++;
            if (KeyNum == 4)GuangYu_Xia--;
        }
        if (state3 == 6)
        {
            if (KeyNum == 3)YanYu++;
            if (KeyNum == 4)YanYu--;
        }
        if (state3 == 7)
        {
            if (KeyNum == 3)COYu++;
            if (KeyNum == 4)COYu--;
        }
        if (state3 == 3)
        {
            if (KeyNum == 3)TempYu_Shang++;
            if (KeyNum == 4)TempYu_Shang--;
        }
        if (state3 == 2)
        {
            if (KeyNum == 3)TempYu_Xia++;
            if (KeyNum == 4)TempYu_Xia--;
        }
        if (state3 == 5)
        {
            if (KeyNum == 3)HumiYu_Shang++;
            if (KeyNum == 4)HumiYu_Shang--;
        }
        if (state3 == 4)
        {
            if (KeyNum == 3)HumiYu_Xia++;
            if (KeyNum == 4)HumiYu_Xia--;
        }
    }
    if (state2_1 == 0)
    {
        flag2 = 0;  //传感器信息
        /*********室内烟雾和CO量超过各自阈值,蜂鸣器报警***********/
        if ((bufe[1] > YanYu) || (bufe[2] > COYu))
        {
            Buzzer_ON();
        }
        else
        {
            Buzzer_OFF();
        }
        /************优先级1---光照强度***************/
        if ((bufe[0] > GuangYu_Shang) && (Flag_dakai == 0))
        {
            open_curtain();      //光照强度大于光照强度上限就打开窗户
        }
        else  if ((bufe[0] < GuangYu_Xia) && (Flag_dakai == 1))
        {
            close_curtain();    //光照强度小于光照强度下限就关闭窗户
        }
        else
        {
            /************优先级2---温度***************/
            if ((bufe[3] > TempYu_Shang) && (Flag_dakai == 0))
            {
                open_curtain();     //温度大于温度上限就打开窗户
            }
            else  if ((bufe[3] < TempYu_Xia) && (Flag_dakai == 1))
            {
                close_curtain();    //温度小于温度下限就关闭窗户
            }
            else
            {
                /************优先级2---湿度***************/
                if ((bufe[4] > HumiYu_Shang) && (Flag_dakai == 0))
                {
                    open_curtain();     //湿度大于湿度上限就打开窗户
                }
                else  if ((bufe[4] < HumiYu_Xia) && (Flag_dakai == 1))
                {
                    close_curtain();    //湿度小于湿度下限就关闭窗户
                }
            }
        }
    }
}


int main(void)
{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(9600);       //串口初始化为9600
    delay_init();      //延时函数初始化

    LED_Init();            //初始化与LED连接的硬件接口
    DHT11_Init();
    Buzzer_Init();             //下面为外设初始化
    OLED_Init();
    Key_Init();
    AD_Init();
    MyRTC_Init();
    Moto_Init();
    Serial2_Init();   //串口2初始化(语音识别模块)
    MY_Gizwits_Init();   //机智云初始化

    LED = 0;

    while (1)
    {
        userHandle();    //数据上传
        gizwitsHandle((dataPoint_t *)&currentDataPoint);   //后台处理,必须放在while里

        DHT11_Read_Data(&temp, &humi);  //读取温湿度并显示在OLED上
        bufe[3] = temp;
        bufe[4] = humi;


        if (state != 4)
        {
            if (flag2 == 0)      //显示传感器信息
            {
                if (flag1 == 0) //目的就是使OLED_Clear();执行一次
                {
                    OLED_Clear();
                    flag1 = 1;
                }
                OLED_ShowChinese(2, 1, 53);
                OLED_ShowChinese(2, 2, 54);
                OLED_ShowString(2, 5, ":");
                OLED_ShowNum(2, 6, bufe[0], 2);
                OLED_ShowString(2, 8, "%");

                OLED_ShowChinese(3, 1, 60);
                OLED_ShowChinese(3, 2, 61);
                OLED_ShowString(3, 5, ":");
                OLED_ShowNum(3, 6, bufe[1], 2);
                OLED_ShowString(3, 9, "CO:");
                OLED_ShowNum(3, 12, bufe[2], 2);

                OLED_ShowChinese(4, 1, 26);
                OLED_ShowChinese(4, 2, 28);
                OLED_ShowString(4, 5, ":");
                OLED_ShowChinese(4, 5, 27);
                OLED_ShowChinese(4, 6, 28);
                OLED_ShowString(4, 13, ":");
                OLED_ShowNum(4, 6, bufe[3], 2);
                OLED_ShowNum(4, 14, bufe[4], 2);
            }
            else                 //显示阈值
            {
                if (flag3 == 0) //目的就是使OLED_Clear();执行一次
                {
                    OLED_Clear();
                    flag3 = 1;
                }
                OLED_ShowString(2, 1, "G:");
                OLED_ShowNum(2, 3, GuangYu_Xia, 2);
                OLED_ShowString(2, 5, "-");
                OLED_ShowNum(2, 6, GuangYu_Shang, 2);

                OLED_ShowString(3, 1, "W:");
                OLED_ShowNum(3, 3, TempYu_Xia, 2);
                OLED_ShowString(3, 5, "-");
                OLED_ShowNum(3, 6, TempYu_Shang, 2);

                OLED_ShowString(4, 1, "S:");
                OLED_ShowNum(4, 3, HumiYu_Xia, 2);
                OLED_ShowString(4, 5, "-");
                OLED_ShowNum(4, 6, HumiYu_Shang, 2);

                OLED_ShowString(2, 10, "Y :");
                OLED_ShowNum(2, 13, YanYu, 2);

                OLED_ShowString(3, 10, "CO:");
                OLED_ShowNum(3, 13, COYu, 2);

            }
        }

        if (t % 10 == 0)
        {
            AD0 = AD_GetValue(ADC_Channel_0);    //光照传感器     PA0
            if (AD0 > 4000)AD0 = 4000;
            bufe[0] = (u8)(100 - (AD0 / 40));

            AD1 = AD_GetValue(ADC_Channel_1);    //MQ2传感器
            if (AD1 > 4000)AD1 = 4000;
            bufe[1] = (u8)(80 - (AD1 / 40));

            AD4 = AD_GetValue(ADC_Channel_4);    //MQ7传感器
            if (AD4 > 4000)AD4 = 4000;
            bufe[2] = (u8)(80 - (AD4 / 40));

        }
        t++;

        KeyNum = Key_GetNum();

        if (KeyNum == 1)
        {
            qingping = 0;
            state2 = 2,
            delay_ms(20);
            if (KeyNum == 1)
            {
                state++;
                if (state > 4)
                {
                    state = 0;
                }
            }
        }
        if (state == 0)    //远程模式
        { 
					   if (qingping == 0)
            {
                OLED_Clear();
                qingping = 1;
            }	
            TimeRead();
            OLED_ShowChinese(1, 7, 49);
            OLED_ShowChinese(1, 8, 50);
            if ((flag == 1) && Flag_dakai == 0)
            {
                flag = 0;
                open_curtain();
            }
            if ((flag == 2) && Flag_dakai == 1)
            {
                flag = 0;
                close_curtain();
            }
        }
        if (state == 1)    //自动模式
        {
				
					
            OLED_ShowChinese(1, 7, 51);
            OLED_ShowChinese(1, 8, 52);
            zhidong();
        }
        if (state == 2)    //手动模式
        {
            OLED_ShowChinese(1, 7, 18);
            OLED_ShowChinese(1, 8, 52);
            shoudong();
        }
        if (state == 3)    //语音模式
        {
            OLED_ShowChinese(1, 7, 57);
            OLED_ShowChinese(1, 8, 58);
            YuYingMode();
        }
        if (state == 4)    //语音模式
        {
            if (qingping == 0)
            {
                OLED_Clear();
                qingping = 1;
            }
            OLED_ShowChinese(1, 7, 68);
            OLED_ShowChinese(1, 8, 69);
            DingShiMoShi();
        }

    }
}



void TimeSet()           //设置时间
{
    if (KeyNum == 2)    //PB10
    {
        delay_ms(20);
        if (KeyNum == 2)
        {
            T_state++;
            if (T_state > 2)
            {
                T_state = 0;
            }
        }
    }
    if (T_state == 0)    //时间显示模式
    {
        MyRTC_ReadTime();

        OLED_ShowNum(1, 5, MyRTC_Time[3], 2);    //时
        OLED_ShowString(1, 7, ":");
        OLED_ShowNum(1, 8, MyRTC_Time[4], 2);    //分
        OLED_ShowString(1, 10, ":");
        OLED_ShowNum(1, 11, MyRTC_Time[5], 2);   //秒

        RTC_Time[0] = MyRTC_Time[3];
        RTC_Time[1] = MyRTC_Time[4];
        RTC_Time[2] = MyRTC_Time[5];
    }
    if (T_state == 1)    //修改时间
    {
        if (KeyNum == 5)
        {
            delay_ms(20);
            if (KeyNum == 5)
            {
                T_state1++;
                if (T_state1 > 2)
                {
                    T_state1 = 0;
                }
            }
        }
        if (T_state1 == 0)  //修改时
        {
            if (KeyNum == 4)RTC_Time[0]++;
            if (KeyNum == 3)RTC_Time[0]--;
            if (RTC_Time[0] > 23 & RTC_Time[0] < 100)RTC_Time[0] = 0;
            if (RTC_Time[0] > 100)RTC_Time[0] = 23;
            OLED_ShowNum(1, 5, RTC_Time[0], 2);  //时
        }
        if (T_state1 == 1)  //修改分
        {
            if (KeyNum == 4)RTC_Time[1]++;
            if (KeyNum == 3)RTC_Time[1]--;
            if (RTC_Time[1] > 59 & RTC_Time[1] < 100)RTC_Time[1] = 0;
            if (RTC_Time[1] > 100)RTC_Time[1] = 59;
            OLED_ShowNum(1, 8, RTC_Time[1], 2);  //时
        }
        if (T_state1 == 2)  //修改秒
        {
            if (KeyNum == 4)RTC_Time[2]++;
            if (KeyNum == 3)RTC_Time[2]--;
            if (RTC_Time[2] > 59)RTC_Time[2] = 0;
            if (RTC_Time[2] > 59 & RTC_Time[2] < 100)RTC_Time[2] = 0;
            if (RTC_Time[2] > 100)RTC_Time[2] = 59;
            OLED_ShowNum(1, 11, RTC_Time[2], 2);  //时
        }
    }
    if (T_state == 2)
    {
        MyRTC_Time[3] = RTC_Time[0];
        MyRTC_Time[4] = RTC_Time[1];
        MyRTC_Time[5] = RTC_Time[2];
        MyRTC_SetTime();
        T_state = 0;
    }
}

void TimeRead()
{
    MyRTC_ReadTime();

    OLED_ShowNum(1, 5, MyRTC_Time[3], 2);    //时
    OLED_ShowString(1, 7, ":");
    OLED_ShowNum(1, 8, MyRTC_Time[4], 2);    //分
    OLED_ShowString(1, 10, ":");
    OLED_ShowNum(1, 11, MyRTC_Time[5], 2);   //秒
}


void DingShiMoShi()
{
    TimeRead();

//...............................定时模式..................................../
    if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2]))
    {
        open_curtain();
    }

    if ((MyRTC_Time[3] == RTC_Time2[0]) && (MyRTC_Time[4] == RTC_Time2[1]) && (MyRTC_Time[5] == RTC_Time2[2]))
    {
        close_curtain();
    }

//...............................修改定时时间..................................../

    OLED_ShowChinese(3, 1, 31);  
    OLED_ShowString(3, 3, ":");    		
    OLED_ShowNum(3, 5, RTC_Time1[0], 2);     
    OLED_ShowString(3, 7, ":");
    OLED_ShowNum(3, 8, RTC_Time1[1], 2);
    OLED_ShowString(3, 10, ":");
    OLED_ShowNum(3, 11, RTC_Time1[2], 2);

    OLED_ShowChinese(4, 1, 32);  
    OLED_ShowString(4, 3, ":"); 
    OLED_ShowNum(4, 5, RTC_Time2[0], 2);
    OLED_ShowString(4, 7, ":");
    OLED_ShowNum(4, 8, RTC_Time2[1], 2);
    OLED_ShowString(4, 10, ":");
    OLED_ShowNum(4, 11, RTC_Time2[2], 2);


    if (KeyNum == 5)
    {
        delay_ms(20);
        if (KeyNum == 5)
        {
            state_dingshi_yu_switch++;
            if (state_dingshi_yu_switch > 2)
            {
                state_dingshi_yu_switch = 0;
            }
        }
    }

    if (state_dingshi_yu_switch == 1)    //设置阈值开的时间
    {
        if (KeyNum == 2)
        {
            delay_ms(20);
            if (KeyNum == 2)
            {
                state_dingshi_yu_kai++;
                if (state_dingshi_yu_kai > 2)
                {
                    state_dingshi_yu_kai = 0;
                }
            }
        }
        if (state_dingshi_yu_kai == 0)    //时
        {
            if (KeyNum == 3) RTC_Time2[0]++;
            if (KeyNum == 4) RTC_Time2[0]--;
        }
        if (state_dingshi_yu_kai == 1)//分
        {
            if (KeyNum == 3) RTC_Time2[1]++;
            if (KeyNum == 4) RTC_Time2[1]--;
        }
        if (state_dingshi_yu_kai == 2)//秒
        {
            if (KeyNum == 3) RTC_Time2[2]++;
            if (KeyNum == 4) RTC_Time2[2]--;
        }



    }
    else
    {
        if (KeyNum == 2)
        {
            delay_ms(20);
            if (KeyNum == 2)
            {
                state_dingshi_yu_guan++;
                if (state_dingshi_yu_guan > 2)
                {
                    state_dingshi_yu_guan = 0;
                }
            }
        }
        if (state_dingshi_yu_guan == 0)    //时
        {
            if (KeyNum == 3) RTC_Time1[0]++;
            if (KeyNum == 4) RTC_Time1[0]--;
        }
        if (state_dingshi_yu_guan == 1)//分
        {
            if (KeyNum == 3) RTC_Time1[1]++;
            if (KeyNum == 4) RTC_Time1[1]--;
        }
        if (state_dingshi_yu_guan == 2)//秒
        {
            if (KeyNum == 3) RTC_Time1[2]++;
            if (KeyNum == 4) RTC_Time1[2]--;
        }
    }
    if (state3_1 == 0)    //时
    {
        if (KeyNum == 5) RTC_Time1[0]++;
        if (KeyNum == 6) RTC_Time1[0]--;
    }
    if (state3_1 == 1)//分
    {
        if (KeyNum == 5) RTC_Time1[1]++;
        if (KeyNum == 6) RTC_Time1[1]--;
    }
    if (state3_1 == 2)//秒
    {
        if (KeyNum == 5) RTC_Time1[2]++;
        if (KeyNum == 6) RTC_Time1[2]--;
    }
}

8、总结

智能窗帘控制系统的硬件设计:单片机和显示模块,语音识别模块,光照强度采集模块,一氧化碳传感器和烟雾传感器电路,DHT11温湿度电路,电动机控制电路,报警电路。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

5132单片机设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值