基于STM32的智能路灯系统控制的Proteus仿真



一、智能路灯系统控制

1.题目要求

1、设置时间段、控制灯光亮灭:系统允许用户设定具体的时间段,以自动控制灯光的开启与关闭。
这一功能能够根据城市的实际照明需求,灵活调整路灯工作时间,避免不必要的能耗,提升能源利用效率。

2、光照传感器检测光照强度:系统配备高精度光照传感器,能够实时监测环境光照强度。
当光照低于设定的光照阈值时,系统会自动调整灯光强度,确保夜间或光照不足时,路灯能够提供足够的照明,
满足行人和车辆的安全需求。

3、三挡亮度调节:根据环境光照条件,系统设计了三挡亮度调节功能用户可以根据具体情况选择合适的亮度级别,
以适应不同场景的需求,如人流量大的区域可设置较高的亮度,而人流量较少的区域可选择较低亮度从而实现灵活的照明管理。

4、自动感应亮度调整:系统在光照暗时,通过人体感应传感器检测到有行人经过,将灯光自动调至三挡亮度。
这一智能化功能不仅提升了路灯的使用效率,还增强了夜间的安全性,减少了潜在的交通事故风险。

5、OLED 显示功能:系统配备 OLED 显示屏,能够实时显示当前的光照强度、灯光亮度等级以及是否有人经过。
此功能使得用户可以直观了解当前的环境状况,从而做出及时的管理决策。

6、手机 APP 控制:为了提升用户体验,系统开发了手机 APP 功能用户可以通过移动设备远程监控和控制路灯。
APP界面能够显示实时的光照强度、灯光亮度等级和人员状态,并允许用户设置时间段,实现智能化的管理,增强了系统的可操作性和灵活性。

在这里插入图片描述

2.思路

由上面的功能需求和实物照片,我们可知需要一个单片机STM32F103C8T6,时钟芯片DS1302,光照传感器BH1750,
HCSR501人体传感器,显示屏OLED,WiFi模块ESP8266以及四个按键。

都是一些常见的模块,简单过一遍。

单片机STM32F103C8T6:

在这里插入图片描述

时钟芯片DS1302:

光照传感器BH1750:

HCSR501人体传感器:

显示屏OLED:

在这里插入图片描述

WiFi模块ESP8266(proteus仿真没有,用虚拟终端连接到串口调试助手代替)

在这里插入图片描述

四个按键:

在这里插入图片描述

3.电路仿真

3.1 未仿真

在这里插入图片描述

3.2 开始仿真,显示屏显示初始化连接界面后,转为正常显示界面

1.初始化连接界面

在这里插入图片描述

2.正常显示界面

在这里插入图片描述

3.3 按下模式按键,切换为AUTO1模式

在这里插入图片描述

3.4 再次按下模式按键,切换为HAND模式

手动模式下可以设置低阈值和高阈值

刚进入HAND模式,使用阈值加减按键设置阈值为31(原先为30)

再次按下模式按键,切换为设置高阈值,如果这个时候按下阈值加减,改变的是高阈值的值

在这里插入图片描述

3.5 切换为时间设置界面,设置时间

在这里插入图片描述
通过时间选择按键来选择设定时,分,秒,更新时间

在时分秒下,可以通过时间加或者时间减来设置具体时分秒。在设定好秒之后,再次按下时间选择按键就会将当前时间更新为你所设置的时间。

在这里插入图片描述

3.6 手机设置wifi模式,查询光照强度以及设置时间段

在这里插入图片描述

4.仿真程序

4.1 程序说明

主控芯片:STM32F103C8
HICK:64MHZ
Systick: 1ms

光照传感器:LDR(PA0)

模拟WIFI模块(Uart1):9600(PA9:tx1,PA10:rx1)

按键:
KEY1(PB0)
KEY2(PB1)
KEY3(PB2)
KEY4(PB3)

红外检测IR:(PB4)

模拟路灯:PWM(PB6)

时钟模块:
RST(PB9)
SCLK(PB10)
IO(PB11)

OLED显示屏:SCL(PB14),SDA(PB15)

在这里插入图片描述

串口协议
举例如发送*Wifi1,即设置Wifi开关打开
设置指令:
*WifiX 设置Wifi开关 X取值为0-1(0为关闭,1为打开)
*LampX 设置灯光等级 X取值为0-3(必须在打开Wifi开关后设置)
*TimeXXXXXXXXXXXX 设置时间段 前面XXXX表示开启时间XX时XX分XX秒,后面XXXX表示开启时间XX时XX分XX秒(时必须小于24,分必须小于60,秒必须小于60)

查询指令:查询光照强度、灯光亮度等级和人员状态
*Read

