毕业/课程设计——基于STM32的智能灯光控制系统(智能家居、手机APP控制、语音控制)

news2024/11/20 0:05:53

        文章首先介绍本系统所包含的功能,主要包含六方面功能,之后逐步分享开发过程,其流程如下:点亮灯带(三极管)调节灯光亮度(PWM)→为系统添加远程控制功能→为系统添加语音识别功能→添加超声波姿态监测功能→添加OLED显示功能

        特别主要:本文不是将所有程序罗列在一起,而是按照上放所说的流程进行,添加一个功能,展示一下该功能的程序,这种方式对学习者非常有利,观看完本文肯定能明白类似的智能家居系统如何开发!!!!

一、功能介绍

1、远程控制灯光:手机端app远程控制灯光开关(手机app自主开发)
        手机端通过触发相应的组件,将相应的控制命令上传至云平台,esp-01s通过wifi信号连接该云平台获取到该指令,由stm32控制灯光亮灭、暖光与冷光切换、一档、二档、三档调节

2、语音控制功能:通过语音控制灯光
        采用高识别率离线语音识别模块,识别使用者的语音命令,通过说话的方式控制灯光亮灭、暖光与冷光切换、一档、二档、三档调节

3、远程显示功能:环境温度、湿度在手机端显示
        系统具备dht11测温传感器,单片机驱动这个传感器工作,并将相应的数据通过esp-01s 、云平台,上传至手机app显示。

4、坐姿异常监测显示:超声波传感器测距身体的距离
        使用本系统制作台灯时,可添加该功能,监测坐姿是否规范,若距离过近,蜂鸣器报警,并在OLED屏幕上显示。

5、系统当前状态显示:灯光是否开启、挡位显示、坐姿是否异常等在OLED屏显示
        将当前时刻系统的工作状态显示在OLED屏幕上,包括灯光是否打开、挡位、坐姿是否异常,当以上状态发生变化时,OLED及时更改显示(既OLED始终显示最新的状态)。

6、RTC实时时钟:OLED显示实时时钟,且支持按键离线修改
        本项目利用核心板上的RTC时钟晶振,开发实时时钟,在时间显示界面可以观察到具体时间,且本项目支持“通过按键修改时间”。K1:进入时间设置界面、切换所修改的时间单位、返回时间显示界面,K2:时间加一个单位,K3:时间减一个单位

        在时间显示界面触发K1按键,进入时间设置界面;之后触发K1按键设置不同的时间单位,刚进入时间设置界面时是对年份进行修改,再按一下K1对月份进行修改,如此递推(oled屏幕上有个小箭头,小箭头所指的就是当前正在修改的时间单位),当最后在按下一次K1时,返回时间显示界面,并进行时间更新。

二、详细阐述开发流程

2.1、先让灯亮起来

        正如章节3中所说,灯带是通过三极管(NPN)驱动的,单片机的IO口连接三极管基极,可以将其看成控制信号,当该引脚输出高电平时,可以认为三极管导通,电流由集电极所连的VCC提供,也就是用电源给灯带供电,这个电流远大于IO口直接输出的电流,足以满足灯带的需求。

2.2、调节灯光亮度

        刚刚已经介绍过如何使用三极管点亮灯带。那么又该如何控制灯的亮度哪?也就是如何控制电流呢?这就需要常说的PWM输出了,可以将三极管看成一个“水龙头”,PWM可以理解为我们拧水龙头的力气,通过调节不同的占空比,使得三极管“打开不同的口子”,控制逻辑如下:

①PWM占空比大→“打开的口子大”→输出的电流大→灯带更亮

②PWM占空比小→“打开的口子小”→输出的电流小→灯带更暗

        在程序中首先将IO口配置为PWM输出,本设计选用的定时器4的通道3与通道4产生PWM(两个灯,一个冷光一个暖光,需要两路PWM输出)具体程序如下:

