You are on page 1of 8

 Home

 About

« Digital Metronome
Multiplexing the Drive Circuit »

A Sensitive DIY Ultrasonic Range Sensor


January 22, 2011, 9:43 pm

I needed some ultrasonic range finders for my project. But most of the commercial sensors like Parallax’s
PING sensor and other similar products are quite expensive, especially if multiple units are needed. So I
thought why not building it myself?

The theory behind ultrasonic ranging is quite simple. Typically a short ultrasonic burst is transmitted from
the transmitter. When there is an object in the path of the ultrasonic pulse, some portion of the transmitted
ultrasonic wave is reflected and the ultrasonic receiver can detect such echo. By measuring the elapsed time
between the sending and the receiving of the signal along with the knowledge of the speed of sound in the
medium, the distance between the receiver and the object can be calculated. The picture below (source:
Wikipedia) illustrates this basic principal:

Ultrasonic Ranging (Courtesy of Wikipedia)

In my design, I used separate transducers for transmitter and receiver. It is possible to multiplex the
transmission and receiving with a single transducer (e.g. Maxbotix range finders), but the design would be
significantly more complex.

Ultrasonic Transducer

There are quite a few ultrasonic transducers to choose from, and the main criteria are the resonant frequency,
radiation pattern and sensitivity. Generally speaking, these parameters affect the measurement in the
following ways: a higher resonant frequency can provide finer details of the surroundings due to the shorter
wavelength. A more directional radiation pattern can also enhance the resolution of the measurement.
Sensitivity affects the efficiency of the transducer and also attributes to the SNR (signal to noise ratio).

I bought these 24 kHz transducers on sale (see picture below). These transducers are very inexpensive
(around a dollar each, and even cheaper when on sale) but effective. With properly designed circuits these
sensors can easily achieve a range of more than 20 feet. Of course, using the higher priced 40 kHz sensors
should achieve even better performance.
24 kHz Ultrasonic Transducers

But for these DIY ultrasonic range finders, the choice of the transducers are really not that critical and this
transducer really hits the performance to price sweet spot.

The Transmitter

The ultrasonic transmitter is powered from ATmega328′s counter 1 PWM output (chip pin 16 and Arduino
digital pin 10). In order to achieve the maximum output power of the transducer for a given supply voltage, I
used the bridged output design as shown in the following schematics:

Ultrasonic Transmitter

This bridged circuit produces an output voltage roughly twice the Vcc. I used +5V for Vcc and the result is
already quite good (more than 20 feet of range). For even longer range measurement, you can safely
increase this driving voltage to around 12 Volts as most ultrasonic transducers can be driven with voltage as
high as 20 to 30 volts. If you increase the voltage significantly above 5V however, you will have to change
the transistors to allow more power dissipation. With 2N3904 and 2N3906 the transistors get warm during
normal operation and would heat up drastically with voltage above 6V.

Here is the output of the ultrasonic burst measured at the output transducer’s terminals:
Output Waveform

The small “ladders” at the half-way voltage point in the output waveform is due to the slight added delay of
the inverted signal stage due to the use of an extra NPN transistor. To obtain purer rectangular wave form
and reduce switching loss, a PNP transistor with similar timing parameters can be used on the side that is
directly connected to the driving signal. For this application though, the waveform is more than adequate
and the added switching loss is negligible.

The transmitter and receiver transducers can be mounted on a circuit board with approximately one inch of
spacing (see below).

Ultrasonic Range Sensor

In order to reduce possible interference from the reflected ultrasonic waves, the components are mounted on
the reverse side of the board (below is the H-bridge circuit that drives the ultrasonic transducer, a few
decoupling capacitors are used to reduce noise and they are not shown in the schematics above):
H Bridge

The code to drive the transducer is similar to that I used previously, except that I changed the pre-scalar to 1
so that the output frequency can be controlled more precisely in the kHz range.

?
1
2
3
4
5
6
7
8
9
1
0 void startTransducer(float freq, float dutyCycle)
1 {
1   if (dutyCycle > 0.5) dutyCycle = 0.5;
1   else if (dutyCycle < 0) dutyCycle = 0;
2  
  cli();
1
  TCCR1B = _BV(WGM13) | _BV(CS10) | _BV(ICNC1);
3   //f0 = fclk / (2 * N * Top)
1   long topv = (long) ((float) F_CPU /(freq * 2.0 * 1.0));
4   ICR1 = topv;
1  
5   OCR1A = (int) ((float) topv * dutyCycle);
  OCR1B = (int) ((float) topv * (1 - dutyCycle));
1   DDRB |= _BV(PORTB1) | _BV(PORTB2);
6   TCCR1A = _BV(COM1A1) | _BV(COM1B1);
1   sei();
7 }
1  
8 void stopTransducer()
{
1   cli();
9   TCCR1B = 0;
2   sei();
0   digitalWrite(9,LOW);
  digitalWrite(10,LOW);
2 }
1
2
2
2
3
2
4
2
5
2
6

