目录
一、设计背景和意义
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展示


六、软件程序设计
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 *)¤tDataPoint); //数据上传至机智云
}
}
七、项目资料包内容
