【STM32项目开源】基于STM32的智能路灯控制系统

目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"


一、设计背景和意义

1.1设计背景

随着城市化进程的加快和智慧城市概念的普及,公共照明系统的智能化改造成为当前研究的热点之一。传统的路灯系统普遍存在能源浪费、管理效率低下、维护成本高等问题。例如,许多路灯仍采用固定亮度或简单定时开关的控制方式,无法根据实际环境需求动态调节,导致在无人时段或光照充足的情况下仍持续工作,造成电力资源的浪费。此外,故障检测依赖人工巡检,响应速度慢,维护成本较高。

1.2设计意义

该系统以STM32微控制器为核心,结合多传感器数据融合技术和物联网平台,实现了路灯的按需照明、远程监控及智能管理。相较于传统照明方式,该系统能够根据环境光照强度和人体活动情况自动调节亮度,在保证照明需求的同时最大限度地降低能耗,符合国家"双碳"战略对绿色节能技术的迫切需求。同时,通过接入机智云平台,管理人员可以实时监控路灯状态、远程调整参数,并借助故障报警功能快速定位问题,大幅提升运维效率。

二、实物效果展示

2.1实物图片

2.2实物演示视频

【开源】基于STM32的智能LED路灯系统

三、硬件功能简介

3.1项目功能详解

  1. 传感器检测:检测光照强度、监测人体红外
  2. 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
  3. 执行机构:系统可以控制路灯的调光。
  4. 接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台。
  5. App远程监控:通过App远程监控全部传感器数据;
  6. 阈值数据设定:系统通过按键设定阈值,也可以通过手机App远程设定。
  7. 模式切换:可以通过按键或者手机App实现自动/手动模式的切换。
  8. 故障模拟:设定了特定按键来模拟实现故障的检测,按键按下后,系统报故障,同时灯灭
  9. 手动模式:通过手机App或小程序控制开关
  10. 自动模式:根据环境的光亮自动调节LED灯的亮度,两个光敏分别调节
  11. 定时开关:可以设定时间实现自动开关。

3.2元器件清单

  1. 主控STM32F103C8T6最小系统板
  2. 0.96 OLED显示屏幕
  3. ESP8266联网WIFI
  4. 人体红外热释电传感器
  5. 红外对管
  6. DS1302时钟模块
  7. 光敏电阻2

四、主框图与软件流程图

主框图

流程图

五、硬件PCB展示

六、软件程序设计

cpp 复制代码
#define KEY_Long1	11

#define KEY_1	1
#define KEY_2	2
#define KEY_3	3
#define KEY_4	4

#define FLASH_START_ADDR	0x0801f000	//写入的起始地址

uint8_t hc501;						//存储人体信号
uint8_t systemModel = 0;				//存储系统当前模式

uint8_t hour,minute,second;			//时 分 秒
uint8_t menu = 1;					//显示菜单变量


SensorModules sensorData;	//声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold;	//声明传感器阈值结构体变量



/**
  * @brief  记录阈值界面下按KEY1的次数
  * @param  无
  * @retval 返回次数
  */
uint8_t SetSelection(void)
{
	static uint8_t count = 1;
	if(KeyNum == KEY_1)
	{
		KeyNum = 0;
		count++;
		if (count >= 4)	{
			count = 1;
		}
	}
	return count;
}

/**
  * @brief  显示阈值界面的选择符号
  * @param  num 为显示的位置
  * @retval 无
  */
void OLED_Option(uint8_t num)
{
	switch(num)
	{
		case 1:	
			OLED_ShowChar(1,1,' ');
			OLED_ShowChar(2,1,'>');
			OLED_ShowChar(3,1,' ');
			OLED_ShowChar(4,1,' ');
			break;
		case 2:	
			OLED_ShowChar(1,1,' ');
			OLED_ShowChar(2,1,' ');
			OLED_ShowChar(3,1,'>');
			OLED_ShowChar(4,1,' ');
			break;
		case 3:	
			OLED_ShowChar(1,1,' ');
			OLED_ShowChar(2,1,' ');
			OLED_ShowChar(3,1,' ');
			OLED_ShowChar(4,1,'>');
			break;
		default: break;
	}
}

/**
  * @brief  显示时间调节界面的选择符号
  * @param  num 为显示的位置
  * @retval 无
  */
