Distance Monitor with Visual Display

We can use the distance sensor from a previous tutorial to continually monitor distance and illuminate LEDs in order. The LED tail we are using has 3 green LEDs and 2 red LEDs to indicate when we are getting too close.

The HC-SRO4 ultrasonic distance sensor and set of LED tails
The distance sensor needs to have a resistor (ideally around 1kΩ) wired in series on the Echo pin. In the picture this is the white wire. Other than that it's just a case of wiring it up as below. (For more information please consult this tutorial). Open Pinout Diagram
HC-SR04 Pin Raspbrry Pi Pin
VCC +5v
ECHO (plus resistor) GPIO 24
TRIG GPIO 25
GND Ground (GND)
Pinout table for the HC-SR04 distance sensor

LED Tail

The LEDs are colour coded on the tips (assuming you are using the Electro Cat Studios version). If you are using your own version then you will need to make sure that the LEDs are wired up correctly. The following table shows the pin wiring for the code below (if the pins are in use elsewhere then you can change them but you will need to modify the code to use the correct pins).
LED Tail Colour Raspbrry Pi Pin
Black Ground (GND)
Red GPIO 21
Orange GPIO 20
Green GPIO 16
Blue GPIO 26
Yellow GPIO 19
Pinout table for the LED VU meter

The Code

The code for testing the project is available from Github. The address of the hosted code is https://github.com/filtoid/rpi-distance-sensor. If everything is connected correctly then you should be able to load up and run measure_distance.py using the following command from the directory that the code is located in.
sudo python measure_distance.py
This should print out a distance in cm. If you rerun the program with a piece of card in front of the sensor it should report the distance accurately(bear in mind accuracy may be only to a few CM either way). If there are problems here, like for instance the program hangs then it might be worth checking the debugging section below. Next we need to check that the lights are connected up properly. To do this we need to run the other script in the provided code, 'lights_test.py'. To do this run the following command/
sudo python lights_test.py
You should see all of the lights on the sensor light up in order. If they do not then check out the debugging section for help.

Next up we need to have a go at putting the two different scripts together to form a single script which will continually measure the distance and turn lights on an off as needed.

Solution

It might be worth having a go at thinking about how you would solve this problem.

There are several steps. We need to store the return value from the function measure_distance() in a variable and then compare that value and turn on the appropriate number of lights as needed.

Once we have the value we need to repeatedly get new values of distance but with a timer. About 10 times a second should be about right. To do this we use timer.sleep(0.1) because timer.sleep() takes an argument of the number of seconds you wish to sleep for.

The completed code might look something like this:
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

# Pins for the Sensor
TRIG = 23
ECHO = 24

GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)

# Pins for the lights
RED1 = 21
RED2 = 20
GREEN1 = 16
GREEN2 = 26
GREEN3 = 19

GPIO.setup(RED1, GPIO.OUT)
GPIO.setup(RED2, GPIO.OUT)
GPIO.setup(GREEN1, GPIO.OUT)
GPIO.setup(GREEN2, GPIO.OUT)
GPIO.setup(GREEN3, GPIO.OUT)

def light_off(index):
GPIO.output(index, False)

def light_on(index):
GPIO.output(index, True)

def measure_distance():
GPIO.output(TRIG, True)

time.sleep(0.00001)
GPIO.output(TRIG, False)

while GPIO.input(ECHO)==0:
pulse_start = time.time()

while GPIO.input(ECHO)==1:
pulse_end = time.time()

pulse_dur = pulse_end - pulse_start
distance = pulse_dur * 17150
distance = round(distance, 2)
print(str(distance) + " centimetres")
return distance

# Wait for the sensor to settle in
GPIO.output(TRIG, False)
print("Letting sensor settle")
time.sleep(2)

while True:
dist = measure_distance()

if dist < 25:
light_on(GREEN3)
else:
light_off(GREEN3)

if dist < 20:
light_on(GREEN2)
else:
light_off(GREEN2)

if dist < 15:
light_on(GREEN1)
else:
light_off(GREEN1)

if dist < 10:
light_on(RED2)
else:
light_off(RED2)

if dist < 5:
light_on(RED1)
else:
light_off(RED1)

GPIO.cleanup()
Running the code above should result in a sensor which reports it's distance by printing to the screen and also light up a number of lights based on how close your hand is. If you have any problems with the code or it doesn't work as expected then check it and check the debugging section below.


Debugging

If you are having problems then try some of the steps below to solve them.

When I try to measure the distance it just hangs

Make sure that all the pins are connected correctly. If you need to stop the program press ctrl+c together, this tells the program to exit. Sometimes if the pins are making a decent electrical connection it can cause this hanging. To test if this is the case you can try gently pushing the pins on the Pi, it doesn't take a lot of pressure to make the pins connect though so don't push too hard. You can try to change the wires out to see if new wiring solves the problem.

The code reports that the variable pulse_start does not exist

If this happens then the pins are not connected correctly or are failing to make a proper electrical connection. See the question above for possible solutions.

The distance reported is very high (over 30m for instance)

The sensor is not very accurate over about 2m in range. This is because it uses sound which spreads in all directions. Commercial distance sensors use lasers because the energy created travels in straight lines rather than disappating. If the sensor is reporting a value which you think is too high then you could try moving a piece of card nearer the device and rerunning the code. It can also help if you remove any possible interference likes moving air (if there is a fan nearby for instance) or external sources of noise, which can disrupt the operation of the sensor.

The lights don't all light up

Check your wiring, it seems that some of the tails are not plugged into the correct GPIO pins.

The lights don't come on in the right order

If they light up in the wrong order then check the cables are connected to the correct pins. If any of the LEDs have fallen out of the card and been replaced it is probably worth making sure they were replaced correctly.