Ultrasonic hc-sr04 Sensor Interfacing with ESP32

Overview of Ultrasonic Sensor

 

Ultrasonic HC-SR 04 Sensor
  • Ultrasonic Module HC-SR04 works on the principle of SONAR and RADAR systems. It can be used to determine the distance of an object in the range of 2 cm – 400 cm.

 

HC-SR04 Ultrasonic Sensor Pinout

Pin details of ultrasonic Sensor

 

Pin description and specification:

  • VCC: It operated on +5V DC
  • GND: Connect to the ground
  • Trig: Trigger as an input Pin
  • Echo: Echo Pin as an output pin
  • Working current: 15mA
  • Ranging Distance: 2-­400 cm
  • Measuring Angle: 30º
  • Trigger Input Pulse width: 10uS

 

Ultrasonic Module HC-SR04 Operation:

  1. Provide a minimum 10µsec pulse to trigger the pin.
  2. This will generate & transmit 8 pulses of 40 kHz and makes the Echo pin high. 
  3. The echo pin remains high till it gets the echo signal on the receiver. i.e., the 40Hz transmitted signal gets reflected back by the obstacle. The same will be received by the receiver.
  4. The time for which the echo pin remains high, i.e., the width of the Echo pin gives the time taken for generated ultrasonic sound to travel to the object and back.
  5. Using this time and the speed of sound in air, we can find the distance of the object using a simple formula for distance using speed and time.

For more information about the ultrasonic module HC-SR04 and how to use it, refer to the topic Ultrasonic Module HC-SR04 in the sensors and modules section.

 

Connection Diagram of HC-SR04 Ultrasonic Sensor with ESP32

Ultrasonic HC-SR04 interfacing with ESP32

 

 

Measuring Distance Using ESP32 and Ultrasonic Sensor

Let’s interface the Ultrasonic sensor to ESP32 and display the distance in CM and Inch on the serial monitor.

In this application, we are using the Ping example that comes with Arduino IDE in the Sensors library.

You can find this example in –

 

Here we have modified the below example as per the above interfacing diagram connection.

HC-SR04 Ultrasonic Sensor Code for ESP32

/*
  Ping))) Sensor

  This sketch reads a PING))) ultrasonic rangefinder and returns the distance
  to the closest object in range. To do this, it sends a pulse to the sensor to
  initiate a reading, then listens for a pulse to return. The length of the
  returning pulse is proportional to the distance of the object from the sensor.

  The circuit:
      - +V connection of the PING))) attached to +5V
      - GND connection of the PING))) attached to ground
      - SIG connection of the PING))) attached to digital pin 7

  created 3 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

 https://www.arduino.cc/en/Tutorial/BuiltInExamples/Ping
*/

// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 14;

void setup() {
  // initialize serial communication:
  Serial.begin(115200);
}

void loop() {
  // establish variables for duration of the ping, and the distance result
  // in inches and centimeters:
  long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH pulse
  // whose duration is the time (in microseconds) from the sending of the ping
  // to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}

long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are 73.746
  // microseconds per inch (i.e. sound travels at 1130 feet per second).
  // This gives the distance travelled by the ping, outbound and return,
  // so we divide by 2 to get the distance of the obstacle.
  // See: https://www.parallax.com/package/ping-ultrasonic-distance-sensor-downloads/
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the object we
  // take half of the distance travelled.
  return microseconds / 29 / 2;
}

 

  • Now upload the code. (While uploading the code make sure your ESP32 board is in the boot mode.)
  • After uploading the code open the serial monitor and set the baud rate to 115200 to see the output.

 

ESP32 Serial Output for Ultrasonic Sensor

 

Let’s Understand the code

Set the GPIO pin 14 as input-output for trig and the echo of the ultrasonic sensor.

const int pingPin = 14;

 

In Setup function

We have initiated the serial communication with a 115200 Baud rate.

void setup(void){
  Serial.begin(115200);
}

 

In loop function

Define the variable for duration, inches, and cm.

long duration, inches, cm;

Defined the pingPin as OUTPUT and triggered by a HIGH pulse of 2 or more microseconds and give a short LOW pulse beforehand to ensure a clean HIGH pulse:

pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);

The same pin is used to read the signal from the PING. 

pinMode(pingPin, INPUT);

Read the pulse HIGH pulse whose duration is a time in microseconds.

duration = pulseIn(pingPin, HIGH);

Convert the time into a distance

cm = microsecondsToCentimeters(duration); 
inches = microsecondsToInches(duration);

According to datasheet for the PING, there are 73.746 microseconds per inch (i.e. sound travels at 1130 feet per second). This gives the distance travelled by the ping, outbound, and return, so we divide by 2 to get the distance of the obstacle.

long microsecondsToInches(long microseconds) {
  return microseconds / 74 / 2;
}