void Motor_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	//使能定时器4时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
	 
   /*****输出TIM4_CH3和TIM4_CH4和的PWM脉冲波形*****/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //TIM_CH3和TIM_CH4 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
 
   /********************初始化TIM3*******************/
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	/*******初始化TIM4 Channel3、TIM4 Channel4 PWM模式********/	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
	TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //初始化外设TIM4 OC3
	TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //初始化外设TIM4 OC4

   /*******使能预装载寄存器********/
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  
	TIM_Cmd(TIM4, ENABLE);  //使能TIM4
	
}

        

        如此PWM的输出就已经配置好了,下面就在主循环中调用修改PWM占空比函数即可,具体程序如下,该程序修改了三个不同的占空比,以对应灯光的一档、二档、三档。

/********两端都使能 1档**********/
TIM_SetCompare3(TIM4,5000);					
TIM_SetCompare4(TIM4,5000);	

/********两端都使能 2档**********/
TIM_SetCompare3(TIM4,10000);	
TIM_SetCompare4(TIM4,10000);	

/********两端都使能 3档**********/
TIM_SetCompare3(TIM4,20000);	
TIM_SetCompare4(TIM4,20000);	

4.3、远程控制功能

        正如上文所说,远程控制功能实现的原理是,手机app连接云平台,手机APP相应按键触发时,将相应的控制指令上传至云平台,esp-01s通过周围的WiFi信号连接云平台,获取云平台上的数据,并通过串口将该数据传输给STM32单片机,单片机解析数据并完成相应的驱动。接下来逐步进行开发,分为手机端app的制作,手机连接云平台、设备连接云平台。

4.3.1手机端app的制作:

        本项目使用一款麻省理工研发的开发安卓app的平台——appinventor,该平台基于图形化编程,是“不愿意编程党”的福音,不需要使用代码开发app,使用一些逻辑关系模块完成开发。首先在主页面拖放好各种想要的按键,之后在编程界面拖放逻辑关系模块,完成开发(与labview相似)。

4.3.2手机端连接云平台:

        在使用appinventor开发的过程中,调用连接云平台接口,连接云平台,博主使用的是巴法云平台,在巴法云官网有详细的教程。打开巴法云官网,其界面如图8所示,点击图片中所圈的地方“实例指南”进入巴法云论坛,之后在论坛中找到“APP inventor编写安卓app控制ESP8266”这篇文章,如图9所示,里面有详细的制作过程。

图8 巴法云界面

图9 论坛内容

        需要注意的是连接云平台的接口,ClientSocketAI2Ext,这个不是appinventor的原生组件,需要再Extension下导自行导入插件。

4.3.3设备(单片机)连接云平台

        esp-01s也是一个MCU,通过编程开发,本设计通过arduino平台开发相关的功能,值得注意的是esp-01s通过WiFi信号连接云平台,所以环境中必须要有WiFi,由于此处程序过多,仅展示重要的地方。

①云平台定义及主题相关定义,具体程序如下:

#include <ESP8266WiFi.h>
#include<SimpleDHT.h>

//巴法云服务器地址
#define TCP_SERVER_ADDR "bemfa.com"
//服务器端口,tcp创客云端口8344
#define TCP_SERVER_PORT "8344"

//********************需要修改的部分*******************//
#define DEFAULT_STASSID  "HUAWEI P30 Pro+"     //WIFI名称,区分大小写,不要写错
#define DEFAULT_STAPSW   "18253858772"        //WIFI密码
String UID = "23f9a5f2d3584dc8516409db14b4827c";  //用户私钥,可在控制台获取,修改为自己的UID
String TOPIC1 ="TD00light";         //主题名字,可在控制台新建
String TOPIC2 = "TD00temp";       //用户私钥,可在控制台获取,修改为自己的UID
const int LED_Pin = 0;              //单片机LED引脚值,GPIO0引脚
int pinDHT11 = 2;
//**************************************************//

②接下来是连接服务器,向服务器发送指令cmd=1&uid="+UID+"&topic="+TOPIC1+"\r\n,其中的UID与TOPIC1就是上方程序中的相关定义。

具体程序如下:

void startTCPClient()
{
if(TCPclient.connect(TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT)))
{   
	Serial.print("\nConnected to server:");
Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_POR	T));
    	String tcpTemp="";  //初始化字符串
   	 	tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC1+"\r\n"; //构建订阅指令
   	 	sendtoTCPServer(tcpTemp); //发送订阅指令
    	tcpTemp="";//清空
    	preTCPConnected = true;
   	 	preHeartTick = millis();
    	TCPclient.setNoDelay(true);
  }
  Else
{
    Serial.print("Failed connected to server:");
    Serial.println(TCP_SERVER_ADDR);
    TCPclient.stop();
    preTCPConnected = false;
  }
  preTCPStartTick = millis();
}

