1. 项目概述:当窗帘遇上STM32
去年夏天我租了个朝南的房子,每天清晨五点半阳光准时把我晒醒。试过各种遮光布、定时器都不理想,直到用STM32做了这个光控窗帘系统——现在我的卧室永远保持最舒适的亮度。这个系统通过光敏电阻感知环境光照,STM32处理数据后驱动电机调整窗帘开合度,LCD1602实时显示状态,整套成本不到200元。
智能窗帘在智能家居领域属于高频需求,但市售成品动辄上千元。自己动手不仅能完全定制功能,还能深入理解传感器采集、电机控制等嵌入式开发核心技能。这个项目适合:
- 需要实际STM32练手项目的电子爱好者
- 想给家里添置智能窗帘但预算有限的DIYer
- 物联网/自动化相关专业的学生
2. 硬件设计解析
2.1 核心器件选型对比
我在器件选型时对比了三种方案,最终选择如下配置:
| 器件类型 | 候选方案 | 最终选择 | 选择理由 |
|---|---|---|---|
| 主控芯片 | STM32F103C8T6 vs 51单片机 | STM32F103C8T6 | 32位ARM内核性能更强,自带PWM输出和ADC,价格仅比51单片机贵10元左右 |
| 光敏传感器 | 光敏电阻 vs BH1750 | GL5528光敏电阻 | 成本仅0.5元,线性度满足需求,无需I2C通信简化程序 |
| 显示模块 | LCD1602 vs OLED | LCD1602 | 阳光直射下可视性更好,经典16x2字符显示足够展示当前光照值和窗帘状态 |
| 电机驱动 | L298N vs TB6612FNG | TB6612FNG | 效率更高(90% vs 70%),发热量小,支持1.2A持续电流正好驱动我的42步进电机 |
关键提示:TB6612的VM电压要高于电机额定电压1-2V,我用的12V电机就接了14V电源
2.2 电路设计要点
光敏电阻分压电路是采集精度的关键。我的设计经验:
c复制// 典型接法:光敏电阻与10kΩ固定电阻串联
// ADC采样点位于两者之间
Vout = Vcc * (R_fixed / (R_light + R_fixed))
实测发现的问题及解决方案:
- 环境光突变时ADC值抖动
- 在PCB上并联104电容滤波
- 软件端采用滑动平均算法(我取10次平均值)
- 电机干扰导致ADC异常
- 光敏电阻走线远离电机驱动线路
- 在STM32的ADC引脚加磁珠
电机驱动部分要注意:
- TB6612的PWMA/PWMB需接STM32的定时器PWM输出
- STBY引脚必须接高电平
- 散热片建议用3M双面胶固定,实测连续工作温度约50℃
3. 软件架构实现
3.1 光照采集与处理
我的ADC配置采用DMA方式,避免频繁中断影响电机控制:
c复制// CubeMX配置
hadc1.Instance = ADC1;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
光照等级划分算法经过三次迭代:
- 最初简单分三档:暗/正常/亮 → 窗帘动作太频繁
- 改为五档+迟滞比较 → 改善明显但仍有抖动
- 最终方案:动态阈值算法
c复制// 根据昼夜自动调整触发阈值 if (hour > 20 || hour < 6) { // 夜间模式 threshold_low = 800; // ADC值 threshold_high = 1000; } else { // 日间模式 threshold_low = 500; threshold_high = 800; }
3.2 电机控制逻辑
步进电机驱动采用梯形加减速算法,比传统延时方式更平滑:
c复制void Motor_Run(int steps) {
// 加速度计算
for(int i=0; i<accel_steps; i++) {
delay = max_delay - (max_delay-min_delay)*i/accel_steps;
HAL_GPIO_WritePin(STEP_GPIO, STEP_PIN, GPIO_PIN_SET);
delay_us(delay);
HAL_GPIO_WritePin(STEP_GPIO, STEP_PIN, GPIO_PIN_RESET);
delay_us(delay);
}
// 匀速段...
// 减速段...
}
实测参数建议:
- 42步进电机:max_delay=1000us, min_delay=200us
- 加速度步数accel_steps取总步数的1/3
4. 系统优化与问题排查
4.1 常见问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| LCD显示乱码 | 初始化时序不对 | 检查RS/RW/EN时序,加2ms延时 |
| 电机只振动不转 | 缺相或电流不足 | 测量驱动芯片输出,调整VREF电压 |
| 光照值跳动剧烈 | 电源干扰或采样电阻不当 | 加滤波电容,更换10kΩ为4.7kΩ分压电阻 |
| 窗帘到位后电机不停 | 限位开关接触不良 | 改用光电开关,或软件增加堵转检测 |
4.2 功耗优化技巧
我的系统从最初350mA降到现在待机仅15mA:
- 关闭未用外设时钟
c复制
__HAL_RCC_ADC1_CLK_DISABLE(); __HAL_RCC_TIM2_CLK_DISABLE(); - 采用停机模式+光敏中断唤醒
c复制
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); - LCD背光PWM调光(夜间自动降低亮度)
5. 扩展功能实现
5.1 手机蓝牙控制
加装HC-05模块后,通过串口接收手机指令:
c复制// 串口中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if(rx_data[0] == 'O') { // Open指令
Motor_Run(OPEN_STEPS);
}
// 其他指令处理...
}
推荐使用Serial Bluetooth Terminal APP,可自定义按钮发送指令
5.2 环境温湿度监测
增加DHT11传感器后的代码调整:
c复制// 需要重写微秒级延时
void DHT11_Delay_us(uint16_t us) {
__HAL_TIM_SET_COUNTER(&htim3, 0);
while(__HAL_TIM_GET_COUNTER(&htim3) < us);
}
注意:DHT11数据引脚要加4.7kΩ上拉电阻
6. 项目进阶建议
- 改用ESP8266实现远程控制(需处理掉线重连机制)
- 增加太阳能供电(6V/2W板子+TP4056充电管理)
- 开发图形化界面(用TFT屏替代LCD1602)
- 加入机器学习算法预测用户习惯(需扩展SRAM)
这个项目最让我惊喜的是TB6612的驱动效果——相比之前用过的L298N,电机运行安静得多,特别适合卧室环境。后来我又给父母的卧室也做了一套,他们把触发光照值调高了20%,因为老年人更喜欢明亮的环境。这种能根据实际需求灵活调整的DIY乐趣,是成品智能窗帘无法比拟的。
