# How To Measure Distance Between Two Ultrasonic Sensors

Ultrasonic sensor (HC-SR04) is commonly used to find the distance of an object from one particular point. It has been fairly easy to do this with the Arduino and the code is also pretty simple. But in this article we are going to try something different with these popular HC-SR04 sensors.

We will try calculating the distance between two Ultrasonic sensors that is, we will make one sensor to act as transmitter and the other sensor to act as receiver. By doing this we can track the location of one transmitter using many ultrasonic receivers this tracking is called triangulation and can be used for automatic docking robots luggage followers and other similar application. Finding the distance between two US sensors might sound to be a fairly simple task but I faced few challenges which are discussed in this project.

The technique discussed in this article is not fairly accurate and might not be useful in any real systems without modifications. During the time of this documentation I did not find anyone getting results as close as mine so I have just shared my views on how I got it to work so that people who are trying this need not re-invent the wheel.

### Materials Required:

1. Arduino (2Nos) – Any model
2. HCSR04 Module (2Nos)

### Circuit Diagram:

Even though we are going to make one US (Ultrasonic) sensor to work as transmitter and the other as receiver it is mandatory connect all the four pins of the sensors with the Arduino. Why should we? More of that will be discussed later, but for now the circuit diagram will be as follows:

As you can see the circuit diagram for both Transmitter and receiver are both identical. Also check: Arduino Ultrasonic Sensor Interfacing

### How HC-SR04 module actually works:

Before we proceed any further let us understand how the HC-SR04 sensor works. The below timing Diagram will help us understand the working.

The sensor has two pins Trigger and Echo which is used to measure distance as shown in the timing diagram. First to initiate measurement we should send an Ultrasonic wave from the transmitter, this can be done by setting the trigger pin high for 10uS. As soon as this is done the transmitter pin will send 8 sonic burst of US waves. This US wave will hit an object bounce back and will be received by the receiver.

Here the timing diagram shows that once the receiver receives the wave it will make the Echo pin go high for a duration of time which is equal to the time taken for the wave to travel from US sensor and reach back to the sensor. This timing diagram does not seem to be true.

I covered the Tx (transmitter) part of my sensor and checked if the Echo pulse got high, and yes it does go high. This means that the Echo pulse does not wait for the US (ultrasonic) wave to be received by it. Once it transmits the US wave it goes high and stays high until the wave returns back. So the correct timing diagram should be something like this shown below (Sorry for my poor writing skills)

Making your HC-SR04 to work as Transmitter only:

It is pretty much straight forward to make a HC-SR04 to work as transmitter only. As shown in the timing diagram you have to declare the Trigger pin as output pin and make it stay high for 10 Microseconds. This will initiate the Ultrasonic wave burst. So whenever we want to transmit the wave we just have to control the trigger pin of the Transmitter sensor, for which the code is given below.

Making your HC-SR04 to work as Receiver only:

As shown in the timing diagram we cannot control the rise of the Echo pin as it is related to trigger pin. So there is no way we could make the HC-SR04 to work as receiver only. But we can use a hack, by just covering the Transmitter part of the sensor with tape (as shown in the picture below) or cap the US wave cannot escape outside its Transmitter casing and the Echo pin will not be affected by this US wave.

Now to make the echo pin go high we just have to pull this dummy trigger pin high for 10 Microseconds. Once this Receiver sensor gets the US wave transmitted by the Transmitter sensor the echo pin will go low.

### Measuring distance between two Ultrasonic sensors (HC-SR04):

So far we have understood how to make one sensor work as transmitter and the other sensor to work as receiver. Now, we have to transmit the ultrasonic wave from transmitter sensor and receive it with the receiver sensor and check the time taken for the wave to travel from transmitter to receiver sounds easy right?? But sadly!, we have a problem here and this will not work.

The Transmitter module and Receiver module are far apart and when the receiver module receives the US wave from the transmitter module it will not know when the transmitter sent this particular wave. Without knowing the start time we cannot calculate the time taken and thus the distance. To solve this problem the Echo pulse of the receiver module must be made to go high exactly when the Transmitter module has transmitted the US wave. In other words, the Transmitter module and the receiver module should trigger at the same time. This can be achieved by the following method.