③获取云平台传来的数据,并通过串口传输给STM32,具体程序如下:

if (TCPclient.available()) //若有数据传来
{
   char c =TCPclient.read();
   TcpClient_Buff +=c;        //数据存储
   TcpClient_BuffIndex++;
   TcpClient_preTick = millis();
   if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1)
   {
      TcpClient_BuffIndex = MAX_PACKETSIZE-2;
      TcpClient_preTick = TcpClient_preTick - 200;
    }
    preHeartTick = millis();
 }
if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
{
   TCPclient.flush();
   Serial.println(TcpClient_Buff);    //串口传输
   if((TcpClient_Buff.indexOf("&msg=11") > 0)) 
{
      turnOnLed();
    }else if((TcpClient_Buff.indexOf("&msg=10") > 0)) 
{
      turnOffLed();
    }
   TcpClient_Buff="";
   TcpClient_BuffIndex = 0;
}

        如此就可以将云平台中的控制指令传输给STM32,STM32进行解析并完成相应的控制,由于本设计还添加了语音识别功能,所以相关控制的实现等讲解完语音识别后在进行讲解。

4.4语音识别功能

        语音识别功能主要采用了SU-03T离线语音识别模块,这个模块不需要编程,使用厂家提供的云平台(智能公元)开发,正如前文所说本设计主要用了该模块的串口功能,该模块的串口与STM32单片机的另一个串口连接,当识别到相应的语音时,串口输出相应的控制指令给STM32。在此只展示打开灯光、关闭灯光、打开冷光、打开暖光对应的指令,分别为0x11、0x10、0x21、0x22,相关配置如图10所示。

图10 su-03t平台配置

4.5STM32解析指令并完成相关驱动

        正如前文所说,WiFi模块与su-03t都是使用串口与STM32单片机建立联系的,所以我们首先需要完成串口的相关配置,在此以WiFi模块对应的usart3为例,配置串口。       

具体程序如下:

void usart3_init(u32 bound)
{  
NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

/***********使能时钟************/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);					RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
 	USART_DeInit(USART3);  //复位串口3

/*******配置输出引脚*******/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10
   
    /*******配置输入引脚*******/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB11
	
/********串口相关配置********/
	USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFl
owControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART3, &USART_InitStructure); //初始化串口3

	USART_Cmd(USART3, ENABLE);                    //使能串口 
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断   
	
	/*******设置中断优先级********/
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	TIM3_Int_Init(1000-1,7200-1);		//10ms中断
	USART3_RX_STA=0;		       //清零
	TIM_Cmd(TIM3,DISABLE);			//关闭定时器7
}

        至此WiFi模块对应的串口就配置完成,su-0t对应的串口配置与该串口相似,WiFi模块传输来的数据是需要解析的,而su-03t直接传输的十六进制,不需要解析,所以接下来就是解析WiFi模块通过串口传来的数据。

具体程序如下:

if(USART3_RX_STA&0X8000)		//接收到一次数据了
{ 
	rlen=USART3_RX_STA&0X7FFF;	//得到本次接收到的数据长度
	USART3_RX_BUF[rlen]=0;		//添加结束符 

	//数据提取
	if(strncmp(USART3_RX_BUF,"cmd=2",5)==0)
	{
		for(i=0;i<strlen(USART3_RX_BUF)+1;i++)
		{
			data_tiqu[s]=USART3_RX_BUF[i];
			s++;
		}
		printf("%s",data_tiqu);
		for(i=0;i<strlen(data_tiqu);i++)
		{
			if(data_tiqu[i]==cmd[0])
			{
				k=i;
				k++;
				for(j=1;j<strlen(cmd);j++)
				{
					if(data_tiqu[k]==cmd[j])
					{
						k++;
						flag=1;
					}
					else
					{
						flag=0;
					}
				}
			}			
		}
		s=0;
		//数据提取结束
		printf("\r\n\r\n");
		if(flag==1)
		{
			for(i=k+1;i<strlen(data_tiqu)+1;i++) //此时 i为传输接受数据的索引
			{
				data[s]=data_tiqu[i];
				s++;
			}
			printf("%s",data);
			printf("zaici");     //作用:程序定位
			printf("\r\n");
		}
	}
	if(strncmp(USART3_RX_BUF,"cmd=0&res=1",11)==0)
	{
		printf("%s",USART3_RX_BUF);
	}
	USART3_RX_STA=0;
}

                解析好的数据就存放在data这个数组中,接下来就在主循环中判断data数组中存放的数据以及su-03t通过串口直接传来的十六进制指令即可,根据相应的指令完成相关外设的驱动。

