Search

Distance Measurement with ESP32: HC-SR04 Ultrasonic Sensor Guide

This tutorial illustrates how to use the HC-SR04 Ultrasonic Sensor with the ESP32 board using the Arduino core. The sensor employs sonar technology to determine the distance to an object. We will walk you through the steps of connecting the sensor to the ESP32 and provide several example sketches for measuring the distance to an object with the HC-SR04.

HC-SR04 Ultrasonic Sensor Overview

The HC-SR04 ultrasonic sensor utilizes sonar for distance measurement to an object. It can measure distances ranging from 2cm to 400cm (0.8inch to 157inch) with an accuracy of 0.3cm (0.1inches), making it suitable for various hobbyist projects. Additionally, this module includes ultrasonic transmitter and receiver modules.

The image below illustrates the HC-SR04 ultrasonic sensor.

The subsequent image reveals the reverse side of the sensor.

HC-SR04 Ultrasonic Sensor Technical Data

The following table shows the key features and specs of the HC-SR04 ultrasonic sensor. For more information, you should consult the sensor’s datasheet.

Power Supply5V DC
Working Current15 mA
Working Frequency40 kHz
Maximum Range4 meters
Minimum Range2 cm
Measuring Angle15º
Resolution0.3 cm
Trigger Input Signal10uS TTL pulse
Echo Output SignalTTL pulse proportional to the distance range
Dimensions45mm x 20mm x 15mm

HC-SR04 Ultrasonic Sensor Pinout

Here’s the pinout of the HC-SR04 Ultrasonic Sensor.

VCCPowers the sensor (5V)
TrigTrigger Input Pin
EchoEcho Output Pin
GNDCommon GND

How Does the HC-SR04 Ultrasonic Sensor Operate?

The ultrasonic sensor employs sonar technology to determine the distance to an object. Here’s a breakdown of its functioning:

  1. The ultrasound transmitter (trig pin) emits a high-frequency sound (40 kHz).
  2. The emitted sound travels through the air, and if it encounters an object, it reflects back to the module.
  3. The ultrasound receiver (echo pin) picks up the reflected sound (echo).

By considering the speed of sound in the air and the time it takes for the signal to travel (elapsed time since transmission and reception), we can calculate the distance to an object. The formula for this calculation is as follows:

distance to an object = ((speed of sound in the air)*time)/2
  • speed of sound in the air at 20ºC (68ºF) = 343m/s

Schematic – ESP32 with HC-SR04 Ultrasonic Sensor

Wire the HC-SR04 ultrasonic sensor to the ESP32 as shown in the following schematic diagram. We’re connecting the Trig pin to GPIO 5 and the Echo pin to GPIO 18, but you can use any other suitable pins.

Ultrasonic SensorESP32
VCCVIN
TrigGPIO 5
EchoGPIO 18
GNDGND

Code – Getting Distance to an Object using the HC-SR04 Ultrasonic Sensor and ESP32

The following sketch is a simple example of how you can get the distance between the sensor and an object using the ESP32 board with the Arduino core.

const int trigPin = 5;
const int echoPin = 18;

//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
float distanceCm;
float distanceInch;

void setup() {
  Serial.begin(115200); // Starts the serial communication
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance
  distanceCm = duration * SOUND_SPEED/2;
  
  // Convert to inches
  distanceInch = distanceCm * CM_TO_INCH;
  
  // Prints the distance in the Serial Monitor
  Serial.print("Distance (cm): ");
  Serial.println(distanceCm);
  Serial.print("Distance (inch): ");
  Serial.println(distanceInch);
  
  delay(1000);
}

Upload the code to your board and it will work straight away. Continue reading if you want to learn how the code works or skip to the demonstration section.

How the Code Operates

To begin, define the trigger and echo pins:

const int trigPin = 5;
const int echoPin = 18;

In this instance, we are using GPIO 5 and GPIO 18. However, you can choose any other suitable GPIOs—refer to the ESP32 Pinout Reference: Which GPIO pins should you use?

The SOUND_SPEED variable stores the velocity of sound in the air at 20ºC, with the value expressed in cm/uS.

#define SOUND_SPEED 0.034

The CM_TO_INCH variable facilitates the conversion of distance from centimeters to inches.

#define CM_TO_INCH 0.393701

Subsequently, initialize the following variables:

long duration;
float distanceCm;
float distanceInch;

The duration variable records the travel time of the ultrasonic waves (time elapsed since transmission and reception of the pulse wave). The distanceCm and distanceInch variables, as their names imply, store the distance to an object in centimeters and inches.

setup()

In the setup(), initiate serial communication at a baud rate of 115200 to enable the printing of measurements on the Serial Monitor.

Serial.begin(115200); // Starts the serial communication

Define the trigger pin as an OUTPUT—the trigger pin emits the ultrasound. Define the echo pin as an INPUT—the echo pin receives the reflected wave and sends a signal to the ESP32 that is proportional to the travel time.

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input

loop()

