Ultrasonic Range Sensor

Ultrasonic Range Sensor

In preperation for the PiTank (or PiBot V2.0) i purchased 2 of these little ultrasonic range finder modules (google HC-SR04) for a few quid each so that i could create a simple collision detection system.

 

As you can see from the photo the wiring is very simple connect the +v to the 5v rail and ground to the ground rail. Next use two available GPIO pins if you wish to follow the photo exactly i connected Trig to pin 22 and Echo to pin 17. Now i have been having some issues with floating pin values on startup so i have placed two resistors between the pins i am using and the ground rail which will pull their values to ground unless i set them to high or the response from the ultrasonic module sets it to high. If you have problems with really random readings this is probably your issue.

 

Below is the code for the ultrasonic module which i half found on the internet and then modified to add more functions. There are a number of easy to use functions within it.

 

To add this to your library simply open a new .py file using "nano ultrasound.py" and past the code in before saving.

 

To test your sensor is working fine and wired correctly if you run the module directly e.g sudo python ultrasound.py.

 

To import the module use "import ultrasound as us"

 

To measure the distance in a metric unit of your choice use "us.distance_x" where x is m, cm or mm. This will return a distance in the unit selected

To use the sensor as a proximity warning sensor use "us.proximity( insert distance here, insert units m etc)" This will return True if the distance is less than set or false if it is greater than set.

 

# Module: ultrasound.py
# This module can be used to operate an HC-SR04 ultrasonic sensor
# from a raspberry pi GPIO.
 
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
 
# setup which pins are which
TRIG = 22
ECHO = 17
 
# set the trigger pulse length and timeouts
pulsetrigger = 0.0001 # Trigger duration in seconds
timeout = 2100        # Length of time for timeout
 
def configure(trigger, echo):
    TRIG = trigger
    ECHO = echo
    GPIO.setup(TRIG, GPIO.OUT)
    GPIO.setup(ECHO, GPIO.IN)
 
def fire_trigger():
    # Set trigger high for 0.0001s then drop it low
    GPIO.output(TRIG, True)
    time.sleep(pulsetrigger)
    GPIO.output(TRIG, False)
 
def wait_for_echo(desired_state):
    countdown = timeout
    while (GPIO.input(ECHO) != desired_state and countdown > 0):
        countdown = countdown - 1
    return (countdown > 0) # Return true if success, false if timeout
 
def measure_time():
    # Fire the trigger to set the whole thing in motion
    fire_trigger()
 
    # Check that the echo goes high....
 GPIO.setup(TRIG, GPIO.OUT)
    GPIO.setup(ECHO, GPIO.IN)
 
def fire_trigger():
    # Set trigger high for 0.0001s then drop it low
    GPIO.output(TRIG, True)
    time.sleep(pulsetrigger)
    GPIO.output(TRIG, False)
 
def wait_for_echo(desired_state):
    countdown = timeout
    while (GPIO.input(ECHO) != desired_state and countdown > 0):
        countdown = countdown - 1
    return (countdown > 0) # Return true if success, false if timeout
 
def measure_time():
    # Fire the trigger to set the whole thing in motion
    fire_trigger()
 
    # Check that the echo goes high....
    if wait_for_echo(1):
        # Start the timer and wait for the echo to go low
        echo_start = time.time()
        if wait_for_echo(0):
            # Stop the timer
            echo_end = time.time()
            return echo_end - echo_start
        else:
            print "Timeout 2"
            return -1
    else:
        print "Timeout 1"
        return -1
 
def measure_average_time():
    count = 1
    total_time = 0
    while(count <= 3):
        total_time = total_time + measure_time()
        time.sleep(0.1)
        count = count + 1
 # Start the timer and wait for the echo to go low
        echo_start = time.time()
        if wait_for_echo(0):
            # Stop the timer
            echo_end = time.time()
            return echo_end - echo_start
        else:
            print "Timeout 2"
            return -1
    else:
        print "Timeout 1"
        return -1
 
def measure_average_time():
    count = 1
    total_time = 0
    while(count <= 3):
        total_time = total_time + measure_time()
        time.sleep(0.1)
        count = count + 1
    return total_time / 3
 
def distance_m():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        return (time * 340)/2
 
def distance_mm():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        return ((time * 340) / 2)*1000
 
def distance_cm():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
def distance_m():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        return (time * 340)/2
 
def distance_mm():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        return ((time * 340) / 2)*1000
 
def distance_cm():
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        return ((time * 340) / 2)*100
 
def proximity(prox_length, unit):
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        measured_length = (time * 340) / 2
 
    if unit == "m":
        prox_length_m = prox_length
    elif unit == "mm":
        prox_length_m = prox_length / 1000
    elif unit == "cm":
        prox_length_m = prox_length / 100
    else:
        return "Incorrect Units"
 
 
    if measured_length <= prox_length_m:
        return True
def proximity(prox_length, unit):
    time = measure_average_time()
    if time < 0:
        return -1
    else:
        measured_length = (time * 340) / 2
 
    if unit == "m":
        prox_length_m = prox_length
    elif unit == "mm":
        prox_length_m = prox_length / 1000
    elif unit == "cm":
        prox_length_m = prox_length / 100
    else:
        return "Incorrect Units"
 
 
    if measured_length <= prox_length_m:
        return True
    else:
        return False
 
if __name__ == "__main__":
    print "Starting ultrasound test"
    # Set up the GPIO board
    #GPIO.setmode(GPIO.BCM)
 
    # Tell the Pi which pins the ultrasound is on
    configure(TRIG, ECHO)
 
    try:
        while True:
            distance = distance_m()
            if distance < 0:
                print "Timeout"
            else:
               # print "Distance = %.0f cm" % (int(round(distance)))
                print distance
            time.sleep(2)
 
    except KeyboardInterrupt:
        print "Stopping"
        GPIO.cleanup()