In the above diagram, the Tx represents Transmitter sensor and Rx represents Receiver sensor. As shown the Transmitter sensor will be made to transmit US waves at a periodic known delay, this is all it has to do.

In the Receiver sensor we have to somehow make the trigger pin go high exactly during when the transmitter pin goes high. So initially we randomly make the Receivers Trigger to go high which will and stay high till the echo pin goes low. This echo pin will go low only when it receives a US wave from the transmitter. So as soon as it goes low we can assume that the Transmitter sensor just got triggered. Now, with this assumption as soon as the echo goes low we can wait for the known delay and then trigger the receivers trigger. This would partially sync the trigger of both the Transmitter and receiver and hence you can read the immediate echo pulse duration using pulseIn() and calculate the distance.

### Program for Transmitter Sensor:

The complete program for the transmitter module can be found at the bottom of the page. It does nothing but trigger the transmitter sensor at a periodic interval.

```digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);```

To trigger a sensor we have to make the trigger pin to stay high for 10uS. The code to do the same is shown above

### Program for Receiver Sensor:

In the receiver sensor we have cover the Transmitter eye of the sensor to make it dummy as discussed earlier. Now we can use the above mentioned technique to measure distance between two sensors. The complete program is given at the bottom of this page. Few important lines are explained below

```Trigger_US();
while (digitalRead(echoPin)==HIGH);
delayMicroseconds (10);
Trigger_US();
duration = pulseIn(echoPin, HIGH);```

Initially we trigger the US sensor by using the function Trigger_US() and then wait till the echo pin stays high using a while loop. Once it gets low we wait for pre-determined duration, this duration should be somewhere between 10 to 30 microseconds which can be determined using trial and error (Or you can use improvised idea given below). After this delay trigger the US again using the same function and then use the pulseIn() function to calculate the duration of the wave.

Now using the same old formulae we can calculate the distance as below

`distance= duration*0.034;`

### Working:

Make the connections as explained in the program. Cover the Tx part of the receiver sensor as shown in the picture. Then upload the Transmitter code and receiver code which are given below to the transmitter and receiver Arduino respectively. Open the serial monitor of the receiver module and you should notice the distance between two modules being displayed as shown in the video below.

Note: This method is just an ideology and might not be accurate or satisfying. However you can try the improvised idea below to get better results.

### Improvised Idea – calibrating the sensor using a known distance:

The method that was explained so far oddly seems to be satisfying, yet it was sufficient for my project.  However I would also like to share the drawbacks of this method and a way to overcome them. One major drawback of this method is that we assume that the Echo pin of the receiver falls low immediately after the Transmitter sensor has transmitted the US wave which is not true since the wave will take some time to travel from transmitter to receiver. Hence the Trigger of the transmitter and the trigger of the receiver will not be in perfect sync.

To overcome this we can calibrate the sensor using a know distance initially. If the distance is know we will know the time taken for the US wave to reach the receiver from the transmitter. Let’s keep this time taken as Del(D) as shown below.

Now we will exactly know after how much time we should make the Trigger pin of the Receiver to high to get sync with the trigger of the Transmitter. This duration can be calculated by Known Delay (t) – Del(D). I was not able to test this idea due to time limitations so I am not sure how accurate it would work. So if you happen to try it do let me know the results through the comment section.

Code:

### Programming code for Receiver part

```const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance, Pdistance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
Pdistance=distance;
Calc();
distance= duration*0.034;
if (Pdistance==distance || Pdistance==distance+1 || Pdistance==distance-1  )
{
Serial.print("Measured Distance: ");
Serial.println(distance/2);
}
//Serial.print("Distance: ");
//Serial.println(distance/2);
delay(500);
}
void Calc()
{
duration=0;
Trigger_US();
while (digitalRead(echoPin)==HIGH);
delay(2);
Trigger_US();
duration = pulseIn(echoPin, HIGH);
}
void Trigger_US()
{
// Fake trigger the US sensor
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
}
```

### Programming code for Transmitter part

```// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
delay(2);
}```