Holooly Plus Logo

Question 12.10: You want to measure distance using an ultrasonic rangefinder......

You want to measure distance using an ultrasonic rangefinder.

Step-by-Step
The 'Blue Check Mark' means that this solution was answered by an expert.
Learn more on how do we answer questions.

Use a low cost SR-04 rangefinder. These devices need two GPIO pins, one to trigger the pulse of ultrasound and the other to monitor how long it takes for the echo to return.

To make this recipe, you will need:

• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)
• SR-04 rangefinder (eBay)
• 470Ω resistor (see “Resistors and Capacitors” on page 380)
• 270Ω resistor (see “Resistors and Capacitors” on page 380)

Fit the components onto the breadboard as shown in Figure 12-17. The resistors are necessary to reduce the echo output of the rangefinder from 5V to 3.3V (see Recipe 8.12).

Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called ranger.py.

import RPi.GPIO as GPIO
import time
trigger_pin = 18
echo_pin = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(trigger_pin, GPIO.OUT)
GPIO.setup(echo_pin, GPIO.IN)
def send_trigger_pulse():
GPIO.output(trigger_pin, True)
time.sleep(0.0001)
GPIO.output(trigger_pin, False)
def wait_for_echo(value, timeout):
count = timeout
while GPIO.input(echo_pin) != value and count > 0:
count = count – 1
def get_distance():
send_trigger_pulse()
wait_for_echo(True, 10000)
start = time.time()
wait_for_echo(False, 10000)
finish = time.time()
pulse_len = finish – start

distance_cm = pulse_len / 0.000058
distance_in = distance_cm / 2.5
return (distance_cm, distance_in)
while True:
print(“cm=%f\tinches=%f” % get_distance())
time.sleep(1)

The operation of the program is described in the Discussion. When the program is run, it will report the distance in both centimeters and inches, once per second. Use your hand or some other obstacle to change the reading.

sudo python ranger.py
cm=154.741879 inches=61.896752
cm=155.670889 inches=62.268356
cm=154.865199 inches=61.946080
cm=12.948595 inches=5.179438
cm=14.087249 inches=5.634900
cm=13.741954 inches=5.496781
cm=20.775302 inches=8.310121
cm=20.224473 inches=8.089789

Discussion

While there are a number of ultrasonic rangefinders available, the type used here is easy to use and low cost. It works by sending a pulse of ultrasound and then measuring the amount of time taken for the echo to be received. One of the round ultrasonic transducers on the front of the device is the transmitter, and the other is the receiver.

This process is controlled from the Raspberry Pi. The difference between this type of device and more expensive models is that the more expensive versions include their own microcontroller, which carries out all the necessary timing and provides an I2C or serial interface to return a final reading.

When you are using one of these sensors with a Raspberry Pi, the trig (trigger) input to the rangefinder is connected to a GPIO output, and the echo output of the rangefinder is connected to a GPIO input on the Raspberry Pi after having its voltage range lowered from 5V to a safe 3.3V.

Figure 12-18 shows an oscilloscope trace of the sensor in action. The top (red) trace is connected to trig and the bottom (yellow) trace is connected to echo. You can see that first the trig pin is taken high for a short pulse. There is then a short delay before the echo pin goes high. This then stays high for a period that is proportional to the distance from the sensor.

The code for this sensor first generates a trigger pulse (using the function send_trig ger_pulse). It must wait until the echo pin goes high and then times how long the echo pin stays high.

We can then calculate the distance using the time taken for the echo pulse and the speed of sound.

The wait_for_echo function waits until the echo pin either goes high or low, depending on its first argument. Its second argument is used to provide a timeout so that if for any reason, the echo pin does not change to the state being waited for, the loop won’t hang indefinitely.

See Also

Take a look at the datasheet for the ultrasonic rangefinder.

Table A-3. Prototyping equipment
Description Suppliers
M-M jumper wires SparkFun: PRT-08431, Adafruit: 759
M-F jumper wires SparkFun: PRT-09140, Adafruit: 825
F-F jumper wires SparkFun: PRT-08430, Adafruit: 794
Half-sized breadboard SparkFun: PRT-09567 Adafruit: 64
Pi Cobbler Adafruit: 1105
Table A-4. Resistors and capacitors
270Ω 0.25W resistor Mouser: 293-270-RC
470Ω 0.25W resistor Mouser: 293-470-RC
1kΩ 0.25W resistor Mouser: 293-1k-RC
3.3kΩ 0.25W resistor Mouser: 293-3.3k-RC
4.7kΩ 0.25W resistor Mouser: 293-4.7k-RC
10 kΩ trimpot Adafruit: 356, SparkFun: COM-09806, Mouser: 652-3362F-1-103LF
Photoresistor Adafruit: 161, SparkFun: SEN-09088
220nF capacitor MCM: 31-0610, Mouser: 80-C322C224M5U5HA
17
12.18

Related Answered Questions

Question: 12.11

Verified Answer:

Use the Tkinter library to open a window and write...
Question: 12.12

Verified Answer:

Write a Python program that writes the data to a f...
Question: 12.9

Verified Answer:

Use the DS18B20 digital temperature sensor. This d...
Question: 12.7

Verified Answer:

Use an MCP3008 ADC chip. However, unless you need ...
Question: 12.8

Verified Answer:

Use an analog accelerometer with a MCP3008 ADC chi...
Question: 12.6

Verified Answer:

Use a potential divider with one fixed resistor an...
Question: 12.2

Verified Answer:

Use the same basic recipe and code as Recipe 12.1,...
Question: 12.3

Verified Answer:

Low-cost resistive gas sensors are available that ...
Question: 12.4

Verified Answer:

The Raspberry Pi GPIO connector has only digital i...
Question: 12.5

Verified Answer:

Use a pair of resistors to act as a voltage divide...