4.2 主程序

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{			
			if (stSysTime.flg._100ms + TEN_MILLISECOND < Time_millis()) //10ms
			{
				stSysTime.flg._10ms = Time_millis();	
                Key_Scan();//按键扫描				
			}
			if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
			{
				stSysTime.flg._50ms = Time_millis();						
				ADC_Scan();//光照检测	
                Led_Scan();//Led扫描				
			}				
			if(stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
			{
				stSysTime.flg._100ms = Time_millis();					
				Receive_data_Handel();//数据接收判断 						
				OLED_Handel();//OLED显示				
				Time_Handel();//时间显示					
				IWDG_ReloadCounter();//清开门狗 				
			}
			if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
			{
				stSysTime.flg._1s = Time_millis();											
			}
  }
}

4.3 OLED显示函数

/*******************************************************************************
 * 函数名:OLED_Handel
 * 描述  :OLED显示
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :100ms
*******************************************************************************/
void OLED_Handel(void)
{  	
	if(wifi_en == 1)
	{
		OLED_ShowString(1, 1, "luminosity");	
		OLED_ShowNum(1,12,ADC_Value,2);
		OLED_ShowString(1, 14, "%");			

		OLED_ShowString(2, 1, "MODE");	
		
		OLED_ShowString(2, 6, "WIFI");	
		
		OLED_ShowNum(2,12,led_grade,2);					

    if(IR_flag)
		{
		  OLED_ShowString(3, 1, "ON");	
      OLED_Part_Clear(3,3,4);			
		}
    else
		{
		  OLED_ShowString(3, 1, "OFF");				
		}	

		OLED_ShowNum(3,6,ADC_Low_Threshold,2);
		OLED_ShowNum(3,12,ADC_High_Threshold,2);			
	}
	else
	{
			if(Screen_switching == 1)
			{
				OLED_ShowString(1, 1, "luminosity");	
				OLED_ShowNum(1,12,ADC_Value,2);
				OLED_ShowString(1, 14, "%");			

				OLED_ShowString(2, 1, "MODE");	
				
				OLED_ShowString(2, 6, "AUTO");	
				
				OLED_ShowNum(2,12,led_grade,2);					

				if(IR_flag)
				{
					OLED_ShowString(3, 1, "ON");	
					OLED_Part_Clear(3,3,4);			
				}
				else
				{
					OLED_ShowString(3, 1, "OFF");				
				}	

				OLED_ShowNum(3,6,ADC_Low_Threshold,2);
				OLED_ShowNum(3,12,ADC_High_Threshold,2);		
			}
			else if(Screen_switching == 2)
			{	
				OLED_ShowString(1, 1, "luminosity");	
				OLED_ShowNum(1,12,ADC_Value,2);
				OLED_ShowString(1, 14, "%");			

				OLED_ShowString(2, 1, "MODE");	
				
				OLED_ShowString(2, 6, "AUTO1");	
				
				OLED_ShowNum(2,12,led_grade,2);					

				if(IR_flag)
				{
					OLED_ShowString(3, 1, "ON");	
					OLED_Part_Clear(3,3,4);			
				}
				else
				{
					OLED_ShowString(3, 1, "OFF");				
				}	

				OLED_ShowNum(3,6,ADC_Low_Threshold,2);
				OLED_ShowNum(3,12,ADC_High_Threshold,2);			
			}
			else if((Screen_switching == 3) || (Screen_switching == 4))
			{	
				OLED_ShowString(1, 1, "luminosity");	
				OLED_ShowNum(1,12,ADC_Value,2);
				OLED_ShowString(1, 14, "%");			

				OLED_ShowString(2, 1, "MODE");	
				
				OLED_ShowString(2, 6, "HAND");	
				
				OLED_ShowNum(2,12,led_grade,2);				

				if(IR_flag)
				{
					OLED_ShowString(3, 1, "ON");	
					OLED_Part_Clear(3,3,4);			
				}
				else
				{
					OLED_ShowString(3, 1, "OFF");				
				}	

				OLED_ShowNum(3,6,ADC_Low_Threshold,2);
				OLED_ShowNum(3,12,ADC_High_Threshold,2);			
			}
			else if(Screen_switching == 5) 
			{	
				OLED_ShowString(1, 1, "NOW Time:");		
				OLED_ShowNum(2,1,Set1_Hour,2);		
				OLED_ShowString(2, 3, ":");	
				OLED_ShowNum(2,4,Set1_Minute,2);		
				OLED_ShowString(2, 6, ":");		
				OLED_ShowNum(2,7,Set1_Second,2);	
				
				OLED_ShowNum(4,1,Set2_Hour,2);		
				OLED_ShowString(4, 3, "-");	
				OLED_ShowNum(4,4,Set2_Minute,2);		
				OLED_ShowString(4, 6, "-");		
				OLED_ShowNum(4,7,Set2_Second,2);				
			}
  }		
}

4.4 串口接收函数

/*******************************************************************************
 * 函数名:Send_Cmd1
 * 描述  :设置Wifi开关          X取值为0-1(0为关闭,1为打开)
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :举例如发送*Wifi1,即设置Wifi开关打开
 *******************************************************************************/
void Send_Cmd1(void)
{
	uint8_t i = 0;
	if(uart1_rx_buf[i+5] == '1')
	{
		OLED_Clear();//OLED清屏		
		wifi_en = 1;		
		printf("打开wifi开关\r\n");		
	}
	else if(uart1_rx_buf[i+5] == '0')
	{		
		OLED_Clear();//OLED清屏		
		wifi_en = 0;		
		printf("关闭wifi开关\r\n");				
	}	
}