The Receiver

The performance of the range sensor is largely determined by the sensitivity of the receiver for a given
transmitter power level. Because the received signal is usually very weak (less than 1 mV), a high gain low
noise amplifier is needed to ensure optimal performance.
I used a two stage inverted band-pass amplifier design (see below). Each stage has a gain of around 67 (36.5
dB) and the circuit has a combined voltage gain of 73 dB. The operational amplifier I used is National’s
LPC662. In general, any operational amplifier with a sufficient gain bandwidth product should work just as
well.

Each stage has a band-pass filter that is centered around the operation frequency (24 kHz). Because the
amplifier has a very high gain, we must pay special attention to the circuit layout in order to prevent
parasitic oscillation. The connection between the receiver transducer and the circuit input (6.8n capacitor)
needs to be shielded to reduce noise and unwanted coupling.

Ultrasonic Receiver

Because we are using a single power supply the output voltage of the opamp is centered at around Vcc/2
(2.5V). In order to make it easier to process the echo, a diode (IN4148), capacitor (0.1uF) and resistor (10k)
are used to demodulate the signal and a coupling capacitor (1uF) is used to rid the demodulated signal of the
DC component.

You can see the demodulated envelope waveform from the following oscilloscope screenshots (you can
ignore the frequency measurement as these signals are none-periodical the frequency readings are
meaningless). The higher amplitude waveforms in both images are the results of the ultrasonic burst, the
lower amplitude waveforms are from the echo. In the first screenshot on the left, two echoes can be seen.

Echo and the demodulated waveform 1 Echo and the demodulated waveform 2

The following screenshot shows the relationship between the ultrasonic pulses (measured from ATmega328
pin 16) from the transmitter and the demodulated echo output. One key observation is that the received
signal takes much longer time to fade then the original pulse duration and thus we must add in some delay
after the transmission of the ultrasonic pulses. A delay of 1 to 2 millisecond is typical. With a 1 millisecond
delay, the shortest measurable distance is around 30 centimeters or one foot.
Demodulated Echo

And here is a picture of the finished project.

Ultrasonic Range Finder

Range Calculation

Since the measured distance is a function of the time interval between the time at which the pulse is
transmitted and the time at which the echo is received, we need to reliability detect the echo.

Empirically, we can measure the peak of the received echo and use the time displacement to calculate the
distance. We assume that the strongest echo comes from the closest object (this may not always be true as
the reflectivity of different objects are different, but generally achieves very good results in real-world
situations) and thus the peak measurement corresponds to the closest object’s position.

The code snippet below assumes that we are interested in measuring objects with a range of up to about 20
feet. After the pulses are transmitted from the transmitter, we wait for a millisecond for the initial receiver
signal to fade. Then we search the peak value in the next 20 milliseconds or so (the loop limit 256 is set
empirically, in the code below this setting corresponds to a 20 milliseconds interval between transmitted
pulses which is suitable for distance measurement up to approximately 20 feet. To measure longer distance,
the upper limit for the loop needs to be increased correspondingly) and assume that the peak comes from the
first echo.

?
1 byte a = 0;
unsigned long t_start = 0;
2 unsigned long t_peak = 0;
3 unsigned long t = 0;
4 byte v_peak = 0;
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4 const float SPEED_OF_SOUND_20C = 0.0003432; //meters per micro-second
1 float d = 0;
5  
1 void loop()
6 {
  startTransducer(24000.0, 0.5);
1
  delayMicroseconds(300);
7   stopTransducer();
1  
8   v_peak = 0;
1   t_start =micros();
9   t_peak = t_start;
  delayMilliseconds(1);
2
0  
  for (int i = 0; i < 256; i++) {
2     a = analogRead(0);
1     t = micros();
2  
2     if (a > v_peak) {
2       t_peak = t;
      v_peak = a;
3     }
2   }
4  
2   t = t_peak - t_start;
5   d = (float) t * SPEED_OF_SOUND_20C / 2.0;
  Serial.println(d , 2);
2 }
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
Here’s the full code listing for this project:
UltraSonicRangeFinder.tar.gz

The bill of material for this ultrasonic range finder is less than 5 dollars (excluding the MCU since it can be
incorporated into your projects).

Update

I would like to thank Thomas for pointing out the mistakes in my H-Bridge schematic. The PNP transistor’s
collector and emitter are swapped by mistake (I should have double checked the schematics. Anyway, the
photo shows the correct orientation) and I have updated the image.

Also on the receiver side, the first OP’s output was missing connection to the 0.1uF capacitor, I have
updated it as well.

You might also like