1. 项目概述
作为一名嵌入式开发工程师,我最近完成了一个基于STM32的智能台灯项目。这个项目不仅实现了传统台灯的基本照明功能,还加入了人体感应、环境光自适应、无线控制等智能化特性。在实际开发过程中,我发现市面上很多智能台灯要么功能单一,要么价格昂贵,于是决定自己动手打造一款高性价比的智能台灯系统。
这个系统以STM32F103C8T6作为主控芯片,配合多种传感器和执行器,实现了以下核心功能:
- 自动亮度调节:根据环境光照强度自动调整LED亮度
- 人体感应开关:检测用户存在状态实现自动开关灯
- 多模式控制:支持手动触摸、手机APP和语音控制
- 色温调节:可切换冷暖光模式
- 能耗统计:记录用电情况并生成报告
2. 硬件设计详解
2.1 主控芯片选型
选择STM32F103C8T6作为主控主要基于以下考虑:
- 性价比:零售价约10-15元,批量采购可低至8元
- 性能:72MHz主频的Cortex-M3内核,完全满足控制需求
- 外设资源:
- 3个USART(用于WiFi、蓝牙模块通信)
- 2个SPI接口(连接显示屏等外设)
- 2个I2C接口(连接传感器)
- 多达15个PWM通道(LED调光控制)
注意:STM32F103系列有多个型号,C8T6的64KB Flash和20KB RAM对于本项目完全够用,不需要选择更高配置的型号。
2.2 传感器模块配置
2.2.1 人体红外传感器
选用HC-SR501模块,关键参数设置:
- 检测距离:0.3-7米可调(建议设置为2米)
- 延时时间:5秒-200秒可调(建议设置为30秒)
- 工作电压:4.5-20V(直接使用5V供电)
接线方式:
c复制VCC -> 5V
OUT -> PA0 (外部中断引脚)
GND -> GND
2.2.2 光照传感器
对比了光敏电阻和BH1750数字光照传感器后,选择了BH1750,优势在于:
- 直接输出lux值,无需AD转换和计算
- 测量范围1-65535 lux,精度±20%
- I2C接口,仅需2个IO口
典型应用电路:
c复制SCL -> PB6 (I2C1_SCL)
SDA -> PB7 (I2C1_SDA)
VCC -> 3.3V
GND -> GND
2.3 LED驱动电路设计
采用PWM调光方案,关键设计要点:
- LED选型:使用2835封装的白光LED,单颗功率0.5W
- 驱动电路:使用MOSFET(如AO3400)作为开关器件
- 保护电路:
- 串联电阻限流
- 并联稳压二极管防反压
- PWM频率:选择1kHz避免可见闪烁
典型电路参数计算示例:
假设使用12V电源,LED正向电压3V,期望电流100mA:
限流电阻 R = (12V - 3V) / 0.1A = 90Ω(取标准值100Ω)
电阻功率 P = I²R = 0.1² × 100 = 1W(选用2W电阻)
3. 软件系统实现
3.1 开发环境搭建
使用STM32CubeIDE作为主要开发工具,配置步骤:
- 安装STM32CubeMX和STM32CubeIDE
- 新建工程,选择STM32F103C8T6型号
- 配置时钟树:外部8MHz晶振,PLL倍频到72MHz
- 外设初始化:
- GPIO:设置LED、按键等引脚
- TIM:配置PWM输出
- USART:配置串口通信
- I2C:配置传感器接口
3.2 核心算法实现
3.2.1 自动调光算法
c复制#define MIN_LUX 50 // 最小照度阈值
#define MAX_LUX 500 // 最大照度阈值
#define MIN_PWM 100 // 最小PWM值(约10%亮度)
#define MAX_PWM 1000 // 最大PWM值(100%亮度)
uint16_t auto_adjust_brightness(uint16_t ambient_lux)
{
uint16_t pwm_value;
if(ambient_lux <= MIN_LUX) {
pwm_value = MAX_PWM;
}
else if(ambient_lux >= MAX_LUX) {
pwm_value = MIN_PWM;
}
else {
// 线性映射
pwm_value = MAX_PWM - (ambient_lux - MIN_LUX) * (MAX_PWM - MIN_PWM) / (MAX_LUX - MIN_LUX);
}
return pwm_value;
}
3.2.2 人体感应状态机
设计了一个三状态的状态机:
- OFF状态:灯关闭,等待人体信号
- ON状态:灯亮起,开始计时
- STANDBY状态:检测到人体离开,等待超时
状态转换逻辑:
c复制typedef enum {
LAMP_OFF,
LAMP_ON,
LAMP_STANDBY
} LampState;
void update_lamp_state(void)
{
static uint32_t timer = 0;
switch(current_state) {
case LAMP_OFF:
if(human_detected) {
current_state = LAMP_ON;
turn_on_light();
}
break;
case LAMP_ON:
if(!human_detected) {
current_state = LAMP_STANDBY;
timer = HAL_GetTick();
}
break;
case LAMP_STANDBY:
if(human_detected) {
current_state = LAMP_ON;
}
else if(HAL_GetTick() - timer > STANDBY_TIMEOUT) {
current_state = LAMP_OFF;
turn_off_light();
}
break;
}
}
3.3 无线通信实现
3.3.1 WiFi模块配置
使用ESP8266-01S模块,AT指令配置流程:
- 初始化串口:115200波特率
- 发送测试指令:AT\r\n
- 设置WiFi模式:AT+CWMODE=3\r\n(STA+AP模式)
- 连接路由器:AT+CWJAP="SSID","password"\r\n
- 启动TCP服务器:AT+CIPSERVER=1,8080\r\n
3.3.2 通信协议设计
自定义简单协议格式:
code复制[HEADER][LEN][CMD][DATA][CHECKSUM]
- HEADER:0xAA 0x55
- LEN:数据长度
- CMD:命令字(如0x01开关,0x02调光)
- DATA:参数数据
- CHECKSUM:异或校验
示例手机APP控制命令:
code复制AA 55 03 01 01 00 // 开灯
AA 55 03 01 00 00 // 关灯
AA 55 04 02 80 00 // 设置亮度50%
4. 系统优化与调试
4.1 功耗优化技巧
- 低功耗模式配置:
- 无人时进入Stop模式,仅保留RTC和外部中断
- 唤醒源:人体感应中断、定时器中断
- 外设电源管理:
- 不使用时关闭传感器电源
- WiFi模块空闲时进入睡眠模式
- 实测结果:
- 工作电流:约120mA(全亮度)
- 待机电流:<5mA
- 深度睡眠电流:<1mA
4.2 常见问题解决
4.2.1 PWM调光闪烁问题
症状:LED亮度变化时出现可见闪烁
解决方法:
- 提高PWM频率至3-5kHz
- 在PWM输出端增加RC滤波(如100Ω+0.1μF)
- 软件上采用渐变算法,避免亮度突变
4.2.2 WiFi连接不稳定
症状:频繁断开连接或响应超时
排查步骤:
- 检查天线位置,避免金属遮挡
- 降低串口波特率至9600测试
- 添加看门狗定时器,超时后重启模块
- 增加AT指令重试机制
4.3 生产测试方案
设计了一套自动化测试流程:
- 电源测试:检查3.3V、5V电压是否正常
- 传感器测试:
- 遮挡光敏电阻,检查亮度变化
- 触发人体感应,检查开关响应
- 无线测试:
- 发送控制命令,验证响应
- 测试最大通信距离
- 老化测试:
- 连续工作24小时,监测稳定性
5. 进阶功能扩展
5.1 语音控制实现
使用LD3320语音识别模块的集成步骤:
- 硬件连接:
- SPI接口连接STM32
- MIC接入模块音频输入
- 固件烧录:
- 下载官方语音识别固件
- 通过串口工具烧录
- 关键词训练:
- 添加"开灯"、"关灯"、"亮一点"等指令
- 设置对应的识别码
- 软件对接:
- 解析模块输出的识别码
- 执行相应控制操作
5.2 智能家居联动
通过MQTT协议接入Home Assistant平台:
- ESP8266配置:
- 编译AT固件支持MQTT
- 设置Broker地址和凭证
- 主题定义:
- 订阅:home/lamp/cmd
- 发布:home/lamp/status
- 自动化场景示例:
- 日落时自动开灯
- 检测到房间无人时自动关灯
- 与其他设备联动(如窗帘、空调)
5.3 固件远程升级(OTA)
设计安全的OTA更新机制:
- 双Bank方案:
- Bank1运行当前固件
- Bank2存储新固件
- 更新流程:
- 下载固件到外部Flash
- 校验签名和CRC
- 擦除Bank2并写入新固件
- 重启后跳转到Bank2
- 安全措施:
- AES加密传输
- 数字签名验证
- 回滚机制
6. 项目总结与心得
在实际开发过程中,我总结了以下几点经验:
-
传感器选型要注重实际环境适应性。最初使用的光敏电阻受温度影响大,后来改用数字传感器稳定性明显提升。
-
PWM调光频率选择很关键。测试发现1-3kHz既能避免闪烁,又不会导致MOS管过热。
-
低功耗设计需要全面考虑。除了MCU的睡眠模式,外设的电源管理同样重要,比如WiFi模块在空闲时的电流可能比MCU还大。
-
产品化思维很重要。从原型到产品需要考虑生产工艺、测试方案、用户体验等各方面因素。
这个项目从构思到完成历时两个月,期间遇到了不少挑战,但最终的成果令人满意。智能台灯系统不仅实现了预期的功能,在稳定性和用户体验方面也达到了商业级水准。