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()