1. 项目概述:一个零硬件成本的STM32智能家居方案
去年帮学弟改毕设时偶然翻到这个智能窗帘晾衣架项目,发现它完美符合"无实物演示"的需求——全套代码、电路图、报告模板一应俱全,甚至连仿真文件都准备好了。这种项目对于手头没有硬件设备但又需要快速搭建演示系统的学生党来说简直是救命稻草。
整套系统以STM32F103C8T6为核心(也就是最便宜的蓝色小开发板),通过光敏电阻检测环境亮度,雨滴传感器监测天气变化,配合定时功能和OLED状态显示,实现了窗帘和晾衣架的智能控制。最妙的是所有传感器模块都能在Proteus里找到对应模型,完全不需要真实硬件就能跑通整个流程。
2. 硬件设计精要
2.1 核心器件选型解析
选择STM32F103C8T6主要考虑三点:首先是价格(某宝20元包邮),其次是丰富的片上资源(3个ADC、多个定时器、I2C接口等),最重要的是其完善的HAL库支持。光敏传感器推荐使用GL5528光敏电阻模块,它已经内置分压电路,直接输出模拟信号。雨滴检测则选用常见的DO输出型模块,这类模块通常采用比较器电路,灵敏度可通过电位器调节。
关键提示:购买传感器时务必确认工作电压范围,3.3V系统要选择兼容3.3V的模块,避免信号电平不匹配
2.2 电路设计避坑指南
原理图设计有三大易错点需要特别注意:
- ADC输入引脚必须配置为模拟输入模式,很多新手会误设成浮空输入
- 雨滴传感器的数字输出端建议加上10kΩ上拉电阻,防止干扰导致误触发
- 电机驱动部分必须使用隔离方案,推荐采用光耦+继电器组合,成本约8元
以下是典型连接方式:
plaintext复制STM32F103C8T6 外围设备
PA0(ADC1_IN0) → 光敏模块OUT
PA1 → 雨滴模块DOUT
PB6(I2C1_SCL) → OLED SCL
PB7(I2C1_SDA) → OLED SDA
PA5 → 继电器控制线
3. 软件实现详解
3.1 传感器数据采集优化
光照采集的核心在于ADC配置和数据处理。实际测试发现,直接读取ADC值会有约±50的波动,建议采用滑动平均滤波:
c复制#define SAMPLE_SIZE 10
uint16_t light_samples[SAMPLE_SIZE];
uint8_t sample_index = 0;
uint16_t Get_FilteredLight(void) {
light_samples[sample_index++] = Get_Light();
if(sample_index >= SAMPLE_SIZE) sample_index = 0;
uint32_t sum = 0;
for(int i=0; i<SAMPLE_SIZE; i++) {
sum += light_samples[i];
}
return sum / SAMPLE_SIZE;
}
雨滴检测则需要加入消抖逻辑,以下是改进后的代码:
c复制uint8_t Get_StableRain(void) {
static uint8_t count = 0;
static uint8_t last_state = 0;
uint8_t current = Get_Rain();
if(current != last_state) {
count = 0;
last_state = current;
} else {
if(++count > 5) { // 连续5次检测相同才确认状态
return current;
}
}
return last_state;
}
3.2 多模式状态机实现
系统支持自动、定时、手动三种模式,使用状态机模式可以清晰管理状态转换:
c复制typedef enum {
MODE_AUTO,
MODE_TIMER,
MODE_MANUAL
} SystemMode;
SystemMode current_mode = MODE_AUTO;
uint8_t curtain_state = 0; // 0=关闭,1=打开
uint8_t rack_state = 1; // 默认展开晾衣架
void Handle_AutoMode(void) {
uint16_t light = Get_FilteredLight();
uint8_t rain = Get_StableRain();
// 光照低于阈值开窗帘
if(light < 1000 && !curtain_state) {
Curtain_Open();
curtain_state = 1;
}
// 光照高于阈值关窗帘
else if(light > 3000 && curtain_state) {
Curtain_Close();
curtain_state = 0;
}
// 下雨收衣架
if(rain && rack_state) {
Rack_Retract();
rack_state = 0;
}
// 天晴且无雨展衣架
else if(!rain && light > 2000 && !rack_state) {
Rack_Extend();
rack_state = 1;
}
}
3.3 OLED界面优化技巧
128x64的OLED显示空间有限,需要精心设计信息布局。推荐采用以下分区方案:
- 顶部20像素:系统状态栏(模式图标+时间)
- 中间30像素:传感器数据区
- 底部14像素:操作提示区
使用自定义字体可以提升显示效果,以下是字体定义示例:
c复制// 8x16像素自定义字体
const uint8_t Font8x16[][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 空格
{0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00} // !
// 其他字符定义...
};
void OLED_ShowCustomChar(uint8_t x, uint8_t y, uint8_t index) {
for(uint8_t i=0; i<16; i++) {
OLED_WR_Byte(Font8x16[index][i], OLED_DATA);
}
}
4. 进阶功能扩展
4.1 手机蓝牙控制实现
添加HC-05蓝牙模块(约15元)即可实现手机控制,需要修改串口初始化:
c复制void USART1_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&huart1);
}
配套的Android端可以使用MIT App Inventor快速开发控制APP,定义简单通信协议:
- "O1": 打开窗帘
- "C1": 关闭窗帘
- "O2": 展开衣架
- "C2": 收起衣架
4.2 能耗优化策略
通过以下方法可降低系统功耗约60%:
- 将主循环延迟从100ms改为500ms
- 关闭未使用的时钟(如SPI2、ADC2等)
- 使用停机模式+外部中断唤醒
c复制void Enter_LowPowerMode(void) {
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config(); // 唤醒后重新配置时钟
HAL_ResumeTick();
}
5. 常见问题解决方案
5.1 传感器读数异常排查
现象:光敏值始终为0或4095
- 检查ADC引脚配置是否正确
- 测量模块输出电压是否在0-3.3V范围内
- 确认ADC时钟已使能
现象:雨滴传感器频繁误触发
- 调整模块上的灵敏度电位器
- 检查电源是否稳定(建议并联100μF电容)
- 增加软件消抖时间
5.2 OLED显示异常处理
花屏问题:
- 检查I2C地址(通常0x78或0x7A)
- 确认初始化序列完整
- 降低I2C时钟速度(<400kHz)
显示残影:
- 每次刷新前执行清屏操作
- 避免局部刷新,尽量全屏重绘
- 检查电源电压是否稳定(3.3V±5%)
6. 项目文档编写技巧
没有实物的情况下,文档质量直接决定项目评分。推荐采用以下结构:
- 系统框图:使用Draw.io绘制,标注各模块关系
- 电路原理图:Proteus或Altium Designer绘制
- 算法流程图:重点说明控制逻辑
- 测试数据表:模拟不同光照/雨量下的响应
- 参考文献:至少包含STM32参考手册和传感器Datasheet
文档加分项:添加Gantt图展示开发进度,附上仿真运行视频链接
这个项目最实用的地方在于其可扩展性——把窗帘电机换成水泵就是智能浇花系统,换成风扇就是温控装置。我后来用相同框架改出了三个不同主题的课程设计,教授都没发现核心代码是重用的。
