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 Supply | 5V DC |
Working Current | 15 mA |
Working Frequency | 40 kHz |
Maximum Range | 4 meters |
Minimum Range | 2 cm |
Measuring Angle | 15º |
Resolution | 0.3 cm |
Trigger Input Signal | 10uS TTL pulse |
Echo Output Signal | TTL pulse proportional to the distance range |
Dimensions | 45mm x 20mm x 15mm |
HC-SR04 Ultrasonic Sensor Pinout
Here’s the pinout of the HC-SR04 Ultrasonic Sensor.
VCC | Powers the sensor (5V) |
Trig | Trigger Input Pin |
Echo | Echo Output Pin |
GND | Common 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:
- The ultrasound transmitter (trig pin) emits a high-frequency sound (40 kHz).
- The emitted sound travels through the air, and if it encounters an object, it reflects back to the module.
- 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 Sensor | ESP32 |
VCC | VIN |
Trig | GPIO 5 |
Echo | GPIO 18 |
GND | GND |
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);
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.
Parts Required
Component Name | Buy Now |
ESP32-WROOM-32 Development | Amazon |
Ultrasonic Sensor Module HC-SR04 | Amazon |
0.96 Inch OLED I2C IIC Display Module | Amazon |
Breadboard | Amazon |
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
- Effortless LED Control: ESP32 and WLED Setup Tips
- ESP32 Web Server Tutorial: PWM LED Brightness Control Slider
- ESP32 Capacitive Touch Pins: Basics for Interactive Projects
- Essential ESP32 ADC Basics: Analog-to-Digital Converter Explained
- ESP32 Essentials: Exploring the Power of Bluetooth Classic
- Mastering Light Sensing: ESP32 and BH1750 Integration Guide