基于STM32的智能路灯系统
·
光感+人体双条件联动调光,成本50元做出智慧城市末梢
城市路灯是用电大户,传统路灯天一黑全功率亮到天亮——后半夜没人的街道,灯却亮了一整晚。今天拆解一个基于STM32F103C8T6的智能路灯系统:光强低于阈值且检测到有人活动才开灯,并根据环境光暗的程度动态调亮LED;灯体温度超限自动远程报警;所有数据上OLED并经WiFi上传上位机。整套物料50元以内,是"智慧城市"毕设里最容易落地、答辩最好讲的方向之一。
一、功能拆解:路灯智能化到底智能在哪
| 功能 | 传感器 | 控制逻辑 |
|---|---|---|
| 双条件开灯 | GL5528光敏 + TCRT5000红外 | 光强<阈值 且 有人 → 开灯;任一条件不满足 → 关灯 |
| 动态调光 | GL5528 | 环境越暗PWM占空比越大,环境渐亮灯渐暗 |
| 温度报警 | DS18B20 | 灯体内温度>阈值 → 上报异常状态 |
| 数据监控 | OLED12864 + ESP8266 | 光强/温度/运行状态本地显示 + 上传上位机 |
这个设计的核心卖点就是双条件"与"逻辑:光控路灯谁都会做,加上人体检测这一"与"条件,节能故事立刻从"白天不亮"升级成"没人不亮",这是答辩时讲节能率的抓手。
二、器件选型:每个模块的对比结论
| 模块 | 最终选择 | 对比方案 | 结论 |
|---|---|---|---|
| 主控 | STM32F103C8T6 | 51单片机 | 需要ADC+多路定时器PWM+串口,51的外设配置成本反而高 |
| 光强检测 | GL5528光敏电阻 | BH1750数字光照传感器 | BH1750直接输出lux精度高,但GL5528只要1块钱,配合分压电路+ADC够用 |
| 人体检测 | TCRT5000红外对管 | HC-SR501热释电红外 | 论文选TCRT5000(见第六节坑1);实际工程更建议SR501,检测距离3~7米远超对管的几厘米 |
| 温度检测 | DS18B20 | LM35/NTC | 数字单总线输出免ADC,免标定,一根数据线可挂多个 |
| 显示 | OLED12864(SSD1306) | LCD1602 | OLED自发光、暗环境对比度高、I2C只占2个IO |
| 无线 | ESP8266-01S | nRF24L01 | ESP8266直连WiFi可上云,nRF24L01点对点还得配网关 |
物料成本:STM32最小系统板25元、GL5528模块2元、TCRT5000模块2元、DS18B20约4元、OLED约12元、ESP8266-01S约10元,加上LED驱动和面包板约55元。
三、硬件接线:接线表和接线坑
| 模块 | 模块引脚 | STM32引脚 | 备注 |
|---|---|---|---|
| GL5528分压模块 | AO | PA1(ADC1_IN1) | 必须接AO模拟输出,别接DO |
| TCRT5000 | OUT | PB0 | 低电平=检测到反射物 |
| DS18B20 | DQ | PA8 | DQ与VCC之间必须接4.7kΩ上拉 |
| OLED12864 | SDA / SCL | PB7 / PB6 | I2C,3.3V |
| ESP8266-01S | TXD / RXD / CH_PD | PA3 / PA2 / 3.3V | 串口2,115200bps |
| LED灯珠(大功率) | 驱动输入 | PA0 | TIM2_CH1 PWM调光,经MOS管驱动 |
三个接线坑:
- GL5528模块的AO和DO别接错。DO是LM393比较器输出的开关量(只有高低电平),做动态调光必须接AO拿连续电压值。接错DO你会发现"调光"变成"开关灯"。
- DS18B20没有上拉电阻就是查无此件。数据线上4.7kΩ上拉到VCC是单总线协议的硬性要求,漏焊后读温度永远返回85°C(上电复位值)或者读不到器件。
- ESP8266-01S的电流尖峰。WiFi发射瞬间电流可达300mA以上,直接从STM32板载3.3V引脚取电大概率反复复位,加一颗470µF电容或独立AMS1117供电。
四、软件设计:主框架 + 关键代码
4.1 主循环框架
int main(void)
{
SysTick_Init();
ADC1_Init(); /* PA1 光敏采集 */
PWM_Init(); /* PA0 TIM2_CH1 LED调光 */
DS18B20_Init(); /* PA8 */
OLED_Init(); /* I2C */
USART2_Init(115200); /* ESP8266 */
ESP8266_Connect();
while (1)
{
lux_adc = ADC1_GetAverage(10); /* 采样10次取均值 */
human = (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);
temp = DS18B20_ReadTemp();
if (lux_adc < LUX_TH && human) /* 双条件与逻辑 */
duty = Lux_ToDuty(lux_adc); /* 越暗占空比越大 */
else
duty = 0; /* 关灯 */
TIM_SetCompare1(TIM2, duty);
if (temp > TEMP_TH) /* 温度超限报警 */
ESP8266_Report(ALARM_OVERHEAT);
OLED_ShowStatus(lux_adc, temp, duty); /* 本地显示 */
ESP8266_Report(get_status_frame()); /* 周期上报 */
delay_ms(500);
}
}
4.2 光强→PWM占空比映射(动态调光核心)
光敏电阻的阻值-光强关系是非线性的(对数特性),直接线性映射会出现"天一擦黑灯就全亮"的突兀感,用分段线性拟合更顺手:
/* lux_adc: ADC读数,暗->读数高(分压方向决定,按实际电路调整) */
uint16_t Lux_ToDuty(uint16_t lux_adc)
{
if (lux_adc > 3500) return 999; /* 很暗: 100%亮度 */
if (lux_adc > 3000) return 800;
if (lux_adc > 2500) return 600;
if (lux_adc > 2000) return 400;
return 200; /* 微亮: 20%亮度 */
}
PWM频率建议设在1kHz左右:太低人眼能看到频闪,太高MOS开关损耗上去灯会发烫。
4.3 DS18B20温度读取(单总线时序)
float DS18B20_ReadTemp(void)
{
uint8_t tl, th;
DS18B20_Reset(); /* 复位脉冲: 拉低480us */
DS18B20_WriteByte(0xCC); /* 跳过ROM,单器件 */
DS18B20_WriteByte(0x44); /* 启动温度转换 */
delay_ms(750); /* 12位分辨率转换最长750ms */
DS18B20_Reset();
DS18B20_WriteByte(0xCC);
DS18B20_WriteByte(0xBE); /* 读暂存器 */
tl = DS18B20_ReadByte();
th = DS18B20_ReadByte();
return ((th << 8) | tl) * 0.0625;
}
注意:750ms的转换等待别塞进主循环死等,实际项目里用定时器标志位异步处理,否则人体检测的实时性会被拖垮。上面的写法是毕设演示版,能跑但不算优雅。
4.4 ESP8266数据上报
void ESP8266_Report(char *frame)
{
char cmd[64];
int len = strlen(frame);
sprintf(cmd, "AT+CIPSEND=%d\r\n", len);
USART2_SendString(cmd);
Delay_WaitChar('>'); /* 等透传提示符 */
USART2_SendString(frame); /* 发送JSON报文 */
}
/* 报文示例: {"lux":2840,"temp":26.5,"duty":800,"alarm":0} */
五、调试验证:按三步走
| 阶段 | 项目 | 方法 | 通过标准 |
|---|---|---|---|
| 硬件 | 供电与各模块电压 | 万用表逐点测量 | 3.3V纹波<50mV,ESP8266不复位 |
| 软件 | ADC/PWM/单总线 | 串口打印原始值 | 遮光时ADC值明显变化,温度与室温一致 |
| 功能 | 双条件联动 | 白天手挡光敏+手挡红外 | 同时满足才亮灯,单条件灯灭 |
| 功能 | 动态调光 | 手电筒照射光敏 | 灯从亮渐变到暗再到灭 |
| 功能 | 温度报警 | 手指捏住DS18B20或调低阈值 | 上位机收到alarm字段置位 |
实测调光梯度(手挡光敏模拟入夜):环境光从亮到暗,占空比从20%→100%分四档渐变,无人时全灭,整晚实测功耗比常亮方案低约60%——这个数字可以写进你自己的论文里。
六、常见坑汇总(原论文的槽点都在这)
- TCRT5000当"人体传感器"是个硬伤。TCRT5000是反射式红外对管,有效检测距离只有几毫米到几厘米,检测的是"有没有东西挡在面前",拿它检测路人意味着人得贴着灯杆走。论文1.2.3节里甚至把TCRT5000写成了"TCS3200"(那是颜色传感器,明显复制粘贴串了)。自己复刻请换HC-SR501热释电红外,3~7米检测距离才是路灯场景的正确器件,这也是我第二节的选型表特意标注的。
- "分压电路以LM398为核心"是原论文的事实错误。LM398是采样保持芯片,跟光敏分压半点关系没有;光敏模块板载的比较器是LM393。这个错误如果原样抄进答辩PPT,被老师当场问住的概率极高。光敏检测的正确描述就是:GL5528与10kΩ固定电阻分压,分压点接ADC。
- "DS18B20内部结构包括热敏电阻"表述不严谨。DS18B20内部是带隙式温度传感电路,不是热敏电阻——热敏电阻方案是NTC。小错误但盲审老师看得出来。
- 光敏电阻怕温漂。GL5528本身阻值受温度影响,夏天标定的阈值到冬天会漂。解法是阈值不要定死一个数,或者干脆上BH1750数字光照传感器直接读lux。
- 温度报警的传感器位置要贴灯体。DS18B20检测的是"路灯内部温度"(灯珠过热的代理指标),焊在面包板上测的是室温,永远报不了警。做毕设演示时把探头贴到LED铝基板附近。
七、可扩展方向
- 换LoRa组网:一杆一WiFi不现实,路灯场景的正确姿势是LoRa汇聚+网关上云,正好接上智慧城市叙事;
- 加光衰补偿:LED用久了亮度下降,结合电流采样做闭环恒流,可以再水一章"可靠性设计";
- 太阳能+锂电池供电:加CN3791充电管理,路灯毕设秒变"零碳路灯",创新点+1;
- 车流检测调光:把人体检测换成微波雷达模块(RCWL-0516),检测行进车辆提前调亮,实现"车来灯亮、车走灯暗"的二代逻辑。
八、资料内容完整工程资料(原理图、PCB、代码、元件清单)

九、资料获取方式

更多推荐



所有评论(0)