/*******************************************************************************
 * 函数名:Send_Cmd2
 * 描述  :*LampX设置灯光等级
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  : X取值为0-3(必须在打开Wifi开关后设置)
 *******************************************************************************/
void Send_Cmd2(void)
{
	uint8_t i = 0;
	if(wifi_en == 1)
	{
	  variable1 = AsciiToHex(uart1_rx_buf[i+5]);	
		if(variable1 < 4)
		{
			led_grade = variable1;
			printf("手机设置的灯光等级 = %d\r\n",led_grade);	
		}	
		else
		{
			printf("手机设置的灯光等级超出设置范围 \r\n");			
		}			
	}
  else
	{
		printf("未打开wifi开关\r\n");					
	}		
}

/*******************************************************************************
 * 函数名:Send_Cmd3
 * 描述  :*TimeXXXXXXXX  设置时间段
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :前面XXXXXX表示开启时间XX时XX分XX秒,后面XXXX表示开启时间XX时XX分XX秒(时必须小于24,分必须小于60,秒必须小于60)
 *******************************************************************************/
void Send_Cmd3(void)
{
	uint8_t i = 0;
	variable2 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6])); 
	variable3 = (AsciiToHex(uart1_rx_buf[i+7])*10+AsciiToHex(uart1_rx_buf[i+8])); 
	variable4 = (AsciiToHex(uart1_rx_buf[i+9])*10+AsciiToHex(uart1_rx_buf[i+10])); 
	
	variable5 = (AsciiToHex(uart1_rx_buf[i+11])*10+AsciiToHex(uart1_rx_buf[i+12])); 
	variable6 = (AsciiToHex(uart1_rx_buf[i+13])*10+AsciiToHex(uart1_rx_buf[i+14])); 
	variable7 = (AsciiToHex(uart1_rx_buf[i+15])*10+AsciiToHex(uart1_rx_buf[i+16])); 	
  if((variable2 < variable5) || ((variable2 == variable5) && (variable3 < variable6)) \
		|| ((variable2 == variable5) && (variable3 == variable6) &&(variable4 < variable7)))
	{
			if((variable2 < 24) && (variable3 < 60) && (variable4 < 60)) 	
			{
				Star_Hour = variable2;
				Star_Minute = variable3;
				Star_Second = variable4;				
				printf("手机设置的开始时间 = %d时%d分%d秒\r\n",Star_Hour,Star_Minute,Star_Second);	
			}	
			else
			{
				printf("手机设置的开始时间超出设置范围 \r\n");			
			}				
			if((variable5 < 24) && (variable6 < 60) && (variable7 < 60)) 		
			{
				End_Hour = variable5;
				End_Minute = variable6;
				End_Second = variable7;				
				printf("手机设置的结束时间 = %d时%d分%d秒\r\n",End_Hour,End_Minute,End_Second);	
			}	
			else
			{
				printf("手机设置的结束时间超出设置范围  \r\n");			
			}	
  }
	else
	{
				printf("手机设置的开始时间大于结束时间 \r\n");		
	}
}

/*******************************************************************************
 * 函数名:Send_Cmd4
 * 描述  :查询光照强度、灯光亮度等级和人员状态
 * 输入  :void
 * 输出  :void
 * 调用  :需要时调用
 * 备注  :
 *******************************************************************************/
void Send_Cmd4(void)
{
   if(ADC_Flag)
   {	
			if(IR_flag)
			{
		     printf("光照强度=%d 灯光亮度等级=%d 有人\r\n",ADC_Value,led_grade);
			}
			else
			{
	       printf("光照强度=%d 灯光亮度等级=%d 无人\r\n",ADC_Value,led_grade);	
			}			 				
   }	
}

/*******************************************************************************
 * Function    : Receive_data_Handel
 * Description : 数据接收判断
 * Input       : 无
 * Return      : 无
 * Call        : 100ms
 * Others      :
 *******************************************************************************/
void Receive_data_Handel(void)
{
	uint8_t i = 0;
	if(uart1_rx_finsh)
	{	  
			for(i = 0;i< 20; i++)
			{
					if(uart1_rx_buf[i] == '*')	
					{
							switch(uart1_rx_buf[i+1])
							{
								case  'W':Send_Cmd1();break;//*WifiX		
								case  'L':Send_Cmd2();break;//*LampX
								case  'T':Send_Cmd3();break;//*TimeXXXXXXXX											
								case  'R':Send_Cmd4();break;//*Read 										
								default:break;							
							}							
					}
			}
			uart1_rx_finsh = 0;	
			uart1_rx_count = 0;
			memset(uart1_rx_buf,0,RX_MAX_NUM);				
	}	
}

二、总结

今天主要讲了基于STM32的智能路灯系统控制的Proteus仿真。

感谢你的观看!

在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiaobuding_QAQ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值