# Echolocation with HC-SR04 ultrasonic distance sensor

Ultrasonic echolocation is common practice in many areas, including nature itself. We all know how bats or dolphins navigate – they emit ultrasonic waves, and depending on the time delay of reflected echoes, they can determine the distance from obstacles or catch. From an engineering perspective, it is relatively easy to measure distances with ultrasound – all you need to know is sound speed in the air and time delay between sent and received pulses.

$L = C_{AIR}\cdot \frac{t}{2}$

L is the measured distance; CAIR – ultrasound speed; t – the time between transmitted and received pulses.

The accuracy of measured distance mainly depends on air temperature. The following formula can calculate sound speed in the air approximately :

$C_{AIR} = 20.0457\cdot \sqrt{273.15+T} (m/s)$

For instance, at 25ºC, the speed of sound in dry air CAIR = 346.13 m/s. If you want greater accuracy, you should also measure temperature to adjust sound speed.

There are several cheap ultrasonic echolocation modules available, but probably most known and used is HC-SR04. You can find lots of projects built around them, including distance meters, robots, radars, thickness, and security barriers, parking, and liquid level. These modules have pretty good characteristics that make them so popular:

The interfacing module is straightforward – it comes with only four pins. Two of them are power (VCC and GND), one pin is Trigger pin, and one Echo pin. The module itself does the hard work of transmitting and receiving signals. To perform the primary measurement, send at least 10us pulse to Trigger pin and wait for rising edge signal on Echo pin. Once raising edge is detected, start microcontroller counter and wait for a falling edge on Echo pin. Pulse on the Echo is the time between transmitting and receiving signals. Having time delay, you can calculate the distance from the obstacle by the formula above.

## Running HC-SR04 with Arduino and LCD keypad shield

Let’s build a prototype using Arduino, LCD keypad shield, and HC-SR04. The distance will be displayed on LCD. We will use a button to implement couple of different functionalities. Also, it will be interesting to see how accurate the measured distance is compared with tape meter. LCD keypad shield is connected to Arduino, as reviewed previously here. So it occupies pins 8, 9, 4, 5, 6, 7, 10 (backlight) and analog 0 for buttons. So we are left with 1 to 5 analog pins and 0, 1, 2, 3, 11, 12, and 13 digital. We will leave 0 and 1 digital pins for serial output and use digital pin 2 for HC-SR04 trigger and digital 3 for Echo. Also, we need to connect VCC and GND.

Additionally, we want to monitor environment temperature to calculate sound speed in order to achieve better accuracy. So for this, we will use DS18D20, where sense pin is connected to A1 pin of Arduino pulled up to VCC with 4.7k resistor.

Programming Arduino is relatively easy, mainly when special libraries are used. First of all, let us deal with temperature measurement. To read temperature values, we need two libraries: OneWire and DallasTemperature. Using them, life becomes much more comfortable as you only need to initialize temperature sensor, assign pin and read its value.

The same situation is with LCD keypads. The LCD is controlled with standard Arduino library, and no additional libraries are required. If you need to work with buttons that are read with a single analog pin, then you should get LCDKeypad.zip library which makes fundamental reading more robust. We will not analyze them more deeply, and the working is evident in the source code.

We have used temperature to calculate sound speed in the air. A simple empirical formula is used to get speed values in cm/us:

$sound\_speed = 20.0457 \cdot \sqrt{273.15 + temp1}$

Let’s pay a bit attention to how we can read distance out of HC-SR04 sensor. We have assigned Arduino pin 2 for Trigger and pin 3 for Echo signals. So, first of all, we need to get pulse time information which indicates the duration of ultrasonic pulse flight and return. There is a simple routine to trigger the sensor and get time value in microseconds:

digitalWrite(Trigger, LOW);
delayMicroseconds(5);
digitalWrite(Trigger, HIGH);
delayMicroseconds(10);
digitalWrite(Trigger, LOW);


First of all, we give short 5us LOW pulse before sending a clean high pulse. High trigger pulse needs to be at least 10us. When trigger pulse drops LOW, the sensor sends eight 40kHz square pulses. At same time Echo pin becomes HIGH until bounced-back signals are received. Arduino needs to capture the duration of the HIGH state of Echo pin. Luckily Arduino comes with the handy function

pulselength =&nbsp; pulseIn(Echo, HIGH); //microseconds


Which returns time duration in microseconds of pin state high.

Once we have time pulse duration and sound speed, we can calculate the distance using a simple formula:

//centimeters
distancecm = sound_speed *&nbsp; (pulselength/2);
//inches
distancein = distancecm * 0.39370;


With keypad buttons UP and DOWN, we can change centimeters units to inches. With LEFT and RIGHT buttons, we can switch secondary screen where pulse time and sound speed values are visible.

And with SELECT button, we can call REL function, which allows measuring relative distances from a position where the button was pressed.

To evaluate measuring accuracy, I have constructed simple rig with measuring tape.

I didn’t do any statistical analysis, just a simple comparison of two values. As you can see, with tape meter, I get 39.7cm, while with SR04 sensor, 38.9. The difference is 0.8cm.

Practically we cannot expect greater accuracy without additional measures. We have calculated sound speed by taking the only temperature into account. But other factors also influence sound speed – air density which in it, hand depends on altitude. Also, there is an influence of sensor position, measured surface properties, and temperature measurement accuracy. In my opinion, 0.3cm accuracy can only be reached in a controlled environment where the sound of speed is known for real or is directly measured.