This guide shows how to use the HC-SR04 Ultrasonic Sensor with the ESP8266 NodeMCU board using the Arduino core. The ultrasonic sensor uses sonar to determine the distance to an object. We’ll show you how to wire the sensor to the ESP8266 and provide several example sketches to determine the distance to an object using the HC-SR04.
This tutorial covers the following topics:
- Ultrasonic Sensor HC-SR04 Pinout
- Wiring the Ultrasonic Sensor HC-SR04 to the ESP8266
- Getting Distance to an Object Using the Ultrasonic Sensor HC-SR04 with the ESP8266
- Displaying the Distance to an Object on a Display Using the ESP8266 and HC-SR04
Introducing the HC-SR04 Ultrasonic Sensor
The HC-SR04 ultrasonic sensor uses sonar to determine the distance to an object. This sensor reads from 2cm to 400cm (0.8inch to 157inch) with an accuracy of 0.3cm (0.1inches), which is good for most hobbyist projects. In addition, this particular module comes with ultrasonic transmitter and receiver modules.
The following picture shows the HC-SR04 ultrasonic sensor.
The next picture shows the other side of the sensor.
Where to buy HC-SR04 Ultrasonic Sensor?
You can check the Ultrasonic Sensor HC-SR04 sensor on Maker Advisor to find the best price:
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 Work?
The ultrasonic sensor uses sonar to determine the distance to an object. Here’s how it works:
- The ultrasound transmitter (trig pin) emits a high-frequency sound (40 kHz).
- The sound travels through the air. If it finds an object, it bounces back to the module.
- The ultrasound receiver (echo pin) receives the reflected sound (echo).
Taking into account the sound’s velocity in the air and the travel time (time passed since the transmission and reception of the signal) we can calculate the distance to an object. Here’s the formula:
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
Parts Required
To complete this tutorial you need the following parts:
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic – ESP8266 NodeMCU with HC-SR04 Ultrasonic Sensor
Wire the HC-SR04 ultrasonic sensor to the ESP8266 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 | ESP8266 |
VCC | VIN |
Trig | GPIO 12 (D6) |
Echo | GPIO 14 (D5) |
GND | GND |
Preparing Arduino IDE
We’ll program the ESP8266 board using Arduino IDE. So, make sure you have the ESP8266 add-on installed. Follow the next tutorial:
If you want to use VS Code with the PlatformIO extension, follow the next tutorial instead to learn how to program the ESP8266:
Code – Getting Distance to an Object using the HC-SR04 Ultrasonic Sensor and ESP8266
The following sketch is a simple example of how you can get the distance between the sensor and an object using the ESP8266 board with the Arduino core.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-hc-sr04-ultrasonic-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
const int trigPin = 12;
const int echoPin = 14;
//define sound velocity in cm/uS
#define SOUND_VELOCITY 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_VELOCITY/2;
// Convert to inches
distanceInch = distanceCm * CM_TO_INCH;
// Prints the distance on 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 Works
First, define the trigger and the echo pins.
const int trigPin = 12;
const int echoPin = 14;
In this example, we’re using GPIO 12 and GPIO 14. But you can use any other suitable GPIOs—read ESP8266 Pinout Reference: Which GPIO pins should you use?
The SOUND_SPEED variable saves the velocity of sound in the air at 20ºC. We’re using the value in cm/uS.
#define SOUND_SPEED 0.034
The CM_TO_INCH variable allows us to convert distance in centimeters to inches.
#define CM_TO_INCH 0.393701
Then, initialize the following variables.
long duration;
float distanceCm;
float distanceInch;
The duration variable saves the travel time of the ultrasonic waves (time elapsed since transmission and reception of the pulse wave). The distanceCm and distanceInch, as the names suggest, save the distance to an object in centimeters and inches.
setup()
In the setup(), initialize a serial communication at a baud rate of 115200 so that we can print the 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. And define the echo pin as an INPUT—the echo pin receives the reflected wave and sends a signal to the ESP8266 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 following lines produce a 10uS HIGH pulse on the trigger pin—this means the pin will emit an ultrasound. Note that before sending the pulse, we give a short LOW pulse to ensure you’ll get 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);
We use the pulseIn() function to get the sound wave travel time:
duration = pulseIn(echoPin, HIGH);
The pulseIn() function reads a HIGH or a LOW pulse on a pin. It accepts as arguments the pin and the state of the pulse (either HIGH or LOW). It 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, we simply calculate the distance to an object taking into account the sound speed.
distanceCm = duration * SOUND_SPEED/2;
Convert the distance to inches:
distanceInch = distanceCm * CM_TO_INCH;
And 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. Don’t forget to select the board you’re using in Tools > Boards. Also, don’t forget to select the right COM port in Tools > Port.
After uploading, open the Serial Monitor at a baud rate of 115200. Press the on-board RST button to restart the board and it will start printing the distance to the closest object on the Serial Monitor. Something as shown in the picture below.
ESP8266 with HC-SR04 and OLED Display
This section will show you a simple example with the ESP8266 that displays the distance on an I2C OLED display.
To better understand how the project works, we recommend taking a look at our ESP8266 tutorial with the I2C OLED display.
Parts Required
Here’s a list with the parts required to complete this example:
- HC-SR04 Ultrasonic Sensor
- ESP8266 (read Best ESP8266 development boards)
- 0.96 inch I2C OLED Display SSD1306
- Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic Diagram – ESP8266 with HC-SR04 and OLED Display
Wire all the parts as shown in the following schematic diagram.
Learn more about the OLED display with the ESP8266: ESP8266 OLED Display with Arduino IDE
Code – ESP8266 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 through the Arduino Library Manager.
Go to Sketch > Library > Manage Libraries, search for “SSD1306,” and install the SSD1306 library from Adafruit.
After installing the SSD1306 library from Adafruit, type “GFX” in the search box and install the library.
After installing the libraries, restart your Arduino IDE.
Then, simply copy the following code to your Arduino IDE and upload the code to the board.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-hc-sr04-ultrasonic-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
#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 = 12;
const int echoPin = 14;
//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 = 12;
const int echoPin = 14;
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
Go to Tools > Board and select the ESP8266 board you’re using. Go to Tools > Port and select the port your board is connected to. Then, click the upload button.
Open the Serial Monitor at a baud rate of 115200, press the on-board RST button. The sensor measurements will be displayed both on the Serial Monitor and on the OLED display.
Move an object in front of the sensor and see the values changing.
You can watch a quick video demonstration:
Wrapping Up
The HC-SR04 Ultrasonic Sensor allows us to determine the distance to an object. In this tutorial you’ve learned how to use the HC-SR04 with the ESP8266. We have tutorials for other popular sensors that you may like:
- ESP8266 with DHT11/DHT22 Temperature and Humidity Sensor using Arduino IDE
- ESP8266 with BME280 using Arduino IDE (Pressure, Temperature, Humidity)
- ESP8266 with BME680 Environmental Sensor using Arduino IDE (Gas, Pressure, Humidity, Temperature)
- ESP8266 DS18B20 Temperature Sensor with Arduino IDE (Single, Multiple, Web Server)
Learn more about the ESP8266 with our resources:
- Home Automation Using ESP8266
- Build Web Servers with ESP32 and ESP8266 eBook (2nd Edition)
- More ESP8266 Projects and Tutorials…
Thanks for reading.
While I’ve seen several iterations of folks using 5V to power the HC SR04 and drive the input to the ESP (xx) without conditioning, I am reluctant to do so. Further I have tried operating the sensor at the 3.3V level as well as others have, but find the readings to be somewhat “random”, (no pun intended Rui 🙂 ) . It seems adding a logic level converter would be the answer, but those usually come in a x4 module. If space and current are not issues, no problem there. If you are trying to use battery power and wish the batteries to last a bit longer eliminating as many active components as posible would be paramount. There is a modification of the sensor posted on instructables, that basically places a voltage divider on the sensors using 2 resistors. If you’re not good at soldering, You may want to look into the US 100 sensor offered by several vendors. I might also add that some of the newer HC SR-04 sensors may operate better at 3.3v than my older ones.
Thanks for sharing.
Other readers have also suggested using a voltage divider with two resistors.
Regards,
Sara
Hello,
I am doing this project I have some problem with programming please reply me.
What’s the power supply voltage to drive this whole circuit? Would it be possible to use 4 sonars on one Arduino Uno and using only one ESP8266 for wifi data transmission?
can i replace with JSN-SR04T?
Thanks for this tutorial.
after many trials, it didn’t work until I connect the VCC of the ultrasonic sensor to the VU pin, not the Vin pin, without doing that the HC-SR04 always showed the value of 0
Thank for this tutorial.
This device is like the HC-SR04, but it is waterproof. I noticed that extending the trigger pulse to 15uS is more precise and stable. I also ran the test on the hc-sr04, I must say that it works better.
Bye!
Sorry, I use JSN-HC04.
I forgot to mention this at the beginning of the post.