Introduction: Enhanced Ultrasonic Range Finder

About: 55+ years in electronics, computers, and teaching ... now retired.

A common method of measuring distances is to use an Arduino and an HC-SR04 ultrasonic sensor (or similar) as described in instructable https://www.instructables.com/id/Ultrasonic-Range...

The problem with such sensors is that they only respond to the nearest echo. Echos from more distant objects are ignored ... unless the sensor is modified.

This instructable explains how to modify an HY-SRF05 (or HC-SR04) ultrasonic sensor to obtain the return echos from multiple objects.

This simple modification allows us to measure the distance(s) of multiple objects using a single “ping”

Photo 1 shows the test setup.

Photo 2 shows the Arduino Uno R3 test connections

Photo 3 shows a “screen-grab” of the waveforms.

Step 1: Wiring Diagram and Parts List

The wiring diagram is shown in photo 1

Parts List

Very few parts are required to duplicate this project:

    • 1 only HY-SRF05 ultrasonic transducer
    • 1 only Arduino Uno R3 microprocessor
    • 4 only Arduino male-female jumper wires
    • 1 only Arduino male-male jumper wire

    Notes

      1. All parts were obtained from https://www.aliexpress.com/
      2. An HC-SR04 ultrasonic transducer may be substituted for the HY-SRF05. Solder the jumper wire to pin 10 of the center IC (integrated circuit) and ignore the fact that it is labelled U2.

      Step 2: Theory

      The HC-SR04 and HY-SRF05 ultrasonic sensors both work on the following principle:

      On receipt of a 10uS trigger pulse, an onboard microprocessor sends eight pulses, at 25uS intervals, to the transmit circuitry (photo 1 – lower trace).

      The “Echo” pin imediately goes HIGH, and stays HIGH until the first return echo pulse is received (photos 2, 3, & 4 - top trace)

      The distance in centimeters , in all cases, is calculated by measuring the time interval between on the rising edge of the top-trace and the rising-edge of the first return pulse then dividing by 59.

      Echos from more distant objects are ignored (photo 4 – lower trace)

      Examples:

      Photo 2:

      • 4.8 divisions * 500uS-per-division / 59 = 40cm

      Photo 3:

      • 1.2 divisions * 500uS-per-division / 59 = 10cm

      Notes:

      1. The return echos are often longer than the transmitted pulse train (photo 2 – lower trace)
      2. The left-most pulse on the lower-traces of photos 2, 3, and 4 corresponds to the 10uS trigger pulse. This pulse is observed on pin 10 of the HY-SRF05 onboard microprocessor prior to being processed.

      Step 3: Measuring Multiple Distances

      The top trace in photo1 shows a typical waveform that appears on the HY-SRF05 “Echo” pin.

      But if we solder an arduino jumper-wire to U1 pin 10 of the HC-SR05, as shown in photo 2, we obtain the lower trace.

        This trace contains the following information:

        1. The left-hand spike corresponds to the trigger pulse.
        2. The center waveform is the echo from the first object
        3. The right-hand waveform is the echo from the second object.

        Top and bottom views of the HC-SRF05 ultrasonic transducer are shown in photo 3.

        Strategy

        A simple strategy for measuring these distances is to:

          1. Calculate the first-object distance using the “Echo” pulse information on the top trace.
          2. Wait until the first echo-pulses have gone then look for the next rising-edge on the lower trace.
          3. Calculate the second-object distance by measuring the time from the rising edge on the “Echo” pin to the rising-edge of the second-object (lower trace).

          Step 4: Source Code

          This code builds on the code found in my instructables https://www.instructables.com/id/Ultrasonic-Range...

          and https://www.instructables.com/id/Multi-task-Your-...

          The code for the new measure() function follows:

          // ===============================
          // measure distances
          // ===============================
          void measure()
          {
            // ----- locals
            unsigned long start_time;           //microseconds
            unsigned long finish_time;          //microseconds
            unsigned long time_taken;           //microseconds
            unsigned long timeout;              //microseconds
            unsigned long pause;                //microseconds
            boolean flag;
          
            // ----- generate 10uS start pulse
            digitalWrite(Trig, HIGH);
            delayMicroseconds(10);
            digitalWrite(Trig, LOW);
          
            // ----- wait for pulse(s) to be sent
            while (!digitalRead(Echo));                 //wait for high
            start_time = micros();
          
            // ----- set timeout radius
            timeout = start_time + 12000;               //set timeout radius to 2 meters
          
            // ----- measure first object distance    
            flag = false;
            while (!flag)
            {
              if (!digitalRead(Echo)) flag = true;      //exit loop if object detected
              if (timeout < micros()) flag = true;      //exit loop if timeout exceeded
            }
            finish_time = micros();
          
            // ----- calculate first object distance
            time_taken = finish_time - start_time;
            Distance1 = ((float)time_taken) / 59;
          
            // ----- wait for first object echo to finish
            pause = finish_time + 1000;                 //1000uS means 17cm closest object spacing
            while (pause > micros());                   //wait 1000uS (delayMicroseconds(1000) erratic)
          
            // ----- measure second object distance
            flag = false;
            while (!flag)                               //wait for high
            {
              if (digitalRead(RawEcho)) flag = true;    //exit loop if object dectected
              if (timeout < micros()) flag = true;      //exit loop if timeout exceeded
            }
            finish_time = micros();
          
            // ----- calculate second object distance
            time_taken = finish_time - start_time;
            Distance2 = ((float)time_taken) / 59;
          }
          

          The complete code for “ultrasonic_range_finder_2.ino” is attached.

          To install this code:

          1. Download the attached file “ultrasonic_range_finder_2.ino”
          2. Copy the contents of this text file into a new Arduino sketch.
          3. Save this sketch as “ultrasonic_range_finder_2” (without the quotes).
          4. Now upload the sketch to your Arduino Uno R3.

          To view the distance readings:

          1. Click “Tools|Serial Monitor”
          2. and set the speed to 115200 bauds.

          Thanks for reading ...

            Click here   to view my other instructables.