具体程序如下。

/******************驱动控制**************************/
//判断APP控制开关灯
if((data[0]=='1'&&data[1]=='1') || (temp == 0x11))
{
cold_light_flag = 1;
warmth_light_flag = 0;
TIM_SetCompare3(TIM4,5000);					//初始时冷光亮
TIM_SetCompare4(TIM4,0);	
	
temp=0;
state_flag_temp=11;
state_flag[0]=1;  //冷亮
state_flag[2]=1;  //一档

display_on[5] = 24;             //已为您打开灯(oled显示的汉字在数组中的索引)
display_on[6] = 0;              //已为您打开灯(oled显示的汉字在数组中的索引)
}
if((data[0]=='1'&&data[1]=='0') || (temp == 0x10))
{
cold_light_flag = 0;
	warmth_light_flag = 0;
	temp=0;
	state_flag_temp=10;
	state_flag[0]=0;   
	state_flag[1]=0;
	state_flag[2]=0;  
	display_off[5] = 24;
	display_off[6] = 0;
}
//判断APP控制冷暖光调节
if(((data[0]=='2'&&data[1]=='1') || (temp == 0x21)) && (cold_light_flag == 0)) //冷亮暖灭
{
	cold_light_flag = 1;
	warmth_light_flag = 0;
	TIM_SetCompare3(TIM4,5000);					
	TIM_SetCompare4(TIM4,0);	
	
	temp=0;
	state_flag_temp=21;
	state_flag[0]=1;  //冷亮
	state_flag[1]=0;  //暖灭
	
	display_on[5] = 26;             
	display_on[6] = 25;             
}
if(((data[0]=='2'&&data[1]=='2') || (temp == 0x22))  && (warmth_light_flag == 0)) //冷灭暖亮
{
	cold_light_flag = 0;
	warmth_light_flag = 1;
	TIM_SetCompare3(TIM4,0);					/ 
	TIM_SetCompare4(TIM4,5000);	
	
	temp=0;
	state_flag_temp=22;
	state_flag[0]=0;  //冷灭
	state_flag[1]=1;  //暖亮
	display_on[5] = 27;          
	display_on[6] = 25;
}		
//调节灯光的1、2、3档位
if((data[0]=='3'&&data[1]=='1')|| (temp == 0x31))			  //1档
{
	if(warmth_light_flag == 1)				//调节暖光
	{
		TIM_SetCompare3(TIM4,0);					
		TIM_SetCompare4(TIM4,5000);	
	}
	else if(cold_light_flag == 1) 				//调节冷光
	{
		TIM_SetCompare3(TIM4,5000);				
		TIM_SetCompare4(TIM4,0);	
	}
	temp=0;
	state_flag_temp=31;
	state_flag[2]=1;     //一档
	display_now[5] = 37;              
}
if((data[0]=='3'&&data[1]=='2')|| (temp == 0x32))			  //2档
{
	if(warmth_light_flag == 1)
	{
		TIM_SetCompare3(TIM4,0);				
		TIM_SetCompare4(TIM4,10000);	
	}
	else if(cold_light_flag == 1)
	{
		TIM_SetCompare3(TIM4,10000);					
		TIM_SetCompare4(TIM4,0);	
	}
	temp=0;
	state_flag_temp=32;
	state_flag[2]=2; 		 //二档
	display_now[5] = 38;

}
if((data[0]=='3'&&data[1]=='3')|| (temp == 0x33))			   //3档
{
	if(warmth_light_flag == 1)
	{
		TIM_SetCompare3(TIM4,0);					
		TIM_SetCompare4(TIM4,20000);	
	}
	else if(cold_light_flag == 1)
	{
		TIM_SetCompare3(TIM4,20000);					
		TIM_SetCompare4(TIM4,0);	
	}
	temp=0;
	state_flag_temp=33;
	state_flag[2]=3;  	//三档
	display_now[5] = 39;
	
}

