rust 嵌入式esp23 《雨滴传感器》

126 阅读3分钟

雨滴传感器是一种能实时感知外界雨滴存在、雨量大小及降雨强度的环境感知设备,其核心作用在于将雨滴接触带来的物理特性变化(如电阻、电容、光反射率的改变)转化为可被电子系统识别的电信号,为后续的自动化控制、数据采集或预警决策提供精准的雨况依据。​

在应用场景上,雨滴传感器的实用性广泛覆盖多个领域:汽车领域中,它是自动雨刷系统的 “眼睛”,可根据雨量自动调节雨刷摆动速度,同时联动车窗控制系统,遇暴雨时触发车窗自动关闭,避免雨水侵入车内;智能家居场景里,它能与智能天窗、户外智能晾衣架联动,一旦检测到降雨,立即发出指令关闭天窗、收回晾衣架,保障家居物品干燥与室内环境舒适;农业生产中,雨滴传感器可集成至温室大棚或农田灌溉系统,通过监测降雨量动态调整灌溉频率与水量,避免过度灌溉造成水资源浪费,助力农业精准种植;此外,在气象监测站、道路交通安全预警系统(如提醒路面湿滑风险)、户外设备防护(如无人值守设备的防雨保护)等场景中,雨滴传感器也凭借其灵敏的感知能力,成为提升系统自动化水平与运行安全性的关键组件。

实现功能

  1. 通过雨滴传感器获取是否下雨的信息

熟悉硬件:

雨滴传感器

b1.png

基础接口(适用于大多数单片机/开发板型号)

雨滴传感器的接线接口因型号和应用场景不同存在差异,但核心接口及接线逻辑具有共性。以下是综合不同型号的接线说明及注意事项:

VCC(电源正极)
  • 接3.3V或5V电源,需根据传感器工作电压选择(常见为3.3V-5V)
  • 例如:STM32、Arduino等开发板可直接连接5V引脚。
GND(电源负极/地线)
  • 接电源负极或开发板的GND引脚,确保回路闭合
DO(数字输出)
  • 输出开关信号(0或1),用于检测是否有雨。
  • 连接单片机的数字输入引脚(如Arduino的D2、STM32的PA0等)
  • 无雨时输出高电平(DO=1),有雨时输出低电平(DO=0)
AO(模拟输出)
  • 输出0-5V连续电压值,反映雨量大小。
  • 连接单片机的模拟输入引脚(如Arduino的A0、STM32的PA1)
  • 通过ADC读取电压值,计算雨滴强度或雨量

ESP32链接示意图

b2.png 接线:
VCC -->3V3
GND -->GND
DO -->G5
AO -->G4

代码实现

修改Cargo.toml文件,添加nb引入

...
nb = "1.1.0"
...

实现G5引脚信息接入

...
  let raindrop = Input::new(peripherals.GPIO5, InputConfig::default());
...

实现G4引脚信息接入

...
    // 配置 ADC
    let mut adc_config = AdcConfig::new();
    let mut adc_pin = adc_config.enable_pin(peripherals.GPIO4, Attenuation::_11dB); // 设置衰减为 0-3.3V
    let mut adc = Adc::new(peripherals.ADC1, adc_config);
...

打印信息

...
let delay = Delay::new();
loop {
    let raw_value: u16 = nb::block!(adc.read_oneshot(&mut adc_pin)).unwrap();
    let voltage = (raw_value as f32 * 3.3) / 4095.0;
    println!("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" );
    println!("adc_value: {}", raw_value);
    println!("voltage: {}", voltage);
    println!("raindrop: {}", raindrop.is_low());
    delay.delay_millis(1000);
}
...

完整代码

#![no_std]
#![no_main]
#![deny(
    clippy::mem_forget,
    reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
    holding buffers for the duration of a data transfer."
)]

use esp_hal::{
    analog::adc::{Adc, AdcConfig, Attenuation},
    clock::CpuClock,
    delay::Delay,
    gpio::{Input, InputConfig},
    main,
};
use esp_println::println;

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {
        println!("Panic!");
    }
}

pub fn update_method(timestamp: u32) {
    println!("update_method: {}", timestamp);
}
esp_bootloader_esp_idf::esp_app_desc!();
#[main]
fn main() -> ! {
    // generator version: 0.5.0
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);
    let raindrop = Input::new(peripherals.GPIO5, InputConfig::default());
    // 配置 ADC
    let mut adc_config = AdcConfig::new();
    let mut adc_pin = adc_config.enable_pin(peripherals.GPIO4, Attenuation::_11dB); // 设置衰减为 0-3.3V
    let mut adc = Adc::new(peripherals.ADC1, adc_config);
    let delay = Delay::new();
    loop {
        let raw_value: u16 = nb::block!(adc.read_oneshot(&mut adc_pin)).unwrap();
        let voltage = (raw_value as f32 * 3.3) / 4095.0;
        println!("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" );
        println!("adc_value: {}", raw_value);
        println!("voltage: {}", voltage);
        println!("raindrop: {}", raindrop.is_low());
        delay.delay_millis(1000);
    }

    // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin
}

效果展示

b3.gif