1. 项目概述:STM32智能窗帘晾衣架系统
这个基于STM32的智能窗帘晾衣架系统,是我在帮学弟修改毕业设计时偶然翻到的宝藏方案。它最大的特点就是"无实物也能玩"——所有资料完整到可以直接套用,特别适合手头没有硬件但又想快速搭建项目的朋友。系统通过光敏传感器感知环境光照,用雨滴模块检测天气状况,配合定时功能实现窗帘和晾衣架的智能控制。
核心功能模块包括:
- 环境感知:光敏电阻+雨滴传感器
- 人机交互:三按键控制+OLED显示
- 执行机构:继电器控制电机(需外接驱动)
- 智能逻辑:自动/定时/手动三种模式
关键提示:虽然项目资料完整,但实际搭建时仍需注意GPIO驱动能力不足的问题,必须使用继电器或电机驱动模块,直接连接电机可能损坏开发板。
2. 硬件设计与元件选型
2.1 核心控制器:STM32最小系统
推荐使用STM32F103C8T6最小系统板,性价比高且资源充足:
- 48KB SRAM + 64KB Flash
- 3个USART、2个SPI、2个I2C
- 12位ADC(用于光敏采样)
- 16个外部中断(实际只用GPIO功能)
我选择这款芯片的原因是:
- 价格亲民(约15-20元)
- 社区资源丰富
- HAL库支持完善
- 引脚数量适中(48脚LQFP封装)
2.2 传感器模块选型与电路设计
光敏传感器模块
推荐使用GL5528光敏电阻模块:
- 工作电压:3.3V-5V
- 输出形式:模拟量(接ADC)
- 检测范围:10-20 Lux至黑暗环境
- 电路连接:PA0→模块OUT
实际使用中发现:
- 晴天ADC值约3000-4095
- 阴天约800-2000
- 夜晚通常低于500
调试技巧:用手机闪光灯直射传感器可快速测试ADC值变化,避免等待自然光变化。
雨滴检测模块
常用HW-038雨滴传感器:
- 工作电压:5V(需电平转换)
- 输出形式:数字量(下雨时低电平)
- 灵敏度可调电位器
- 电路连接:PA1→模块DO
实测注意事项:
- 必须启用GPIO上拉(模块输出开漏)
- 建议软件消抖(10ms延时滤波)
- 避免水滴直接溅到感应区
2.3 显示与交互模块
OLED显示屏
SSD1306 128x64 I2C屏最合适:
- 分辨率:128x64
- 接口:I2C(节省IO)
- 驱动芯片:SSD1306
- 电路连接:PB6→SCL,PB7→SDA
显示优化建议:
- 使用sprintf格式化字符串
- 刷新间隔100-200ms
- 重要信息反色显示
- 添加简单动画提升体验
按键电路设计
采用3按键方案:
- 模式切换键:PA2(短按切换模式)
- 时间加键:PA3(短按+1h)
- 时间减键:PA4(短按-1h)
按键扫描算法要点:
- 10ms消抖延时
- 状态机实现长短按识别
- 松手检测避免重复触发
3. 软件架构与核心代码实现
3.1 系统初始化流程
完整的硬件初始化顺序:
c复制void System_Init(void)
{
HAL_Init();
SystemClock_Config(); // 由CubeMX生成
MX_GPIO_Init();
MX_ADC1_Init();
MX_I2C1_Init();
OLED_Init();
Rain_Init();
Timer_Init(); // 用于定时功能
}
关键细节:
- ADC需校准(上电后执行HAL_ADCEx_Calibration_Start)
- I2C要配置合适时钟(400kHz)
- 系统时钟建议设置为72MHz
3.2 传感器数据采集实现
光照采集优化代码
c复制#define LIGHT_SAMPLE_NUM 10 // 采样次数
#define LIGHT_THRESHOLD_LOW 1000 // 开窗帘阈值
#define LIGHT_THRESHOLD_HIGH 3000 // 关窗帘阈值
uint16_t Get_AverageLight(void)
{
uint32_t sum = 0;
for(uint8_t i=0; i<LIGHT_SAMPLE_NUM; i++){
sum += Get_Light(); // 基础获取函数
HAL_Delay(5);
}
return sum/LIGHT_SAMPLE_NUM;
}
uint8_t Light_Judgment(void)
{
uint16_t light = Get_AverageLight();
if(light < LIGHT_THRESHOLD_LOW) return 1; // 需要开窗帘
else if(light > LIGHT_THRESHOLD_HIGH) return 2; // 需要关窗帘
else return 0; // 保持现状
}
改进点:
- 增加均值滤波
- 分离判断逻辑
- 可调阈值参数
雨滴检测增强版
c复制#define RAIN_SAMPLE_INTERVAL 50 // 采样间隔ms
#define RAIN_SAMPLE_TIMES 5 // 连续检测次数
uint8_t Get_StableRain(void)
{
uint8_t count = 0;
for(uint8_t i=0; i<RAIN_SAMPLE_TIMES; i++){
if(Get_Rain()) count++;
HAL_Delay(RAIN_SAMPLE_INTERVAL);
}
return (count >= 3)? 1 : 0; // 5次中3次为真即判定下雨
}
3.3 主控制逻辑实现
状态机设计
系统有三种工作模式:
- 自动模式(光照+雨滴控制)
- 定时模式(倒计时控制)
- 手动模式(按键直接控制)
状态转换图:
code复制[上电] --> 自动模式
↑↓短按模式键
定时模式 ←→ 手动模式
核心控制代码
c复制void Control_Logic(void)
{
static uint32_t auto_counter = 0;
static uint32_t timer_counter = 0;
// 模式切换处理
if(key_value == KEY_MODE){
current_mode = (current_mode + 1) % 3;
OLED_Clear();
}
// 各模式专属逻辑
switch(current_mode){
case AUTO_MODE:
if(++auto_counter >= 10){ // 约1秒检测一次
auto_counter = 0;
uint8_t light_state = Light_Judgment();
uint8_t rain_state = Get_StableRain();
if(light_state == 1) Curtain_Open();
else if(light_state == 2) Curtain_Close();
if(rain_state) ClothesRail_Retract();
else ClothesRail_Extend();
}
break;
case TIMER_MODE:
if(++timer_counter >= 3600){ // 1小时计数
timer_counter = 0;
if(--set_time == 0){
Curtain_Close();
ClothesRail_Retract();
}
}
break;
case MANUAL_MODE:
if(key_value == KEY_UP) Curtain_Open();
else if(key_value == KEY_DOWN) Curtain_Close();
break;
}
}
4. 常见问题与调试技巧
4.1 传感器读数异常排查
光敏传感器值不稳定
可能原因及解决方案:
- 电源噪声 → 增加0.1uF去耦电容
- 环境光波动 → 软件均值滤波
- 接触不良 → 检查杜邦线连接
雨滴模块误触发
典型现象:无雨时随机报下雨
解决方法:
- 调整模块上电位器
- 检查感应板是否清洁
- 增加硬件滤波(RC电路)
4.2 OLED显示问题处理
屏幕无显示
检查步骤:
- 确认I2C地址(通常0x78或0x7A)
- 测量SCL/SDA波形
- 检查初始化序列是否正确
显示乱码
可能原因:
- 字体文件未正确移植
- 刷新前未清屏
- 缓冲区越界
4.3 电机控制注意事项
继电器选型要点
- 线圈电压匹配(常用5V)
- 触点容量 > 电机电流
- 建议加续流二极管
典型驱动电路
code复制STM32 GPIO → 1K电阻 → NPN三极管 → 继电器线圈
↑
反向并联1N4148
重要经验:调试时先用LED模拟电机,确认逻辑正确后再接真实负载,避免损坏设备。
5. 项目优化与扩展方向
5.1 功能增强建议
- 添加WiFi模块(ESP8266)实现手机控制
- 增加温湿度传感器(DHT22)优化控制策略
- 加入语音识别模块(LD3320)实现声控
- 开发上位机配置软件
5.2 代码结构优化
使用RTOS改造
将系统拆分为多个任务:
- 传感器采集任务
- 人机交互任务
- 网络通信任务
- 控制执行任务
配置参数存储
添加EEPROM(24C02)存储:
- 光照阈值
- 定时时间
- 工作模式
5.3 低成本替代方案
- 改用STM32F030系列降低成本
- 用光敏三极管替代模块
- 使用1602LCD替代OLED
- 自制雨滴传感器(覆铜板+比较器)
这个项目最让我满意的是它的可扩展性——你可以只实现基础功能快速完成课设,也可以不断添加新模块做成真正的智能家居设备。我后来在这个基础上增加了蓝牙控制和太阳能供电,现在已经成为我工作室的实用装置了。
