How to Use an Ultrasonic Sensor with RPi and C++

Follow this wiring diagram for the HC-SR04 ultrasonic sensor:

I used 1KΩ and 2KΩ resistors instead of 330Ω and 470Ω (because it's what I had on hand). Here's what that looked like:

Test the wiring with this simple Python script:

from gpiozero import DistanceSensor
from time import sleep

ultrasonic = DistanceSensor(echo=17, trigger=4, max_distance=4)

while True:
    print(f"{ultrasonic.distance * 100:.1f} cm")
    sleep(1)

Then install WiringPi , the fastest RPi GPIO access library:

git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build debian
mv debian-template/wiringpi_3.10_arm64.deb .
sudo apt install ./wiringpi_3.10_arm64.deb

Create a file with this program:

#include <wiringPi.h>
#include <iostream>
#include <iomanip>
#include <unistd.h>
  
#define TRIGGER_PIN 4    // GPIO 4
#define ECHO_PIN    17   // GPIO 17
#define TIMEOUT     25000 // Maximum time to wait for echo (in microseconds)
  
double measureDistance() {
    // Send trigger pulse
    digitalWrite(TRIGGER_PIN, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIGGER_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIGGER_PIN, LOW);
    
    // Wait for echo start
    while (digitalRead(ECHO_PIN) == LOW);
    long startTime = micros();
    
    // Wait for echo end
    while (digitalRead(ECHO_PIN) == HIGH && micros() - startTime < TIMEOUT);
    long endTime = micros();

    // Calculate distance
    double duration = (endTime - startTime);
    double distance = (duration * 0.0343) / 2; // Speed of sound = 343 m/s
    return distance;
}

  

int main() {
    // Initialize WiringPi
    if (wiringPiSetupGpio() == -1) {
        std::cerr << "Failed to initialize WiringPi" << std::endl;
        return 1;
    }

    // Setup pins
    pinMode(TRIGGER_PIN, OUTPUT);
    pinMode(ECHO_PIN, INPUT);

    while (true) {
        double distance = measureDistance();
        std::cout << std::fixed << std::setprecision(1)
                  << distance << " cm" << std::endl;
        sleep(1);
    }

    return 0;
}

Compile it (linking wiringPi):

g++ -o ultrasonic main.cpp -l wiringPi

And run:

./ultrasonic

If everything worked correctly, you should see something like this:

66.7 cm
66.2 cm
65.8 cm
4.8 cm
24.4 cm
23.6 cm
4.9 cm

All code available on GitHub.

12.3.2024