In the loop(), the subsequent lines generate a 10uS HIGH pulse on the trigger pin—indicating that the pin will emit an ultrasound. Note that before sending the pulse, a brief LOW pulse is given to ensure a clean HIGH pulse.

// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

The pulseIn() function is employed to retrieve the sound wave travel time:

duration = pulseIn(echoPin, HIGH);
The pulseIn() function reads a HIGH or LOW pulse on a pin. It accepts the pin and the state of the pulse (either HIGH or LOW) as arguments and returns the length of the pulse in microseconds. The pulse length corresponds to the time it took to travel to the object plus the time traveled on the way back.

Then, the distance to an object is calculated, considering the sound speed:

distanceCm = duration * SOUND_SPEED/2;

Convert the distance to inches:

distanceInch = distanceCm * CM_TO_INCH;

Finally, print the results on the Serial Monitor:

Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceInch);

Demonstration

Upload the code to your board. Ensure that you choose the appropriate board in Tools > Boards. Additionally, select the correct COM port in Tools > Port.

Once the code is uploaded, open the Serial Monitor with a baud rate of 115200. Press the on-board RST button to restart the board, and it will commence printing the distance to the nearest object on the Serial Monitor. You should observe an output similar to the image depicted below.

ESP32 with HC-SR04 and OLED Display

In this section, we provide a straightforward example featuring the ESP32, demonstrating the presentation of distance on an I2C OLED display.

For a more comprehensive understanding of how the project functions, we recommend referring to our ESP32 tutorial involving the I2C OLED display.

Schematic Diagram – ESP32 with HC-SR04 and OLED Display

Connect all the components according to the schematic diagram given below.

Code – ESP32 Display Distance (HC-SR04) on OLED Display

To use this example, make sure you have the Adafruit SSD1306 and Adafruit GFX libraries installed. You can install these libraries using the Arduino Library Manager.

Navigate to Sketch > Library > Manage Libraries, search for “SSD1306,” and install the SSD1306 library from Adafruit.

After installing the Adafruit SSD1306 library, type “GFX” in the search box and install the library.

Once the libraries are installed, restart your Arduino IDE.

Then, simply copy the following code into your Arduino IDE and upload it to the board.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

const int trigPin = 5;
const int echoPin = 18;

//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
int distanceCm;
int distanceInch;

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(500);
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
}

void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance
  distanceCm = duration * SOUND_SPEED/2;
  
  // Convert to inches
  distanceInch = distanceCm * CM_TO_INCH;
  
  // Prints the distance in the Serial Monitor
  Serial.print("Distance (cm): ");
  Serial.println(distanceCm);
  Serial.print("Distance (inch): ");
  Serial.println(distanceInch);

  display.clearDisplay();
  display.setCursor(0, 25);
  //Display distance in cm
  display.print(distanceCm);
  display.print(" cm");
  
  // Display distance in inches
  /* display.print(distanceInch);
  display.print(" in");*/
  display.display(); 

  delay(500);  
}

How the Code Works

Start by including the required libraries for the OLED display:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Define the width and height of the OLED display. We’re using a 128×64 OLED display:

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Create an Adafruit_SSD1306 object called display to handle the OLED display.

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

Define the pins that the HC-SR04 sensor is connected to.

const int trigPin = 5;
const int echoPin = 18;

Create variables to save the distance and the duration between the transmission and reception of the sound waves.

long duration;
int distanceCm;
int distanceInch;

setup()

In the setup(), initialize a serial communication at a baud rate of 115200 so that we can print the results on the Serial Monitor.

Serial.begin(115200);

Define the trigger pin as an OUTPUT and the echo pin as an INPUT.

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input

Initialize the OLED display:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
}

Set the font size and color for the display.

display.setTextSize(2);
display.setTextColor(WHITE);

loop()

In the loop() is where we’ll get the distance and display it on the OLED.

Get the distance (we’ve already explained in the previous section how to calculate the distance).

// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
  
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
  
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
  
// Convert to inches
distanceInch = distanceCm * CM_TO_INCH;

Print the distance on the Serial Monitor.

// Prints the distance on the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceInch);

Clear the display in each loop() to write new readings.

display.clearDisplay();

Set the display cursor to (0, 25).

display.setCursor(0, 25);

The following lines print the distance in centimeters in the OLED display.

// Display static text
display.print(distanceCm);
display.print(" cm");

Comment the previous lines and uncomment the following lines if you want to display the readings in inches.

/* Display distance in inches
display.print(distanceInch);
display.print(" in");*/

Lastly, call display.display() to actually show the readings on the OLED.

display.display();

The distance is updated every 500 milliseconds.

delay(500);

Demonstration

Upload the code to your ESP32 board. Navigate to Tools > Board and choose the specific ESP32 board you are using. Then, go to Tools > Port and select the port to which your board is connected. Finally, click the upload button.

Open the Serial Monitor with a baud rate of 115200, and press the on-board RST button. The sensor measurements will be visible on both the Serial Monitor and the OLED display.

Bring an object close to the sensor and observe the changing values.

Related article

Leave a Comment