Skip to content

Instantly share code, notes, and snippets.

@manio
Created August 6, 2023 08:54
Show Gist options
  • Save manio/b91fc07e6d6e9e48382cbf6ea0f0d341 to your computer and use it in GitHub Desktop.
Save manio/b91fc07e6d6e9e48382cbf6ea0f0d341 to your computer and use it in GitHub Desktop.
esp-rs embassy function for reading ultrasonic distance sensor JSN-SR04T / AJ-SR04M using mode 0 (pulse time)
/*
The following snipset is for reading the AJ-SR04M (JSN-SR04T compatible) ultrasonic distance sensor
under rust (esp-rs + embassy).
It is intended for mode 0 (which is the default) and it is counting the resulting echo pulse timing.
Finaly the useconds value is converted to centimeters value.
ESP32 wiring:
Vcc -> 5V
Trigger -> GPIO 19
Echo -> GPIO 21 (via level shifter)
Gnd -> gnd
5V->3v3 level shifter for the echo pin done like this:
https://wokwi.com/projects/364680888105225217
*/
#[entry]
fn main() -> ! {
// standard initialization, watchdog disable, etc
// Instantiate and Create Handle for IO
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Instantiate and Create Handle for trigger output & echo input
let mut trig = io.pins.gpio19.into_push_pull_output();
let echo = io.pins.gpio21.into_floating_input();
// Async requires the GPIO interrupt to wake futures
hal::interrupt::enable(
hal::peripherals::Interrupt::GPIO,
hal::interrupt::Priority::Priority1,
)
.unwrap();
// here you may start your task
// and from there you can call the ping async function
// which will return measured cm value...
// tip: consider use use embassy_time::{with_timeout}
// to be safe when the device will not give any feedback pulse
}
async fn ping(echo: &mut Gpio21<Input<Floating>>, trigger: &mut Gpio19<Output<PushPull>>) -> f64 {
// 1) Set pin ouput to low for 5 us to get clean low pulse
trigger.set_low().unwrap();
Timer::after(Duration::from_micros(5)).await;
// 2) Set pin output to high (trigger) for 20us
trigger.set_high().unwrap();
Timer::after(Duration::from_micros(20)).await;
trigger.set_low().unwrap();
echo.wait_for_rising_edge().await.unwrap();
// Kick off timer measurement
let echo_start = Instant::now();
echo.wait_for_falling_edge().await.unwrap();
// Collect current timer count (result pulse time)
let delay = echo_start.elapsed().as_micros();
// Calculate the distance in cms using formula in datasheet
let distance_cm = ((delay * 348) as f64 / 2.0) / 10_000.0;
distance_cm
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment