Introduction

The distance sensor (also known as an ultrasonic sensor) is used for distance measurements. It can estimate distances from 2 cm to 400 cm, with an accuracy of 3mm. It’s the most widely used and least expensive distance sensor. There are others available that are much more accurate, but also much more expensive.

You can buy one here, or find it in this kit.

How does it works?

To measure distance, the ultrasonic sensor uses a signal sent from the Trigger terminal and received by the Echo terminal. The time it takes for the Echo terminal to receive the signal gives the distance between the sensor and the object.

Here’s how the ultrasonic sensor calculates the distance: Distance = (received signal * speed of sound) /2

The speed of sound in air is 340 m/s.

Let’s take a look at some common examples of how the HC-SR04 ultrasonic sensor is used.

How the distance sensor works with a library

 

 

 

To start operating the sensor, you need to install the HC-SR04 library on arduino :

Here is a diagram of the sensor wiring:

Here is an initial program to measure distance using the sensor:

#include “SR04.h” //Library 

// definition of sensor pins
const int trigPin =2;
const int echoPin =3;

UltraSonicDistanceSensor distanceSensor(trigPin, echoPin); // initialize sensor with pins used

void setup() {
    Serial.begin(9600); // Serial monitor communication initialization (9600 bits/s)
}
void loop() {
    // Measures and displays distance in centimeters on serial port every 500 ms
    Serial.print(“Distance in cm:”) ;
    Serial.println(distanceSensor.measureDistanceCm()) ;
    delay (500) ;
}

Operating the distance sensor without library

It is possible to operate the ultrasonic sensor without using a library. To do so, we’ll have to calculate the echo duration ourselves, i.e. the time it takes for the ultrasonic sensor to receive the beam. Then we’ll calculate the distance between the transducer and the object.

To dispense with the library, you’ll need to add certain elements to your program.

Step 1


First of all, you’ll need to start a 10 microsecond beam on the trig terminal in order to start the signal.

digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

Here we can see that the signal is switched off and then on for 10 microseconds, then switched off a second time.

Step 2


Retrieve the time it takes for the signal to return to the sensor: duree = pulseIn(echoPin, HIGH);

We then calculate this distance using the formula given above: Distance = (received signal * speed of sound) /2

Speed of sound in air: 340 m/s

Distance = duration*0.034/2 ;

Step 3: Final code


Here’s the same code, but without using the library this time:

// Port number definition
const int trigPin = 2; // Trigger (send)
const int echoPin = 3; // Echo (receive)

// Useful variables
long duree; // Echo duration
int distance;

void setup() {
    pinMode(trigPin, OUTPUT); // Trigger port configuration as OUTPUT
    pinMode(echoPin, INPUT); // Echo port configuration as INPUT
    Serial.begin(9600); // Start serial communication at 9600 bits/s
}
void loop() {
    // Send a signal lasting 10 microseconds
    digitalWrite(trigPin, LOW);
    delayMicroseconds(5);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    // Listen to echo
    duree = pulseIn(echoPin, HIGH);
    // Calculate distance
    distance = duration*0.034/2;
    // Display distance in Serial Monitor
    Serial.print(“Distance in cm :”) ;
    Serial.println(distance) ;
    delay(500); // Delay to avoid displaying too many results per second
}

Distance sensor connected to LED

In the program below, the intensity of the LED changes according to the distance from the obstacle.

Its intensity is expressed as a percentage in the table below:

TABLE

Here is the program with the library:

#include “SR04.h” // Library 
// Sensor pin definition
const int trigPin = 2;
const int echoPin = 3;
const int LED=9;
UltraSonicDistanceSensor distanceSensor(trigPin, echoPin); // Sensor initialization with used pins

void setup() {
    pinMode(LED, OUTPUT);
    Serial.begin(9600); // Serial monitor communication initialized at 9600 bits/s
}
void loop() {
    // Measure and display distance in centimeters on serial port every 500 ms
    Serial.print(“Distance in cm:”);
    Serial.println(distanceSensor.measureDistanceCm());
    if (distanceSensor.measureDistanceCm()>100){
        analogWrite(LED,0);
    }
    if (distanceSensor.measureDistanceCm()<100 and distanceSensor.measureDistanceCm()>30){
        analogWrite(LED,123);
    }
    if (distanceSensor.measureDistanceCm()<30 and distanceSensor.measureDistanceCm()>15){
        analogWrite(LED,191);
    }
    if (distanceSensor.measureDistanceCm()<15 and distanceSensor.measureDistanceCm()>0){
        analogWrite(LED,255);
    }
    delay(500); // Delay to avoid displaying too many results per second
}

Here is the same code without the library:

// Definition of sensor pins
const int trigPin = 2;
const int echoPin = 3;
const int LED=9;
// Useful variables
long duree;
int distance;

void setup() {
    pinMode(LED, OUTPUT);
    pinMode(trigPin, OUTPUT); // Trigger port configuration as OUTPUT
    pinMode(echoPin, INPUT); // Echo port configuration as INPUT
    Serial.begin(9600); // Initialize communication with serial monitor
}
void loop() {
    // Measure and display distance in centimeters on serial port every 500 ms
    digitalWrite(trigPin, LOW);
    delayMicroseconds(5);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    // Listen to echo
    duree = pulseIn(echoPin, HIGH);
    // Calculate distance
    distance = duration*0.034/2;
    Serial.print(“Distance in cm:”);
    Serial.println(distance);
    if (distance>100){
        analogWrite(LED,0);
    }
    if (distance<100 and distance>30){
        analogWrite(LED,123);
    }
    if (distance<30 and distance>15){
        analogWrite(LED,191);
    }
    if (distance<15 and distance>0){
        analogWrite(LED,255);
    }
    delay(500); // Delay to avoid displaying too many results per second
}

Light radar

We’re now going to connect our ultrasonic sensor to an RGB LED so that the color of the LED changes as the measured distance decreases. The aim is to create a small radar that would use the LED to indicate when we’re getting closer to an object or obstacle.

Here is the program with the library:

#include “SR04.h” // Library
// definition of sensor pins
const int trigPin = 2;
const int echoPin = 3;
// initialize led pins
const byte PIN_LED_R = 9;
const byte PIN_LED_G = 10;
const byte PIN_LED_B = 11;
UltraSonicDistanceSensor distanceSensor(trigPin, echoPin); // Initialize sensor with used pins
void setup() {
Serial.begin(9600); //Initialize serial port
//Initialize rgb led pins
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_B, OUTPUT);
displayColor(0, 0, 0);
}
void displayColor(byte r, byte g, byte b) {
// Assigns pin status
// Common cathode version
//analogWrite(PIN_LED_R, r);
//analogWrite(PIN_LED_G, g);
//analogWrite(PIN_LED_B, b);
// Common anode version
analogWrite(PIN_LED_R, ~r);
analogWrite(PIN_LED_G, ~g);
analogWrite(PIN_LED_B, ~b);
}
void loop() {
float distance_mm =(distanceSensor.measureDistanceCm()*10);
/* Display results in mm, cm and m */
Serial.print(F("Distance: ”));
Serial.print(distance_mm);
Serial.print(F(“mm (”));
Serial.print(distance_mm / 10.0, 2);
Serial.print(F("cm, ”));
Serial.print(distance_mm / 1000.0, 2);
Serial.println(F(“m)”));
delay(500); // Delay to avoid displaying too many results per second
if (distance_mm >= 300){displayColor(0, 255, 0);}
if (300 > distance_mm and distance_mm >= 250){
displayColor(0, 200, 0);
}
if (250 > distance_mm and distance_mm >= 200){
displayColor(0, 100, 100);
}
if (200 > distance_mm and distance_mm >=

Here is the same program associated with the project without the library:

// Initialize led pins
const byte PIN_LED_R = 9;
const byte PIN_LED_G = 10;
const byte PIN_LED_B = 11;
// Ultrasonic sensor initialization
const byte TRIGGER_PIN = 2; // TRIGGER pin
const byte ECHO_PIN = 3; // ECHO pin
/* Timeout constants */
const unsigned long MEASURE_TIMEOUT = 25000US; // delay before measurement cancellation: 25ms because 25 ms = 25000 us
/* the number of microseconds to wait for the pulse to start; default value is one second (unsigned) */
// Speed of sound in air in mm/us */
const float SOUND_SPEED = 340.0 / 1000 ;
void setup() {
Serial.begin(9600); //Initialize serial port
//Initialize rgb led pins
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_B, OUTPUT);
displayColor(0, 0, 0);
// Initialize ultrasonic sensor pins
pinMode(TRIGGER_PIN, OUTPUT);
digitalWrite(TRIGGER_PIN, LOW); // TRIGGER pin must be LOW at rest
pinMode(ECHO_PIN, INPUT);
}
void displayColor(byte r, byte g, byte b) {
// Common anode version
analogWrite(PIN_LED_R, ~r);
analogWrite(PIN_LED_G, ~g);
analogWrite(PIN_LED_B, ~b);
}
void loop() {
/* 1. starts a distance measurement by sending a 10µs HIGH pulse to the TRIGGER pin */
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
/* 2. Measures the time between sending the ultrasonic pulse and its echo (if any) */

long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
/* 3. Calculate distance from measured time */
float distance_mm = measure / 2.0 * SOUND_SPEED;
/* Display results in mm, cm and m */
Serial.print(F("Distance: ”));
Serial.print(distance_mm);
Serial.print(F(“mm (”));
Serial.print(distance_mm / 10.0, 2);
Serial.print(F("cm, ”));
Serial.print(distance_mm / 1000.0, 2);
Serial.println(F(“m)”));
/* Delay to avoid displaying too many results per second */
delay(500);
if (distance_mm >= 300){

displayColor(0, 255, 0);

}
if (300 > distance_mm and distance_mm >= 250){

displayColor(0, 200, 0);

}
if (250 > distance_mm and distance_mm >= 200){

displayColor(0, 100, 100);

}
if (200 > distance_mm and distance_mm >= 150){

displayColor(100, 100, 0);

}
if (150 > distance_mm and distance_mm >= 100){

displayColor(200, 0, 0);

}
if (distance_mm < 100){

displayColor(255, 0, 0);

}
}