【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项目功能详解
- 传感器检测:检测光照强度、监测人体红外
- 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
- 执行机构:系统可以控制路灯的调光。
- 接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台。
- App远程监控:通过App远程监控全部传感器数据;
- 阈值数据设定:系统通过按键设定阈值,也可以通过手机App远程设定。
- 模式切换:可以通过按键或者手机App实现自动/手动模式的切换。
- 故障模拟:设定了特定按键来模拟实现故障的检测,按键按下后,系统报故障,同时灯灭
- 手动模式:通过手机App或小程序控制开关
- 自动模式:根据环境的光亮自动调节LED灯的亮度,两个光敏分别调节
- 定时开关:可以设定时间实现自动开关。
3.2元器件清单
- 主控STM32F103C8T6最小系统板
- 0.96 OLED显示屏幕
- ESP8266联网WIFI
- 人体红外热释电传感器
- 红外对管
- DS1302时钟模块
- 光敏电阻2
四、主框图与软件流程图
主框图
流程图
五、硬件PCB展示
六、软件程序设计
#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); //从指定页的地址读FLASHSensorthreshold.Distance_threshold = FLASH_R(FLASH_START_ADDR+2); //从指定页的地址读FLASHGENERAL_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 *)¤tDataPoint); //数据上传至机智云 }
}