The speed of sound is 340 m/s or 29 microseconds per centimetre. The ping travels out and back, so to find the distance of the object we take half of the distance travelled.

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

 

Ultrasonic Distance Measurement over ESP32 Web Server

Let’s interface the Ultrasonic sensor to ESP32 and display the distance in CM and Inch on the web server as well as on the serial monitor.

Before uploading the code make sure you have added your SSID and Password as follows.

const char* ssid = "*Your SSID*";         /*Enter Your SSID*/
const char* password = "*Your Password*"; /*Enter Your Password*/

 

Ultrasonic Sensor WebServer Code for ESP32

/*
  ESP32 Ultrasonic HC-Sr04 WebServer Code 
  http:://www.electronicwings.com
*/

#include <WiFi.h>
#include <WebServer.h>
#include "html.h"

WebServer server(80);

const char* ssid = "*Your SSID*";         /*Enter Your SSID*/
const char* password = "*Your Password*"; /*Enter Your Password*/

const int pingPin = 14;
long duration, inches, cm;

void MainPage() {
  String _html_page = html_page;              /*Read The HTML Page*/
  server.send(200, "text/html", _html_page);  /*Send the code to the web server*/
}

void Distance() {
  String data = "[\""+String(cm)+"\",\""+String(inches)+"\"]";
  server.send(200, "text/plane", data);
}

void setup(void){
  Serial.begin(115200);                 /*Set the baudrate to 115200*/
  WiFi.mode(WIFI_STA);                  /*Set the WiFi in STA Mode*/
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  delay(1000);                         /*Wait for 1000mS*/
  while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");} /*Wait while connecting to WiFi*/
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("Your Local IP address is: ");
  Serial.println(WiFi.localIP());       /*Print the Local IP*/

  server.on("/", MainPage);             /*Display the Web/HTML Page*/
  server.on("/readDistance", Distance); /*Display the updated Distance value(CM and INCH)*/
  server.begin();                      /*Start Server*/
  delay(1000);                         /*Wait for 1000mS*/
}

void loop(void){
  pinMode(pingPin, OUTPUT);             /*Define pingPin as a output*/
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);                 /*Wait for 2uS*/
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);                 /*Wait for 5uS*/
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);              /*Define pingPin as a input*/
  duration = pulseIn(pingPin, HIGH);    /*Reads a pulse HIGH on a pingPin*/
 
  cm = microsecondsToCentimeters(duration); /*Convert the time into cm*/
  inches = microsecondsToInches(duration);  /*Convert the time into inch*/
 
  server.handleClient();
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  delay(1000);
}

long microsecondsToInches(long microseconds) {return microseconds / 74 / 2;}
long microsecondsToCentimeters(long microseconds) {return microseconds / 29 / 2;}

 

  • Now upload the code. (While uploading the code make sure your ESP32 board is in the boot mode.)
  • After uploading the code open the serial monitor and set the baud rate to 115200 then reset the ESP32 board and check the IP address as shown in the below image

 

 

  • Now open any mobile browser and type the IP address which is shown in the serial monitor and hit the enter button. 
  • If all are ok, then the web page will start the showing current distance in cm and inch on the web server like in the below image.

Note: make sure your ESP32 and mobile are connected to the same router/server, if they are connected to the same router or server then only you will be able to visible the web page.

Final Output on the webserver

 

Let’s Understand the code

To understand this code, please refer the basics guide of “How to create the ESP32 Server”.

Once you get the basics of ESP32 server creation, it will be very simple to understand the code.

This code starts with important header files and libraries, In WiFi.h file contains all ESP32 WiFi related definitions, here we have used them for network connection purposes. 

The WebServer.h file supports handling the HTTP GET and POST requests as well as setting up a server. In the html.h file contains all the web page code.

#include <WiFi.h>
#include <WebServer.h>
#include "html.h"

Let’s define HTTP port i.e., Port 80 as follows

WebServer server(80);

Set the ultrasonic pin number and define the duration and inches as long values.

const int pingPin = 14;
long duration, inches, cm;

 

Setup Function

In setup function, first we set the WiFi as an STA mode and connect to the given SSID and password

WiFi.mode(WIFI_STA);          /*Set the WiFi in STA Mode*/
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
delay(1000);                  /*Wait for 1000mS*/
while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");}

After successfully connecting to the server print the local IP address on the serial window.

Serial.print("Your Local IP address is: ");
Serial.println(WiFi.localIP());     /*Print the Local IP*/

 

Handling Client Requests and Serving the Page

To handle the client request, we use server.on() function.

It takes two parameters, The first is requested URL path, and the second is the function name, which we want to execute.

As per the below code, when a client requests the root (/) path, the “MainPage()” function executes. 

Also, when a client requests the “/readDHT” path, The DHT_Data() function will be called.

server.on("/", MainPage);           /*Client request handling: calls the function to serve HTML page */
server.on("/readDistance", Distance); /*Display the updated Distance value(CM and INCH)*/

