5.1 Digital Distance Meter
Time to build your own digital radar! The ultrasonic sensor works like a bat’s echolocation or ship sonar - it sends out sound waves you can’t hear and measures how long they take to bounce back. This gives you precise distance measurements from 2cm to 4 meters!
Perfect for: Parking sensors, automatic doors, robot navigation, water level monitoring, or security systems. Imagine creating a “smart trash can” that opens when you approach, or a device that tells you how full your water tank is!
Component List
Raspberry Pi Pico W x1
MicroUSB cable x1
830 Tie-Points Breadboard x1
Ultrasonic Module x1
Jumper Wire Several
Component knowledge
Ultrasonic Module
Connect
Code
Note
Open the
5.1_digital_distance_meter.inofile under the path ofUltimate-Starter-Kit-for-Pico-W\Arduino\1.Projector copy this code into Thonny, then click “Run Current Script” or simply press F5 to run it.Or copy this code into Arduino IDE.
Don’t forget to select the board(Raspberry Pi Pico) and the correct port before clicking the Upload button.
After running the code, move your hand or objects in front of the sensor and watch real-time distance measurements! The sensor updates every 0.5 seconds with precision to 1cm. Try testing different objects, distances, and angles to see how this “electronic measuring tape” responds. It can even detect through thin materials like paper!
The following is the program code:
/*
* Ultrasonic Distance Sensor Project
*
* Measures distance using HC-SR04 ultrasonic sensor with professional
* error handling and timeout protection. Based on sound wave travel time
* calculation with accurate physics constants.
*
* Hardware: HC-SR04 ultrasonic sensor (Trigger + Echo pins)
*/
// Pin Configuration Constants
#define TRIGGER_PIN 17 // Ultrasonic sensor trigger pin
#define ECHO_PIN 16 // Ultrasonic sensor echo pin
// Physics Constants
#define SOUND_SPEED_CM_PER_US 0.0343 // Speed of sound: 343 m/s = 0.0343 cm/µs
#define PULSE_TRIGGER_US 10 // Trigger pulse duration (microseconds)
#define PULSE_DELAY_US 2 // Pre-trigger delay (microseconds)
// Measurement Constants
#define ECHO_TIMEOUT_US 25000 // Maximum wait time for echo (µs) ≈ 4.3m max range
#define MEASUREMENT_DELAY_MS 500 // Delay between measurements (milliseconds)
#define SERIAL_BAUD_RATE 115200 // Serial communication speed
// Measurement Range Constants
#define MIN_DISTANCE_CM 2.0 // Minimum measurable distance
#define MAX_DISTANCE_CM 400.0 // Maximum measurable distance
void setup() {
// Initialize serial communication
Serial.begin(SERIAL_BAUD_RATE);
// Configure ultrasonic sensor pins
setupUltrasonicSensor();
// Display startup information
Serial.println("=== Ultrasonic Distance Sensor ===");
Serial.println("Range: 2cm - 400cm");
Serial.println("Accuracy: ±1cm");
Serial.println("==================================");
}
void loop() {
float distance = measureDistance();
displayMeasurement(distance);
delay(MEASUREMENT_DELAY_MS);
}
/**
* Setup Ultrasonic Sensor
* Initializes the trigger and echo pins for the HC-SR04 sensor.
*/
void setupUltrasonicSensor() {
pinMode(ECHO_PIN, INPUT);
pinMode(TRIGGER_PIN, OUTPUT);
digitalWrite(TRIGGER_PIN, LOW); // Ensure trigger starts LOW
}
/**
* Measure Distance
* Performs ultrasonic distance measurement with timeout protection.
* Returns -1.0 on timeout or invalid measurement.
*/
float measureDistance() {
// Send trigger pulse
sendTriggerPulse();
// Measure echo pulse duration with timeout protection
unsigned long pulseDuration = measureEchoPulse();
// Check for timeout
if (pulseDuration == 0) {
return -1.0; // Measurement failed
}
// Calculate distance using physics formula
float distance = calculateDistanceFromPulse(pulseDuration);
// Validate measurement range
if (distance < MIN_DISTANCE_CM || distance > MAX_DISTANCE_CM) {
return -1.0; // Out of valid range
}
return distance;
}
/**
* Send Trigger Pulse
* Sends a 10µs pulse to trigger the ultrasonic measurement.
*/
void sendTriggerPulse() {
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(PULSE_DELAY_US);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(PULSE_TRIGGER_US);
digitalWrite(TRIGGER_PIN, LOW);
}
/**
* Measure Echo Pulse
* Measures the duration of the echo pulse with timeout protection.
* Returns 0 on timeout, pulse duration in microseconds on success.
*/
unsigned long measureEchoPulse() {
// Use pulseIn with timeout for reliable measurement
unsigned long duration = pulseIn(ECHO_PIN, HIGH, ECHO_TIMEOUT_US);
return duration; // Returns 0 if timeout occurred
}
/**
* Calculate Distance From Pulse
* Converts pulse duration to distance using sound speed.
* Distance = (Pulse_Duration * Sound_Speed) / 2
*/
float calculateDistanceFromPulse(unsigned long pulseDuration) {
// Convert microseconds to distance in centimeters
// Divide by 2 because sound travels to object and back
return (pulseDuration * SOUND_SPEED_CM_PER_US) / 2.0;
}
/**
* Display Measurement
* Shows measurement result with appropriate error handling.
*/
void displayMeasurement(float distance) {
if (distance > 0) {
Serial.print("Distance: ");
Serial.print(distance, 1); // Show 1 decimal place
Serial.println(" cm");
} else {
Serial.println("Measurement failed (Timeout or Out of Range)");
}
}
Phenomenon