1. 雨滴传感器项目概述
雨滴传感器是智能家居和物联网应用中常见的环境监测设备,它能实时检测降雨情况并输出相应信号。在STM32平台上实现雨滴检测功能,不仅成本低廉而且可靠性高,非常适合用于智能窗户、自动雨刷、农业灌溉等场景。
我最近用STM32F103C8T6开发板做了一个雨滴传感器的实验项目,整个过程涉及传感器选型、电路设计、ADC采集和阈值判断等多个环节。这个项目虽然看起来简单,但实际调试过程中有不少值得注意的细节,特别是如何提高检测精度和抗干扰能力。下面我就把完整的实现过程和踩过的坑分享给大家。
2. 硬件设计与元件选型
2.1 雨滴传感器模块选择
市面上常见的雨滴传感器主要有两种类型:
- 基于导电原理的传感器
- 基于光学原理的传感器
我选用的是第一种,型号为YL-83的雨滴传感器模块。这个模块价格便宜(约15元),工作电压3.3V-5V,与STM32的供电兼容。它的核心是一块带有平行导线的PCB板,当雨滴落在板上时会导致电阻变化,模块通过LM393比较器输出数字信号和模拟信号。
提示:虽然数字输出使用方便,但建议使用模拟输出以获得更精确的雨量检测。数字输出只能判断"有雨/无雨",而模拟量可以反映雨量大小。
2.2 电路连接方案
完整的硬件连接如下表示:
| STM32引脚 | 传感器接口 | 备注 |
|---|---|---|
| 3.3V | VCC | 电源正极 |
| GND | GND | 电源负极 |
| PA0 | AO | 模拟信号输出 |
| PA1 | DO | 数字信号输出(可选) |
实际接线时要注意:
- 如果使用杜邦线连接,线长最好不要超过20cm,避免引入干扰
- 建议在VCC和GND之间加一个0.1uF的滤波电容
- 传感器板要倾斜约30度安装,方便雨水滑落
3. 软件实现与ADC配置
3.1 STM32CubeMX基础配置
使用STM32CubeMX进行初始化配置:
- 选择正确的STM32型号(我用的F103C8T6)
- 启用ADC1,选择通道0(对应PA0)
- 配置ADC为12位分辨率,连续转换模式
- 设置适当的采样时间(我用的239.5周期)
- 生成代码时选择生成必要的HAL库函数
关键配置参数示例:
c复制hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
3.2 ADC采集与数据处理
在主程序中实现ADC数据采集:
c复制uint32_t raindrop_value = 0;
HAL_ADC_Start(&hadc1);
while(1) {
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
raindrop_value = HAL_ADC_GetValue(&hadc1);
// 转换为电压值(0-3.3V)
float voltage = raindrop_value * 3.3f / 4095.0f;
// 判断逻辑
if(voltage > 2.5f) {
printf("无雨\n");
} else if(voltage > 1.8f) {
printf("小雨\n");
} else {
printf("大雨\n");
}
}
HAL_Delay(500);
}
3.3 数字信号处理优化
为了提高检测稳定性,我加入了简单的数字滤波算法:
c复制#define SAMPLE_SIZE 5
uint32_t get_filtered_value() {
uint32_t sum = 0;
for(int i=0; i<SAMPLE_SIZE; i++) {
HAL_ADC_PollForConversion(&hadc1, 10);
sum += HAL_ADC_GetValue(&hadc1);
HAL_Delay(10);
}
return sum / SAMPLE_SIZE;
}
4. 校准与调试技巧
4.1 传感器校准方法
-
干燥状态校准:
- 确保传感器完全干燥
- 记录此时的ADC值作为"无雨"基准
- 我的模块干燥时输出约3.0V(ADC值约3720)
-
湿润状态校准:
- 用湿布轻轻擦拭传感器表面
- 记录此时的ADC值作为"有雨"基准
- 我的模块湿润时输出约1.2V(ADC值约1480)
-
设置合理阈值:
- 无雨状态值 × 0.9 作为开始检测阈值
- 根据实际需求划分小雨/大雨的阈值
4.2 常见问题排查
-
数值跳动严重:
- 检查电源是否稳定,建议使用LDO稳压
- 增加软件滤波(如前面介绍的均值滤波)
- 缩短传感器到MCU的连线
-
检测不灵敏:
- 检查传感器表面是否氧化,可用酒精清洁
- 适当降低比较器阈值(调节模块上的蓝色电位器)
- 确保传感器安装角度正确(30度左右最佳)
-
ADC读数异常:
- 确认ADC配置正确,特别是采样时间
- 检查是否有其他外设干扰ADC通道
- 尝试更换ADC通道测试
5. 实际应用扩展
5.1 与继电器模块联动
可以将雨滴传感器与继电器模块结合,实现自动关窗功能:
c复制if(get_filtered_value() < RAIN_THRESHOLD) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 打开继电器
printf("检测到下雨,正在关闭窗户...\n");
} else {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 关闭继电器
}
5.2 通过串口发送数据
添加串口功能,将数据发送到上位机或物联网平台:
c复制void send_raindrop_data() {
uint32_t value = get_filtered_value();
float voltage = value * 3.3f / 4095.0f;
char buffer[64];
sprintf(buffer, "{\"adc\":%lu,\"voltage\":%.2f}\r\n", value, voltage);
HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 100);
}
5.3 低功耗优化技巧
如果需要电池供电,可以优化为间歇工作模式:
- 配置MCU进入STOP模式
- 使用定时器或外部中断唤醒
- 缩短ADC采样时间
- 采样完成后立即返回低功耗模式
实现示例:
c复制void enter_stop_mode() {
HAL_ADC_Stop(&hadc1);
HAL_UART_DeInit(&huart1);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后重新初始化
SystemClock_Config();
MX_ADC1_Init();
MX_USART1_UART_Init();
}
6. 项目总结与改进方向
经过实际测试,这个雨滴检测系统在室内模拟环境下工作良好,能够稳定区分干燥、湿润和积水三种状态。但在实际户外应用中,还需要考虑以下改进:
- 增加温度补偿:传感器特性会随温度变化,可以加入DS18B20进行温度补偿
- 防氧化处理:长期户外使用,传感器表面可涂覆防氧化涂层
- 多传感器融合:结合湿度传感器数据提高判断准确性
- 机械结构优化:设计带排水槽的防护外壳,防止积水影响检测
这个项目虽然简单,但涵盖了STM32开发的多个基础知识点:GPIO配置、ADC采集、定时器使用、中断处理等,非常适合作为STM32外设开发的入门练习。我在调试过程中最大的收获是理解了硬件滤波和软件滤波的结合使用,这对提高传感器系统的稳定性至关重要。