use std::thread::sleep;
use std::time::{Duration, Instant};
use anyhow::{bail, Context, Result};
use rppal::gpio::{InputPin, OutputPin};
use crate::pin::{PinType, RHPin};
pub struct Ultrasonic {
trig: OutputPin,
echo: InputPin,
}
impl Ultrasonic {
pub fn new(trig_pin: PinType, echo_pin: PinType) -> Result<Self> {
if !trig_pin.is_digital_pin() {
bail!(
"trig_pin should be one of PinType::D0-D16, but passed {:?}",
trig_pin
)
}
if !echo_pin.is_digital_pin() {
bail!(
"echo_pin should be one of PinType::D0-D16, but passed {:?}",
echo_pin
)
}
let trig_pin = RHPin::new(trig_pin)
.with_context(|| format!("Creating trigger pin using {:?} failed", trig_pin))?;
let echo_pin = RHPin::new(echo_pin)
.with_context(|| format!("Creating echo pin using {:?} failed", echo_pin))?;
let trig = trig_pin.gpio_pin.into_output();
let echo = echo_pin.gpio_pin.into_input();
Ok(Ultrasonic { trig, echo })
}
pub fn read(&mut self) -> u64 {
self.trig.set_low();
sleep(Duration::from_micros(5));
self.trig.set_high();
sleep(Duration::from_micros(10));
self.trig.set_low();
while !self.echo.is_high() {}
let pulse_start = Instant::now();
while !self.echo.is_low() {}
let time_taken = pulse_start.elapsed().as_micros();
(time_taken / 58) as u64
}
}