void OLED_Time_Option(u8 num)
{
	switch(num)
	{
		case 1:	

			OLED_ShowChar(2,6,'v');
			OLED_ShowChar(2,9,' ');
			OLED_ShowChar(2,12,' ');
			break;
		case 2:	
			OLED_ShowChar(2,6,' ');
			OLED_ShowChar(2,9,'v');
			OLED_ShowChar(2,12,' ');
			break;
		case 3:	
			OLED_ShowChar(2,6,' ');
			OLED_ShowChar(2,9,' ');
			OLED_ShowChar(2,12,'v');
			break;
		default: break;
	}
}

/**
  * @brief  显示时间调节界面的内容
  * @param  无
  * @retval 无
  */
void OLED_ThresholdTime(void)
{
	//系统时间:
	OLED_ShowChinese(1, 3, 20); 
	OLED_ShowChinese(1, 4, 21); 
	OLED_ShowChinese(1, 5, 28); 
	OLED_ShowChinese(1, 6, 29); 
	OLED_ShowChar(1, 13, ':');

	OLED_ShowNum(3,5,hour,2);
	OLED_ShowChar(3,7,':');
	OLED_ShowNum(3,8,minute,2);
	OLED_ShowChar(3,10,':');
	OLED_ShowNum(3,11,second,2);
}

/**
  * @brief  对阈值界面的传感器阈值进行修改
  * @param  num 为当前用户需要更改的传感器阈值位置
  * @retval 无
  */
void ThresholdModification(uint8_t num)
{
	switch (num)
	{
		case 1:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				OLED_Clear();
				menu = timeSettingsPage;
				
				hour = MyRTC_Time[3];
				minute = MyRTC_Time[4];
				second = MyRTC_Time[5];	
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				OLED_Clear();
				menu = timeSettingsPage;
				
				hour = MyRTC_Time[3];
				minute = MyRTC_Time[4];
				second = MyRTC_Time[5];
			}			
			break;		

		case 2:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				Sensorthreshold.Illumination_threshold += 10;
				if (Sensorthreshold.Illumination_threshold > 999)
				{
					Sensorthreshold.Illumination_threshold = 1;
				}
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				Sensorthreshold.Illumination_threshold -= 10;
				if (Sensorthreshold.Illumination_threshold < 1)
				{
					Sensorthreshold.Illumination_threshold = 999;
				}				
			}			
			break;
		case 3:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				Sensorthreshold.Distance_threshold++;
				if (Sensorthreshold.Distance_threshold > 99)
				{
					Sensorthreshold.Distance_threshold = 1;
				}
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				Sensorthreshold.Distance_threshold--;
				if (Sensorthreshold.Distance_threshold < 1)
				{
					Sensorthreshold.Distance_threshold = 99;
				}				
			}
			break;
		default: break;		
	}
}

/**
  * @brief  对系统时间进行修改
  * @param  num 为当前用户需要更改的时分秒位置
  * @retval 无
  */
void TimeModification(uint8_t num)
{
	switch (num)
	{
		case 1:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				hour++;
				if (hour > 24)
				{
					hour = 0;
				}
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				hour --;
				if (hour > 24)
				{
					hour = 24;
				}				
			}		
			break;		

		case 2:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				minute++;
				if (minute > 60)
				{
					minute = 0;
				}
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				minute --;
				if (minute > 60)
				{
					minute = 60;
				}				
			}					
			break;
		case 3:
			if (KeyNum == KEY_3)
			{
				KeyNum = 0;
				second++;
				if (second > 60)
				{
					second = 0;
				}
			}
			else if (KeyNum == KEY_4)
			{
				KeyNum = 0;
				second --;
				if (second > 60)
				{
					second = 60;
				}				
			}		
			break;
		default: break;		
	}
}

/**
  * @brief  获取传感器的数据
  * @param  无
  * @retval 无
  */
void sensorScan(void)
{
		DHT11_Read_Data(&sensorData.humi, &sensorData.temp);
		HC_SR04_Deboanle(&sensorData.distance);
		LDR_LuxData(&sensorData.lux);
		HC_SR501_Input(&sensorData.people);		
}


