diff --git a/examples/arduino-uno/src/bin/uno-hc-sr04.rs b/examples/arduino-uno/src/bin/uno-hc-sr04.rs new file mode 100644 index 0000000000..b0a64491c3 --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-hc-sr04.rs @@ -0,0 +1,73 @@ +//! Example for using the HC-SR04 ultrasonic distance sensor +//! +//! Sensor Datasheet: https://www.electroschematics.com/hc-sr04-datasheet/ +//! +//! Connections: +//! - TRIG <- D2 +//! - ECHO -> D3 +#![no_std] +#![no_main] + +use arduino_hal::prelude::*; +use panic_halt as _; + +#[arduino_hal::entry] +fn main() -> ! { + let dp = arduino_hal::Peripherals::take().unwrap(); + let pins = arduino_hal::pins!(dp); + let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + + let mut trig = pins.d2.into_output(); + let echo = pins.d3; // pin is input by default + + // Starting and initializing the timer with prescaling 64. + // it gives one clock count every 4 µs. + // since the clock register size is 16 bits, the timer is full every + // 1/(16e6/64)*2^16 ≈ 260 ms + let timer1 = dp.TC1; + timer1.tccr1b.write(|w| w.cs1().prescale_64()); + + 'outer: loop { + // the timer is reinitialized with value 0. + timer1.tcnt1.write(|w| unsafe { w.bits(0) }); + + // the trigger must be set to high under 10 µs as per the HC-SR04 datasheet + trig.set_high(); + arduino_hal::delay_us(10); + trig.set_low(); + + while echo.is_low() { + // exiting the loop if the timer has reached 200 ms. + // 0.2s/4µs = 50000 + if timer1.tcnt1.read().bits() >= 50000 { + // jump to the beginning of the outer loop if no obstacle is detected + ufmt::uwriteln!( + &mut serial, + "Nothing was detected and jump to outer loop.\r" + ) + .void_unwrap(); + continue 'outer; + } + } + // Restarting the timer + timer1.tcnt1.write(|w| unsafe { w.bits(0) }); + + // Wait for the echo to get low again + while echo.is_high() {} + + // 1 count == 4 us, so the value is multiplied by 4. + // 1/58 ≈ (34000 ms/2)* 1µs + let value = (timer1.tcnt1.read().bits() * 4) / 58; + + // Await 100 ms before sending the next trig + // 0.1s/4µs = 50000 + while timer1.tcnt1.read().bits() < 25000 {} + + ufmt::uwriteln!( + &mut serial, + "Hello, we are {} cms away from target!\r", + value + ) + .void_unwrap(); + } +}