Action
We'll start by generating the project using the template, then modify the code to fit the current project's requirements.
Generating From template
Refer to the Template section for details and instructions.
To generate the project, run:
cargo generate --git https://github.com/ImplFerris/pico2-template.git
When prompted, choose a name for your project-let's go with "bat-beacon". Don't forget to select rp-hal
as the HAL.
Then, navigate into the project folder:
cd PROJECT_NAME
# For example, if you named your project "bat-beacon":
# cd bat-beacon
Setup the LED Pin
You should understand this code by now. If not, please complete the Blink LED section first.
Quick recap: Here, we're configuring the PWM for the LED, which allows us to control the brightness by adjusting the duty cycle.
#![allow(unused)] fn main() { let pwm = &mut pwm_slices.pwm6; // Access PWM slice 6 pwm.set_ph_correct(); // Set phase-correct mode for smoother transitions pwm.enable(); // Enable the PWM slice let led = &mut pwm.channel_b; // Select PWM channel B led.output_to(pins.gpio3); // Set GPIO 3 as the PWM output pin }
Setup the Trigger Pin
The Trigger pin on the ultrasonic sensor is used to start the ultrasonic pulse. It needs to be set as an output so we can control it to send the pulse.
#![allow(unused)] fn main() { let mut trigger = pins.gpio17.into_push_pull_output(); }
Setup the Echo Pin
The Echo pin on the ultrasonic sensor receives the returning signal, which allows us to measure the time it took for the pulse to travel to an object and back. It's set as an input to detect the returning pulse.
#![allow(unused)] fn main() { let mut echo = pins.gpio16.into_pull_down_input(); }
🦇 Light it Up
Step 1: Send the Trigger Pulse
First, we need to send a short pulse to the trigger pin to start the ultrasonic measurement.
#![allow(unused)] fn main() { // Ensure the Trigger pin is low before starting trigger.set_low().ok().unwrap(); timer.delay_us(2); // Send a 10-microsecond high pulse trigger.set_high().ok().unwrap(); timer.delay_us(10); trigger.set_low().ok().unwrap(); }
Step 2: Measure the Echo Time
Now, measure the time the Echo pin remains high, which represents the round-trip time of the sound wave.
#![allow(unused)] fn main() { let mut time_low = 0; let mut time_high = 0; // Wait for the Echo pin to go high and note down the time while echo.is_low().ok().unwrap() { time_low = timer.get_counter().ticks(); } // Wait for the Echo pin to go low and note down the time while echo.is_high().ok().unwrap() { time_high = timer.get_counter().ticks(); } // Calculate the time taken for the signal to return let time_passed = time_high - time_low; }
Step 3: Calculate Distance
Using the measured time, calculate the distance to the object. The speed of sound in air is approximately 0.0343 cm/µs.
#![allow(unused)] fn main() { let distance = time_passed as f64 * 0.0343 / 2.0; }
Step 3: Calculate Distance
Finally, adjust the LED brightness based on the distance. If the distance is below a certain threshold (e.g., 30 cm), increase the brightness proportionally; otherwise, turn off the LED.
#![allow(unused)] fn main() { let duty_cycle = if distance < 30.0 { let step = 30.0 - distance; (step * 1500.) as u16 + 1000 } else { 0 }; // Set the LED brightness led.set_duty_cycle(duty_cycle).unwrap(); }
Complete Logic of the loop
Note: This code snippet highlights the loop section and does not include the entire code.
#![allow(unused)] fn main() { loop { timer.delay_ms(5); trigger.set_low().ok().unwrap(); timer.delay_us(2); trigger.set_high().ok().unwrap(); timer.delay_us(10); trigger.set_low().ok().unwrap(); let mut time_low = 0; let mut time_high = 0; while echo.is_low().ok().unwrap() { time_low = timer.get_counter().ticks(); } while echo.is_high().ok().unwrap() { time_high = timer.get_counter().ticks(); } let time_passed = time_high - time_low; let distance = time_passed as f64 * 0.0343 / 2.0; let duty_cycle = if distance < 30.0 { let step = 30.0 - distance; (step * 1500.) as u16 + 1000 } else { 0 }; led.set_duty_cycle(duty_cycle).unwrap(); } }
Clone the existing project
You can clone (or refer) project I created and navigate to the ultrasonic
folder.
git clone https://github.com/ImplFerris/pico2-rp-projects
cd pico2-projects/ultrasonic
Your Challenge
- Use Embassy framework instead of rp-hal
- Use the onboard LED instead