至此台灯的控制功能已经全部开发完毕,已经实现了APP远程控制、语音控制功能。

4.6、超声波识别坐姿

        超声波模块使用的事HC-SR04,该模块主要是用于把该系统做成台灯时使用,用于检测坐姿规范的,若是开发家里的照明灯,可不加该模块。该模块实现测距的主要原理是:发射装置发射超声波,同时打开定时器,超声波遇到障碍物反弹,被接收装置接受,此时获取定时器的时间,然后根据速度计算距离。其坐姿判断逻辑如下:

HC-SR04测距低于阈值→坐姿不对,距离桌面过近→蜂鸣器报警

HC-SR04测距高于阈值→坐姿正确,距离桌面适宜→蜂鸣器正常

具体程序见如下

float Hcsr04GetLength(void )
{
	u32 t = 0;
	int i = 0;
	float lengthTemp = 0;
	float sum = 0;
	while(i!=5)
	{
		TRIG_Send = 1;      //发送口高电平输出
		Delay_Us(20);
		TRIG_Send = 0;
		while(ECHO_Reci == 0);      //等待接收口高电平输出
		OpenTimerForHc();        //打开定时器
		i = i + 1;
		while(ECHO_Reci == 1);
		CloseTimerForHc();        //关闭定时器
		t = GetEchoTimer();        //获取时间,分辨率为1US
		lengthTemp = ((float)t/58.0);//cm
		sum = lengthTemp + sum ;
	}
	lengthTemp = sum/5.0;
	return lengthTemp;
}
Hcsr_num++;
if(Hcsr_num == 5)
{
	Hcsr_num = 0;
	length_C = Hcsr04GetLength();                 //测距离
	printf("距离为:%.3f\r\n",length_C);
	if(length_C < 20)
	{
		state_flag[3] =1;
		BEEP =~ BEEP;
		delay_ms(300);
	}
	else
	{
		state_flag[3] =0;
		BEEP = 0;
	}
	if(Hcsr_flag != state_flag[3])
	{
		Hcsr_flag = state_flag[3];
		display_all_flag=1;
	}
}

5.6OLED屏显示状态

        本文第二章也介绍了一个OLED模块,以及展示了相关显示图片,这部分实现的原理是,在上方介绍相关控制功能时会更改相应的标志位,然后在主程序中检查该标志位的状态,当标志位发生改变时,修改OLED屏幕的显示。

具体程序如下。

switch(Dis_mode)
{
	case 0:	  									  //在显示控制状态界面
		switch(state_flag_temp)     //定时显示界面
		{
			case 11:control_part_display(2,6,display_1,display_on);break;   //显示“以为您打开灯”
			case 10:control_part_display(2,6,display_1,display_off);break;   //显示“以为您关闭灯”
			case 21:control_part_display(1,7,display_1,display_on);break;   //显示“以为您打开冷灯”
			case 22:control_part_display(1,7,display_1,display_on);break;   //显示“以为您打开暖灯”
			case 31:control_part_display(1,7,display_1,display_now);break;  //显示 “当前亮度为一档”
			case 32:control_part_display(1,7,display_1,display_now);break;  //显示“当前亮度为二档”
			case 33:control_part_display(1,7,display_1,display_now);break;  //显示“当前亮度为三档”
		}
		data[0]='0';               //清空控制指令
		data[1]='0';
		state_flag_temp=0;
		if(display_all_flag)        //状态整体显示界面
		{
			display_all_flag=0;
			control_all_display(state_flag);
			TIM_Cmd(TIM2,DISABLE);  	 //关闭TIM2定时器
		}
	break;

	case 1:									 //在始终显示界面
		RTC_Display();							 //显示时钟
	break;

       至此,智能灯光系统的相关功能已全部开发完毕,电路板接上电源后系统开始工作,可使用APP控制、语音控制两种方式,实现灯光的开关、一档二档三档的的调节、冷暖光的调节、以及姿势纠正等功能。

感觉未分享清楚、有疑惑

有咨询问题、了解具体内容、需要帮助者 可私信联系

欢迎大家指正交流,有空可以一起讨论代码啊。

制作不易,感谢大家支持,感谢!!!!!!

  --------------一个正在努力的人

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/81995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【脚本项目源码】Python实现鲁迅名言查询系统

前言 本文给大家分享的是如何通过利用Python实现鲁迅名言查询系统&#xff0c;废话不多直接开整~ 开发工具 Python版本&#xff1a; 3.6 相关模块&#xff1a; PyQt5模块 fuzzywuzzy模块 环境搭建 安装Python并添加到环境变量&#xff0c;pip安装需要的相关模块即可。 …

R语言使用最优聚类簇数k-medoids聚类进行客户细分

k-medoids聚类简介 k-medoids是另一种聚类算法&#xff0c;可用于在数据集中查找分组。k-medoids聚类与k-means聚类非常相似&#xff0c;除了一些区别。k-medoids聚类算法的优化功能与k-means略有不同。最近我们被客户要求撰写关于聚类的研究报告&#xff0c;包括一些图形和统…

【JavaWeb开发-Servlet】将项目部署在云服务器

目录 1、环境 &#xff08;1&#xff09;连接服务器 &#xff08;2&#xff09;安装JDK1.8​编辑 ①到官网下载环境 ②将压缩包上传至linux中 ③解压jdk压缩包 ④修改文件名 ⑤配置环境变量 &#xff08;3&#xff09;安装MySQL5.0 ①先下载MySQL的yum库 ②选择5.7发行版本…

基于C#+SQL Server(WinForm)学生选课及成绩查询管理系统【100010027】

学生选课及成绩查询管理系统的设计与开发 1、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分&#xff0c;传统的人工管理档案的方式存在着很多的缺点&#xff0c;如&#xff1a;效率低、保密性差等&#xff0c;所以开发一套综合教务系统管理软件很有必要&#xff…

Shell基础

获取命令结果$? 如果上一个命令是成功的则结果为0 否则为127 结果是 www.qfdu.com is down! EOF使用 sh 其实是bash的一个链接&#xff0c;本质上还是执行bash 然后脚本第一句表示使用什么执行器&#xff0c;如果写的是python但是你执行的时候不指定python会报错&#x…

Linux安装Mysql(图文解说详细版,安装包tar包版)

上次教大家用yum安装mysql https://blog.csdn.net/csdnerM/article/details/121095527&#xff0c; 结果还要小伙伴不知道tar包怎么安装&#xff0c;现在出个tar包安装的教程出来供大家参考 文章目录&#x1f3e2;1.官网下载tar包&#xff08;安装包&#xff09;&#x1f3e3;…

多个著名 Go 开源项目被放弃,做大开源不能用爱发电,更不能只靠自己!

大家好&#xff0c;我是煎鱼。相信关注我的许多同学都有接触 Go 语言的开发&#xff0c;甚至在企业中多有实践。那么你在日常开发中&#xff0c;势必会接触到 gorilla[1] 组织下的各个 Go 开源项目。如下图&#xff1a;gorilla/mux[2]&#xff1a;Star&#xff1a;17.9k。a pow…

VMWare复制CentOS虚拟机后无法联网

1. 现象描述 原来使用一个 CentOS 虚拟机&#xff0c;这里叫 CentOS_1。网络配置如下&#xff1a;VMWare软件设置 NAT 模式&#xff0c;虚拟机配置 DHCP 自动获取 IP &#xff0c;开机启动网络。可以正常联网 现在要重新配置一个虚拟机&#xff0c;环境同 CentOS_1。因此我直…

视频恢复软件哪个好用?推荐这几款恢复率高的软件

如果你意外删除了电脑保存的视频文件&#xff0c;无论是单击回收站“还原”还是通过电脑系统备份“还原”&#xff0c;它都无法恢复。如何解决这个问题&#xff1f;此时&#xff0c;你需要寻求文件删除恢复软件的帮助&#xff0c;推荐下面这几款恢复率高的视频恢复软件。如何操…

安卓讲课笔记6.3 使用SQLite数据库

文章目录零、本讲学习目标一、导入新课二、新课讲解&#xff08;一&#xff09;SQLite数据库1、SQLite构成2、SQLite数据类型3、SQLite数据库特点&#xff08;二&#xff09;使用SQLiteDatabase类操作数据库1、创建安卓应用2、准备图片素材3、字符串资源文件4、主布局资源文件5…

0停机迁移Nacos?Java字节码技术来帮忙

摘要&#xff1a;本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos。本文分享自华为云社区《0停机迁移Nacos&#xff1f;Java字节码技术来帮忙》&#xff0c;作者&#xff1a;华为云PaaS服务小智。 1.市场迁移云环境痛点 市场微服务迁移云环境难主要有以下几…

[ MySQL ] 使用Navicat进行MySQL数据库备份 / 还原(Part 2:备份.sql文件方式)

本文主要讲解如何用Navicat&#xff08;Navicat Premium &#xff0c;或者Navicat for mysql&#xff09;进行MySQL备份和恢复数据库&#xff08;利用.sql文件的方式&#xff09;。 关于MySQL数据库备份&#xff0c;本博客内主要相关文章有&#xff1a; [ MySQL ] 使用Navica…

兔子来源中性粒细胞膜

兔子来源中性粒细胞膜 1.按组成元素分 构成细胞膜的成分有磷脂&#xff0c;糖蛋白&#xff0c;糖脂和蛋白质。 2.按组成结构分 磷脂双分子层是构成细胞膜的基本支架。细胞膜的主要成分是蛋白质和脂质&#xff0c;含有少量糖类。其中部分脂质和糖类结合形成糖脂&#xff0c;部分…

“你家娃为什么这么爱看书?”只用3招,孩子秒变小书迷

我儿子从幼儿园带回来一个消息&#xff0c;说班上所有的孩子都在老师那里订课外书。我儿子立即向老师解释说&#xff1a;我不需要买书。我妈妈给我买了很多书。我家里有很多书。我每天都读。家长群里有家长艾特问我的孩子为什么这么喜欢读书。为什么孩子们喜欢读书&#xff0c;…

作业12:第七章课后题

目录习题7-1 在小批量梯度下降中&#xff0c;试分析为什么学习率要和批量大小成正比习题7-2 在Adam算法中&#xff0c;说明指数加权平均的偏差修正的合理性习题7-9 证明在标准的随机梯度下降中&#xff0c;权重衰减正则化和L_{2}正则化的效果相同.并分析这一结论在动量法和Adam…

【Vue2+Element ui通用后台】左侧菜单实现

文章目录主体布局搭建左侧菜单搭建左侧菜单跳转主体布局搭建 我们在 Container 布局容器&#xff0c;找到有左侧、头部、和主体部分的布局&#xff0c;直接复制代码到 Main.vue 中&#xff1a; <template><div><el-container><el-aside width"200p…

「从零入门推荐系统」06:推荐系统召回算法介绍

作者 | gongyouliu编辑 | gongyouliu我们在前面几章中介绍了推荐系统的一些基本概念&#xff0c;从本章开始我们会进入推荐系统的核心章节&#xff0c;也就是关于推荐算法部分的介绍。我们在第五章「推荐系统业务流程与架构」中讲到推荐系统一般会分为召回和排序两个阶段&#…

ADI Blackfin DSP处理器-BF533的开发详解38:图像处理专题-Sobel 算子边缘检测(含源代码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 功能介绍 代码实现了 Sobel 算子的图像边缘检测&#xff0c;代码运行时&#xff0c;会通过文件系统打开工程文件根目下" …/ImageView"…

Java集合和常见数据结构以及泛型

Java集合和常见数据结构以及泛型集合概述Collection集合的体系特点Collection集合常用APICollection集合的遍历方式方法一&#xff1a;迭代器方法二&#xff1a;foreach/增强for循环方法三&#xff1a;lambda表达式Collection集合存储自定义类型的对象常见数据结构数据结构概述…

PDF格式如何转成Excel?这篇文章教会你如何转换

不知道在日常的办公中&#xff0c;大家有没有碰到过这样一个问题&#xff1a;当领导给你发个PDF文件后&#xff0c;要求你尽快的将PDF文件中的表格数据进行修改&#xff0c;但当你把PDF转换成Excel格式后&#xff0c;发现转换后的文件排版格式错乱的。可是截止时间的压迫和乱七…