HC-SR04 with Arduino | Interfacing Tutorial

Hey guys, I’m back with HC-SR04 with Arduino, another interesting article in the current Arduino Series. HC-SR04 is one of the most commonly used sensors in many projects. This sensor is very easy to use, such that even beginners can take their hands on it for practice. Although this sensor is quite popular, it does have some drawbacks like range and other factors. All these are mentioned further in the article. Moreover, it can be used with almost all microcontrollers available in the market. So without wasting time, let’s begin.

HC-SR04 and Arduino in brief

HC-SR04

Ultrasonic sensors are one of the important sensors in robotics. These can be used easily in projects like Obstacle avoiding Robot, Radar, Blind Stick, etc. HC-SR04 is one such sensor that does its job flawlessly, including some limitations to its use. This sensor uses the principle of reflection of sound also known as ECHO.

Ultrasonic sensors calculate the distance based on the time the sound pulse takes to return. There are two speakers-like objects that are present on the front side of the sensor. These two transmit and receive the Ultrasonic sound waves each. One of which is controlled by its driver IC that sends the pulses of sound waves at regular intervals.

This driver receives the signal from the onboard 8-Bit Microprocessor that controls the driver and reads the timing of the waves it takes to return. The sensor works on the overall frequency of 27Mhz, whereas the sound frequency used is 40kHz, which is inaudible to human ears.

Although this sensor seems promising, it has some limitations. First, this sensor can only measure a distance of about 400 cm. Moreover, the Arduino library for this needs to be edited beforehand to use this sensor at its full potential. However, the board is compatible with a 5V logic level. Hence, you can use it with all microcontrollers.

Arduino UNO

Arduino UNO is one of the most common development boards that is recommended for beginners. This board is built out of ATEGA328PU, which is an AVR-based 8-Bit CMOS Microcontroller. This microcontroller comes in a DIP-28 package that makes it easy to replace in cases of some damage to the IC. Moreover, you can also program multiple ICs just by swapping them on the board.

The board works on the frequency of 16MHz, which is kind of slow compared to ESP32 and NodeMCU boards. Therefore, this board is available at a cheap price but offers quite decent specs. Moreover, the repairability of UNO boards is maximum as compared to most Arduino Boards, as the essential components are mostly easy to solder by hand.

ATMEGA328PU comes with 2 KB of SRAM, which is enough for most of the programs. But keep in mind, you need to program code carefully so that it occupies less space. Along with this, it is paired with 32 KB of programmable flash memory, you can add more SPI flash as per your choice. Lastly, it also provides 1 KB EEPROM, which is a big plus point for a microcontroller at such a price point.

There are a total of 23 I/O pins available on the Arduino UNO Board. This includes 13 digital pins, 6 Analog Pins, and a few other pins for other uses. The Analog pins have a 10-bit of resolution, which is good for most analog operations. There are also 6 PWM pins that are included in 13 Digital pins, also the Serial communication is supported within Digital pins. The I2C communication is provided on A4 & A5 pins, which lie under Analog pins.

Material Required

  • Arduino UNO
  • HC-SR04
  • Breadboard
  • Jumper Wires
  • A system to program Arduino UNO

Fritzing Schematic

HC-SR04 with Aduino

Wiring

Arduino UNOHC-SR04
5VVcc
GNDGND
D3TRIG
D4ECHO

Programming Arduino

We have come this far in HC-SR04 with the Arduino UNO demonstration. To Program Arduino UNO, you should make sure to make some checks before proceeding. Make sure you have downloaded the Arduino IDE or if you have previously downloaded it, then update it to the latest version. Along with this, make sure to download and update all the board definitions and library. If you can’t understand what I stated above, then make sure to read Arduino Introductory article. In this, I have explained all the details regarding Arduino IDE, including an example sketch for Blink LED. Now let’s proceed further for more understanding.

Installing Library

This part is completely optional however, to simplify the code I’d recommend it. You can write the code without needing a library, but this will simplify your code. In addition to this, there are plenty of libraries available for the HC-SR04 Ultrasonic sensor. You can use any one of them as per your choice, but the recommended one can be found here. I was not able to find this library in the inbuilt Library manager in Arduino IDE. Therefore, you need to manually download and install the library

Above is the reference image for installing the library, you can do this from the Sketch menu, Sketch > Include Library > Add ZIP Library. However, you still need to edit the library for the sensor to work at its full potential. Editing the library will be explained in further sections. For now, let’s proceed toward the code section.

Code

This is an important section where I’ll be providing code for the demonstration. The code given below is based on the library I mentioned above. Therefore, you need to install the library however, the code without the library will be updated upon request.

#include <Ultrasonic.h>

Ultrasonic ultrasonic(3,4); // (Trig PIN,Echo PIN)

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

void loop()
{
  Serial.print(ultrasonic.Ranging(CM)); // CM or INC
  Serial.println(" cm" );
  delay(100);
}

You need to save the code so that you can edit it later. However, you need to give it a meaningful name, so save it with “HCSR04_Arduino.ino”. Surely you can give this the name you want. If you want to know more about the HC-SR04 Ultrasonic sensor, then read it from here.

Explanation

This is the most important part of the article. Here, I’ll explain the code line by line so that you can edit the code or write a new code yourself according to your need. Before that, make sure you have completed all the steps mentioned above. Along with this, the code is based on the library which is provided above. Also, the library is edited, that’ll be explained in the next part. Let’s start with the explanation part.

#include <Ultrasonic.h>