int main(void)
{
	ADCX_Init();
	PWM_Init(100 - 1, 720 - 1);
	Timer2_Init(9,14398);
	Uart2_Init(9600);
	Uart1_Init(115200);
	IWDG_Init();	//初始化看门狗
	
	LDR_Init();
	OLED_Init();
	DHT11_Init();
	LED_Init();
	Key_Init();
	HC_SR501_Init();
	HC_SR04_Init();
	Buzzer_Init();
  MyRTC_Init();

	Sensorthreshold.Illumination_threshold = FLASH_R(FLASH_START_ADDR);	//从指定页的地址读FLASH
	Sensorthreshold.Distance_threshold = FLASH_R(FLASH_START_ADDR+2);	//从指定页的地址读FLASH
	
	GENERAL_TIM_Init();
	userInit();		//完成机智云初始赋值
	gizwitsInit();	//开辟一个环形缓冲区
//	GPIO_SetBits(Buzzer_PROT, Buzzer);
//	Delay_ms(1200);
	
	while (1)
	{
		
		IWDG_ReloadCounter(); //重新加载计数值 喂狗
		sensorScan();	//获取传感器数据

		switch (menu)
		{
			case display_page:

				MyRTC_ReadTime();	//调用此函数后,RTC硬件电路里时间值将刷新到全局数组
				OLED_Menu_SensorData();	//显示主页面传感器数据、系统模式等内容
				OLED_Menu();	//显示主页面的固定内容
				if (!systemModel)
				{
					LED_PWM_KEY();	//按键控制LED的PWM			
				}

				//切换系统模式
				if (KeyNum == KEY_1)
				{
					KeyNum = 0;
					systemModel = ~systemModel;
					if (systemModel)
					{
						currentDataPoint.valueModel = 1;
					}
					else
					{
						currentDataPoint.valueModel = 0;
					}
				}				
				
				//判断是否进入阈值设置界面
				if (KeyNum == KEY_Long1)
				{
					KeyNum = 0;
					OLED_Clear();	//清屏
					menu = settingsPage;	//跳转到阈值设置界面
				}
				break;
			case settingsPage:
				OLED_SetInterfacevoid();	//显示阈值设置界面的固定内容
				OLED_Option(SetSelection());	//实现阈值设置页面的选择功能
				ThresholdModification(SetSelection());	//实现阈值调节功能	
			
				//判断是否退出阈值设置界面
				if (KeyNum == KEY_2)
				{
					KeyNum = 0;
					OLED_Clear();	//清屏
					menu = display_page;	//跳转到主界面

					//存储修改的传感器阈值至flash内				
					FLASH_W(FLASH_START_ADDR, Sensorthreshold.Illumination_threshold, Sensorthreshold.Distance_threshold);
					currentDataPoint.valueIllumination_threshold = Sensorthreshold.Illumination_threshold;
					currentDataPoint.valueDistance_threshold = Sensorthreshold.Distance_threshold;
				}
				break;
			case timeSettingsPage:
				OLED_ThresholdTime();	//显示时间设置界面的内容
				OLED_Time_Option(SetSelection());	//实现间设置界面的选择功能
				TimeModification(SetSelection());	//实现时间调节功能	
				
				//判断是否退出时间设置界面
				if (KeyNum == KEY_2)
				{
					KeyNum = 0;
					//将更改的数据赋值回RTC数组中
					MyRTC_Time[3] = hour;	
					MyRTC_Time[4] = minute;
					MyRTC_Time[5] = second;		
					MyRTC_SetTime();	//调用此函数后,全局数组里时间值将刷新到RTC硬件电路	
		
					OLED_Clear();	//清屏
					menu = settingsPage;	//回到阈值设置界面
				}
				break;
		}	
		userHandle();	//更新机智云数据点变量存储的值
		gizwitsHandle((dataPoint_t *)&currentDataPoint);	//数据上传至机智云					
	}
}

七、项目资料包内容

资料获取:查看主页介绍"充哥单片机设计"

相关推荐
啃硬骨头5 小时前
MC33PT2000控制详解七:软件代码设计1-图形化设置
单片机·嵌入式硬件
充哥单片机设计7 小时前
【STM32项目开源】基于STM32的智能语音分类垃圾桶
stm32·单片机·嵌入式硬件
张人玉8 小时前
C# UDP 服务端与客户端2.0
单片机·udp·c#
清风66666612 小时前
基于51单片机宠物喂食系统设计
数据库·单片机·毕业设计·51单片机·课程设计·宠物
客官、打尖还是住店12 小时前
STM32简介
stm32·单片机·嵌入式硬件
GilgameshJSS13 小时前
STM32H743-ARM例程13-SDIO
c语言·arm开发·stm32·嵌入式硬件·学习
机器视觉知识推荐、就业指导13 小时前
STM32 外设驱动模块:DHT11温湿度传感器模块
stm32·单片机·嵌入式硬件
GilgameshJSS13 小时前
STM32H743-ARM例程8-EXTI外部中断
c语言·arm开发·stm32·单片机·嵌入式硬件·学习
lingzhilab13 小时前
零知IDE——STM32F407VET6与GP2Y1014AU的粉尘监测系统实现
stm32·单片机·嵌入式硬件