๐Ÿ“ Pico Series
Episode 03 ยท Pico Learning Series
// CONCEPT: ADC + PULSE TIMING

UltrasonicDistance Sensor

HC-SR04 ยท TRIG/ECHO ยท Pulse Width โ†’ cm/inch
// What you'll learn
How sound waves measure distance (time-of-flight)
How to generate a 10ยตs TRIG pulse to fire the sensor
How to measure ECHO pulse width in microseconds
Converting pulse time โ†’ cm and inches with the speed of sound
// Interactive Distance Simulator
20
centimeters
7.9
inches
1160
ยตs echo
โ† Move slider to change distance โ†’
// 01 โ€” Core Concepts

How Sound Measures Distance

๐Ÿ“ก
Time-of-Flight Principle
The HC-SR04 emits a burst of 40 kHz ultrasonic pulses and measures how long they take to bounce back. Distance = (time ร— speed of sound) รท 2. The รท 2 accounts for the round trip โ€” there and back.
Physics
โšก
TRIG Pulse โ€” Fire!
To start a measurement: pull TRIG HIGH for โ‰ฅ10ยตs, then LOW. This tells the sensor to emit 8 ultrasonic pulses. The Pico does this with gpio_put() and sleep_us(10).
gpio_put() + sleep_us(10)
๐Ÿ“
ECHO Pulse โ€” Measure!
ECHO goes HIGH when the pulses are sent and stays HIGH until the echo returns. The Pico counts microseconds while ECHO is HIGH using a tight loop โ€” that duration is proportional to distance.
gpio_get() + width++
// 02 โ€” Signal Timing

The TRIG / ECHO Protocol

// Signal Diagram
TRIG
10ยตs
ECHO
width ยตs = distance
// Distance Formulas
cm = pulseWidth / 29 / 2
Sound travels 29 ยตs/cm
รท 2 = round trip
inch = pulseWidth / 74 / 2
Sound travels 74 ยตs/inch
ultrasonic.c
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int timeout = 26100; // max ยตs to wait

// Fire TRIG pulse, measure ECHO width
uint64_t getPulse(uint trigPin, uint echoPin) {
    gpio_put(trigPin, 1);
    sleep_us(10);        // โ‰ฅ10ยตs HIGH pulse
    gpio_put(trigPin, 0);

    uint width = 0;

    // Wait for ECHO to go HIGH
    while (gpio_get(echoPin) == 0)
        tight_loop_contents();

    // Count ยตs while ECHO stays HIGH
    while (gpio_get(echoPin) == 1) {
        width++;
        sleep_us(1);
        if (width > timeout) return 0;
    }
    return width;
}

// Convert pulse width โ†’ centimeters
int getCm(uint trig, uint echo) {
    uint64_t pulse = getPulse(trig, echo);
    return pulse / 29 / 2;
}

// Convert pulse width โ†’ inches
int getInch(uint trig, uint echo) {
    uint64_t pulse = getPulse(trig, echo);
    return (long)pulse / 74.f / 2.f;
}

int main() {
    stdio_init_all();
    uint trigPin = 2, echoPin = 3;

    gpio_init(trigPin); gpio_set_dir(trigPin, GPIO_OUT);
    gpio_init(echoPin); gpio_set_dir(echoPin, GPIO_IN);

    while (true) {
        int d = getCm(trigPin, echoPin);
        printf("\nDistance: %d cm", d);
        sleep_us(10000);
    }
}
// 03 โ€” Hardware

Pin Connections

Connection Table โ€” HC-SR04
HC-SR04 Pin   โ†’   Raspberry Pi Pico
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
VCC           โ†’   3.3V
GND           โ†’   GND
TRIG          โ†’   GPIO 2    (OUTPUT)
ECHO          โ†’   GPIO 3    (INPUT)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Output: Distance printed to serial console
// Baud: 115200 via USB CDC (PuTTY/screen)