Introduction: Leader_Follower - Using Direction of Arrival


I was asked to do a project, where one robot (Follower) follows on its own an another robot(Leader) which of course is controlled by a human. Finally I settled on the idea, that the Leader would emit ultrasound sound pulses every second or so, using the HC-SR04 Ultrasound Sensor, while the follower would have three HC-SR04 sensors mounted in three different directions, to sense the direction from which the pulse would arrive and respond in an appropriate way.

To help with the ultrasound communication between the robots, I wanted to use 'interrupts' in the Follower to trigger movements based on whatever direction the pulse was coming from but since HC-SR04 already had a micro-controller in built as explained in detail here, I tried to follow exactly what was done in this link by removing the transmitter and receiver transducers from HC-SR04 module but this didn't seem to work as the distances increased and so I discarded it.

Step 1: Making the Follower:


  1. Arduino Mega (Since we need three external interrupts, UNO has only two)
  2. Chassis
  3. Dc motor and wheels
  4. L293D motor driver IC or module
  5. Three HC-SR04 ultrasound modules
  6. Batteries

The main idea was to use interrupts in the follower to trigger forward, rightward or leftward movements based on which sensor triggered an interrupt But because the way the HC-SR04 functions, we can't use the module in a conventional way for the module is designed to work with the transmitter and the receiver in tandem. Although the detailed explanation can be found here, in short, a 10 microsecond pulse is triggered on the "Trig" pin on the module, and once the ultrasound sound pulse is transmitted through the transmitter, the echo pin goes high and holds until the receiver receives the pulse, at which it goes low and we measure the time between the high and low logic on the Echo pin and thereby enabling us to measure the distance of the object.

But in this case, only the receiver has to function since the pulses are transmitted in a separate module in the Leader. And so after looking at the detailed circuit shown here, one can see that the microcontroller (EM78P153S, marked 'U2' in the module) in the module is connected on its P60/INT pin to the pins SIGIN(4) and SIGIN2(6) on the driver (marked 'U3' in the module). So when the receiver normally receives a pulse, it triggers an interrupt in the built-in microcontroller. So all we have to do is to solder an external wire on the pin 4 or pin 6 on the driver and we can use that to trigger the Arduino Mega directly. Make sure when u solder, the wire or the solder doesn't touch the other pins, otherwise the module will not function properly.


Three HC-SR04 have three wires soldered externally and these

three wires connect to pins 19,20,21 respectively.

However I connected:

Left - D19

Front - D20

Right - D21

The Code:

ISR(INT0_vect) //Interrupts code for LEFT{cli(); //disables global interrupts  left_int = true;  buf[counter]=1; //1 = left (1 is arbitatry)  counter++;  delayMicroseconds(450); //This delay so that the entire 8 or so pulses passes, without triggering an interrupt }

The above segment of code is the interrupt, when the left Ultrasound sensor is triggered.

The buffer was added, more or less after several tests, the pulses sometimes triggered the other direction sensors too, either directly or reflection or through some vibration.

To find what sensors gets triggered, uncomment the portion of the code to print to serial monitor and check and see.

The delay part in the code was needed, since the ultrasound came in 8 pulses at 40K Hz.

so 1/40000 = 25 microseconds * 8 = 200 microseconds

so I added in the extra 250 microseconds, just in case it does not trigger the same sensor again and again or even the other sensors.

The same goes for other interrupts.


This below segment executes either if the zeroth or first location of the buffer, fills with 1 (1 is arbitrarily points to left) and if the Boolean left_int is true. The reason the buffer was used, because sometimes randomly u got a right or forward interrupt too, either because of the same pulse reaching it or some reflection of the previous pulse's.

if ((buf[0] == 1 || buf[1]==1) && left_int) {         digitalWrite(32,LOW);      digitalWrite(33,LOW);      digitalWrite(34,LOW);      digitalWrite(35,HIGH); //LEFT forward      tme=millis(); //Take reading so that after 700 ms passes, all motors stop             //Serial.println("L"); //for debugging      left_int=false;      counter=0; //set counter to 0 so next interrupts fills buffer from 0            sei(); //Enable Global interrupts again so the next interrupts takes place}


if (millis()-tme >=700) { //every 700 milliseconds stop all the motors, so that the follower doesn't go haywire in all directions      digitalWrite(32,LOW);      digitalWrite(33,LOW);      digitalWrite(34,LOW);      digitalWrite(35,LOW); //Set all the motors to zero      tme=millis();  //Take present milliseconds reading for the next loop    }

This above portion of the code, it to stop the follower every 700 milliseconds and check for new interrupts , otherwise the follower sometimes tend to go haywire and the value 700 is something I kept after playing with the follower and its not an absolute value.

Step 2: Making the Leader:


  1. Arduino UNO
  2. chassis
  3. Dc motor and wheels
  4. L293D motor driver IC or module
  5. one HC-SR04 module
  6. HM-10 (to control the Leader
  7. MIT app inventor2

Getting the Leader done was fairly easy.

I used a readily available acrylic robot chassis for the leader and used a L293D motor drive IC to drive the motor/wheels and a HM-10 Bluetooth low energy module to control the Leader and exhaustive explanation for these two circuits is readily available on the internet and so I wouldn't cover it here separately. The HC-SR04 module is connected normally except the Echo pin, which is left disconnected because we are only transmitting.



Vcc - 5V(UNO)

Gnd - Gnd(UNO)

Trig pin - D10(UNO)


Vcc - 3.3V(UNO)

Gnd - Gnd(UNO)

TX - D8(UNO)


The connections between Arduino UNO and the L293D is ignored is here.

To control the Leader, I used the MIT app inventor to build an app, that connects with the HM-10 using Bluetooth low energy, which is different from Bluetooth classic. Although Bluetooth Classic can be used, like the HM-05 module. I have provided the project file, with the aia extension, as sometimes APK might not work, since the Service UUID and the characteristic UUID might have to be changed, which are fundamental to BLE low energy.

I have added a Start/Stop pulse button in the app, since sometimes to stop the Follower from going haywire, the Leader has to stop emitting pulses.

Otherwise the Arduino code is fairly simple and commented for further information.The software Serial library is used, since Arduino UNO has only one set of Serial (UART) pins.

Step 3: Testing:

Finally once the two units were built, it was time to test it.

The follower was sensitive enough to respond, when i snapped my fingers by the three sensors.

The next two videos, here and here show, how the entire set up did seem to work. The Follower did start acting strangely quite often, but sometimes it worked very well.

Step 4: Conclusion:

This project was quite a challenging one and I never thought I would finish it, but finally it worked better than I expected but although you can't trust it always.

The Ultrasound sensors worked well, but sometimes the Follower could follow reflected waves bounced of walls and other objects and might go off in other directions. The Follower would sometimes responded excitedly like a puppy to very loud sound or high pitched sounds.

Finally, this basic project is a great start and more sophisticated sensors should be added to get it to the next level.After i had finished the project, i came across this video on YouTube about the same concept in the US Army, and perhaps someday enact it in a more sophisticated way.