Now start the server using server.begin() function.

server.begin();                     /*Start Server*/

 

Functions for Serving HTML

We have defined the complete HTML page in file named “html.h” and added it in header file. With following function, we are sending complete page to client via server.send() function.

While sending, we are passing the first parameter “200” which is status response code as OK (Standard response for successful HTTP requests). 

Second parameter is content type as “text/html“, and third parameter is html page code.

void MainPage() {
  String _html_page = html_page;              /*Read The HTML Page*/
  server.send(200, "text/html", _html_page);  /*Send HTM page to Client*/
}

Now in the below function only we are sending the updated distance to the web page.

void Distance() {
  String data = "[\""+String(cm)+"\",\""+String(inches)+"\"]";
  server.send(200, "text/plane", data);
}

 

Loop Function

Now to handle the incoming client requests and serve the relevant HTML page, we can use handleClient() function. It executing relevant server.on() as a callback function although it is defined in void setup()

So, it continuously serves the client requests.

server.handleClient();

 

HTML Web Page Code

This is a code for the web page that shows the measured distance using an ultrasonic sensor and ESP32.

/*
  ESP32 Ultrasonic HC-Sr04 HTML WebServer Code 
  http:://www.electronicwings.com
*/

const char html_page[] PROGMEM = R"RawString(
<!DOCTYPE html>
<html>
  <style>
    body {font-family: sans-serif;}
    h1 {text-align: center; font-size: 30px;}
    p {text-align: center; color: #4CAF50; font-size: 40px;}
  </style>

<body>
  <h1>Ultrasonic HC-SR 04 Distance Measurement</h1><br>
  <p>Distance in CM : <span id="_CM">0</span> CM</p>
  <p>Distance in Inch : <span id="_INCH">0</span> Inch</p>

<script>
  setInterval(function() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        const text = this.responseText;
        const myArr = JSON.parse(text);
       document.getElementById("_CM").innerHTML = myArr[0];
        document.getElementById("_INCH").innerHTML = myArr[1];
      }
    };
    xhttp.open("GET", "readDistance", true);
    xhttp.send();
  },50);
</script>
</body>
</html>
)RawString";

 

Let’s understand the code step by step

All html pages start with the <!DOCTYPE html> declaration, it is just information to the browser about what type of document is expected.

<!DOCTYPE html>

The html tag is the container of the complete html page which represents on the top of the html code.

<html>

Now here we are defining the style information for a web page using the <style> tag. Inside the style tag we have defined the font name, size, color, and test alignment. 

  <style>
    body {font-family: sans-serif;}
    h1 {text-align: center; font-size: 30px;}
    p {text-align: center; color: #4CAF50; font-size: 40px;}
  </style>

 

Inside the body, we are defining the document body, in below we have used headings, and paragraphs if you want you can add images, hyperlinks, tables, lists, etc. also.

In the heading of the page, we are displaying the heading of the page, and inside a paragraph centimeter, and inch values. 

Now centimeter and inch values updates under the span id which is manipulated with JavaScript using the id attribute.

<body>
<h1>Ultrasonic HC-SR 04 Distance Measurement</h1><br>
  <p>Distance in CM : <span id="_CM">0</span> CM</p>
  <p>Distance in Inch : <span id="_INCH">0</span> Inch</p>

Now, this is the javascript that comes under the <script> tag, this is also called a client-side script.

<script>

 

In setInterval() method we are calling the function at every 50mS intervals.

setInterval(function() {},50);

Here we are creating the html XMLHttpRequest object

var xhttp = new XMLHttpRequest();

The xhttp.onreadystatechange event is triggered every time the readyState changes and the readyState holds the status of the XMLHttpRequest.

Now in the below code, the ready state is 4 means the request finished and response is ready and the status is 200 which means OK.

xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const myArr = JSON.parse(this.responseText);

 

Now here is the main thing, we are updating the centimeter and inch values in html page using _CM and _INCH id.

document.getElementById("_CM").innerHTML = myArr[0];
document.getElementById("_INCH").innerHTML = myArr[1];

Here we used the AJAX method to send the updated values to the server without refreshing the page.

In the below function we have used the GET method and sent the readDistance function which we defined in the main code asynchronously. 

xhttp.open("GET", "readDistance", true);

Send the request to the server using xhttp.send(); function.

xhttp.send();

 

Close the script

</script>

Close the body

</body>

Close the html.

</html>

Components Used

Ultrasonic Module HC-SR04
Ultrasonic module HC-SR04 is generally used for finding distance value and obstacle detection. It can operate in the range 2cm-400cm.
1
ESP32 WROOM
WiFi Development Tools - 802.11 ESP32 General Development Kit, embeds ESP32-WROOM-32E, 4MB flash.
1

Downloads

ESP32_Ultrasonic_Serial Download
ESP32_Ultrasonic_WebServer Download
Ad