In the first line, we import the library that is used to compile the code. Although this library is used only to simplify and minify the code. It is recommended to use the library and other files, as further deep into this field you meet with complex and long codes that can be troublesome to understand. So in order to use fewer lines of code, we use a library.

This library can be different and totally depends on the one you installed, therefore it is always advised to visit the GitHub page of the downloaded library for more information about its functions and usage instructions.

Ultrasonic ultrasonic(3,4); // (Trig PIN,Echo PIN)

In the next line, we create an object or variable that points to the Ultrasonic sensor we have connected to the defined pins. You can use any of the pins, but it is recommended to use these two, as those pins have a higher frequency than other PWM pins on the Arduino UNO. I have already added the comment to the line that corresponds to the pin definition so that you can connect the correct pin of the sensor to Arduino.

The syntax of the line is like Ultrasonic <variable>(Trig Pin, Echo Pin);. You can give some other variable names, but for understanding purposes, I have used ultrasonic here.

void setup()

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

Next comes the void setup loop, here we write code that needs to be executed once during the whole program cycle. As we don’t have enough lines of code, so we don’t need anything else than starting a serial communication between Arduino UNO and the system. For this you can choose any baud rate, the default one being 9600.

If you are using the simple code without any inclusion of a library, then you have to define the pinMode in this section, but that comes as an optional part. The simple code is not mentioned in the discussion, if you require it, just comment below and I’ll update that part.

void loop()

void loop()
{
  Serial.print(ultrasonic.Ranging(CM)); // CM or INC
  Serial.println(" cm" );
  delay(100);
}

Here comes the main loop of the code, lines written within this section run repeatedly. Make sure to write only lines that are necessary like excessive delay or unwanted delay can result in the program malfunctioning and that is not advised. With this, let’s start the last part of the code. From the first line, we print the distance from the function from the library.

If you are from a programming background, then you might understand the first line. However, for those who don’t know, I’ll explain it here. To get the distance from the sensor you just need to write a line and store it in the variable like in the example below.

int x = ultrasonic.Ranging(CM);
//int <variable> = <variable(ultrasonic sensor)>.Ranging(CM);

Then w can print the value of x, however by writing the line as in the code we save a bit of storage of the chip, but the work of both methods is the same. Here, CM & IN indicates the unit in which we want to measure the distance. CM refers to the centimeter and IN refers to the inch.

At last, we give some delay to print the distance, else the output will be messy and unable to be understood. In the further section, I’ll be discussing some extra points related to code and errors in value, along with how to edit the library.

Errors in the distance estimation

There can be a situation where the actual distance is different from the one the sensor gives. This is because the speed of sound depends on several other factors. These factors are Temperature & Humidity, you need to know the temperature and humidity of your area to find the actual speed of the sound.

Based on this, you can calculate the correct distance. I have personally tried this and this resulted in highly accurate, but you need to use either a DHT11 sensor to measure both or know the correct values of temperature and humidity. For how to use DHT11 with Arduino, you can read the article mentioned here.

However, you still need to edit the library, but for this purpose specifically, you need to edit the whole library which makes it strictly to use with DHT11. On the other hand, in the below section, there is only instruction on how to remove the limit distance measure from the library.

Editing Library

First, to edit the library, you need to locate the library for its location. For this, the most obvious location is the Documents folder. Goto \\Documents/Arduino/Libraries, here you can find all the additional libraries that you have installed so far. Also in the \\Documents/Arduino, Folder, you will find folders to all the code that you have written so far.

Next from all the library folders find the Ultrasonic Folder that contains the Ultrasonic library. As in the above image, you can see clearly a Folder named, Ultrasonic. In this folder, we need to edit the files. Once you open the folder, you can see the files like in the below image. We need to edit the file with extension .cpp.

// Ultrasonic - Library for HR-SC04 Ultrasonic Ranging Module.
// GitHub: https://github.com/JRodrigoTech/Ultrasonic-HC-SR04
// #### LICENSE ####
// This code is licensed under Creative Commons Share alike 
// and Attribution by J.Rodrigo ( http://www.jrodrigo.net ).

#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

#include "Ultrasonic.h"

Ultrasonic::Ultrasonic(int TP, int EP)
{
   pinMode(TP,OUTPUT);
   pinMode(EP,INPUT);
   Trig_pin=TP;
   Echo_pin=EP;
   //Time_out=3000;  // 3000 µs = 50cm // 30000 µs = 5 m Comment out this line
}

Ultrasonic::Ultrasonic(int TP, int EP, long TO)
{
   pinMode(TP,OUTPUT);
   pinMode(EP,INPUT);
   Trig_pin=TP;
   Echo_pin=EP;
   Time_out=TO;
}

long Ultrasonic::Timing()
{
  digitalWrite(Trig_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);
  duration = pulseIn(Echo_pin,HIGH,Time_out);
////////////////////////Comment out this portion///////////////////
  /*if ( duration == 0 ) {
	duration = Time_out; }*/
  return duration;
}

long Ultrasonic::Ranging(int sys)
{
  Timing();
  if (sys) {
	distance_cm = duration /29 / 2 ;
	return distance_cm;
  } else {
	distance_inc = duration / 74 / 2;
	return distance_inc; }
}

Once you’re done with this you can now proceed without any issues, your code will work without any issues or limitations.

With this, we’re done with HC-SR04 with Arduino UNO. This session was a little long as some more extra effort needs to be done in this. If you need any help in the above process then do let me know I’ll be there to help ASAP.

Leave a Comment