Raspi Parking Sensor

Hi guys,

I’m wanting to construct a parking sensor for our rather cramped little garage and I stumbled across this great tutorial that you guys put together:

This is pretty much exactly what I want to do, however I’d like to use a Raspberry Pi Zero (WH) because I’m a bit of a novice, and I like the convenience of the soldered headers.

Just looking for a bit of advice on how I would wire the whole thing up? Like I said, I’m a complete novice, but thought this would be a fun project to get started with.

Hi Shane,

You can follow this tutorial here:
https://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi

This shows you how to use an ultrasonic sensor with a Raspberry Pi (it will be the same on the Pi Zero). There are some extra steps to use it with a RPi because the sensor is a 5V device and the RPi can only accept 3.3V inputs.

Let me know what you think!

Looks great Stephen, thanks for tips.

I also came across this: https://www.instructables.com/id/Raspberry-Pi-Park-Sensor/ which includes a traffic light type LED display, which I think would be good to tell me when to pull up the car.

I’ll end up using both articles as reference but the is a discrepancy in the size of the resistors used to lower the voltage on the RasPi’s GPIO pins. The article you referenced does explain it pretty well, so I dare say I’ll run with that. Would that be your advice???

Hi Shane,

The link I suggested has the correct resistors. The one you found will still work, but it lowers the voltage more than needed (to 2.8V). As far as everything else they both seem good. I used this calculator to check them:

Awesome. Thanks again Stephen, that’s a massive help.

I’ll get on with ordering some bits off you now, and I’ll let you know how I go.

Hi Stephen,

The birth of our first child has meant I’ve been a bit pre-occupied and haven’t had a chance to really get this project off the ground, but it is a work in progress…

I got it to the point now where I have it all laid on a bread board and it appears to be doing everything I want.

For anyone who is interested, here a a few photos and a little video of this contraption in action

The only thing that I think would be ideal would be for the red LED to turn off after 10 minutes so its not constantly turned on while the car is parked. I’m not sure if its possible to do this, but I’ve pasted my code below for reference, so there are any gurus out there that could help me out here, that’d be great. Hopefully I’ve expained myself well enough.

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
TRIG = 4
ECHO = 18
GREEN = 17
YELLOW = 27
RED = 22
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
GPIO.setup(GREEN,GPIO.OUT)
GPIO.setup(YELLOW,GPIO.OUT)
GPIO.setup(RED,GPIO.OUT)
start = 1
def no_light ():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.LOW)
def green_light():
GPIO.output(GREEN, GPIO.HIGH)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.LOW)
def yellow_light():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.HIGH)
GPIO.output(RED, GPIO.LOW)
def red_light():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.HIGH)
def get_distance():
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
global start
while GPIO.input(ECHO) == False: start = time.time()
while GPIO.input(ECHO) == True: end = time.time()
signal_time = end-start
distance = signal_time / 0.000058
return distance
while True:
distance = get_distance()
time.sleep(0.05)
print(distance)
if distance >= 60:
no_light()
elif 90 > distance > 30:
green_light()
elif 28 > distance > 16:
yellow_light()
elif distance <=15:
red_light()
while False:
print “error”

GPIO.cleanup()

Hi Shane,

Some pseudo-code to get you started in the right direction. This code may not work perfectly as is, but the point is that the red light turns on for one second, then the code loops. If it has been red for 10 cycles (about ten seconds with the delay) then it will turn off the LED and wait for 5 minutes before measuring again. If another light is turned on the count resets for the Red LED.

ticks = 0
    while True:
      distance = get_distance()
      time.sleep(0.05)
      print(distance)
      if distance &gt;= 60:
        ticks = 0
        no_light()
      elif 90 &gt; distance &gt; 30:
        green_light()
        ticks = 0
      elif 28 &gt; distance &gt; 16:
        yellow_light()
        ticks = 0
      elif distance &lt;=15:
        ticks = ticks + 1
        time.sleep(1)
        if ticks < 10
          red_light(False)
          time.sleep(1000*60*5)
       else
        red_light()

    GPIO.cleanup()

Hey Stephen,

Thanks heaps for the supplied code. Makes good sense, I’ll give it a run and see how I go.

1 Like

Hi Stephen,

Not sure if you’ve ever come across this previously, but you haven’t steered me wrong thus far so I thought I’d ask.

Using the code I post previously in this thread, I’ve observed that everything works as intended initially, but after a period of time (possibly 3 to 4 hours of continuously running this script) it seems to stop responding, without an apparent error message.

In a practical sense, I could explain it like this - I park the car and the expected sequence occurs, sensor detects the distace to the front of the car and LEDs go from green to yellow to red. Car is parked for 3 to 4 hours (or left overnight), then we I move it, there is no change to the LED

Is there a way to show some more verbose error messages, or could this have to do with something like a user session timeout, or a continuous stream of input / output…

I have this script configured when the Pi boots up using crontab (@reboot)

My only other idea was to stop and restart the script every 10 minutes rather than leaving it run indefinitely.

Let me know if I haven’t explained things very well.

Thanks again

Hi Shane,

You could add print messages throughout your code and monitor it with a serial monitor.
Then you will be able to tell where the code stops. I’m not sure why your code would be stopping after a given amount of time.

Thanks mate, and sorry to be a pest.

I actually got everything working and was meaning to post an update for anyone who might be interested. I found that the code was getting stuck in either of the two while loops that are used to help calculate the distance reading.

I ended up ‘borrowing’ a script that is a bit different to the one I posted above, though I experienced the same issues. Some further research showed me that I’m certainly not the only one who encountered this, and the answer was to add a counter to each loop. The counter when expired, would work to break the loop out, send a new ping from the sensor and take another reading.

Further to this, I found that when this new code would break a problematic loop, the script was crashing stating that the start / stop variable were not defined before they were referenced. My answer to this was to simply assign an initial value to the variable.

I’m not sure if any of this is good coding, I don’t pretend to call myself a developer, but everything works as desired so I’m happy.

I’ll post the code and a few happy snaps of the finished product in action when I get a chance.

Thanks again for all your help.

1 Like

As promised, and for anyone who is interested here is the final working code for this project. I may (as suggested by Stephen earlier) try to implement something which switches the red LED off after a while, but all in all I’m pretty happy with how this all came out. I’ve also posted a link to an updated photo gallery of the finished article.

Script:

Parking-Sensor2.py

Measure distance using an ultrasonic module

in a loop.

#------------------------

Import required Python libraries

-----------------------

from future import print_function
import time
import RPi.GPIO as GPIO

-----------------------

Define some functions

-----------------------

def measure():

This function measures a distance

new_reading=False
counter=0
counter2=0
start = time.time()
stop = time.time()
GPIO.output(GPIO_TRIGGER, True)

Wait 10us

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

while GPIO.input(GPIO_ECHO)==0:
pass
counter += 1
if counter==5000:
new_reading=True
break
start = time.time()

while GPIO.input(GPIO_ECHO)==1:
pass
counter2 +=1
if counter2==5000:
new_reading=True
break
stop = time.time()

if new_reading:
return False

elapsed = stop-start
distance = (elapsed * speedSound)/2

return distance

def measure_average():

This function takes 3 measurements and

returns the average.

distance1=measure()
time.sleep(0.1)
distance2=measure()
time.sleep(0.1)
distance3=measure()
distance = distance1 + distance2 + distance3
distance = distance / 3
return distance

def no_light ():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.LOW)
def green_light():
GPIO.output(GREEN, GPIO.HIGH)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.LOW)
def yellow_light():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.HIGH)
GPIO.output(RED, GPIO.LOW)
def red_light():
GPIO.output(GREEN, GPIO.LOW)
GPIO.output(YELLOW, GPIO.LOW)
GPIO.output(RED, GPIO.HIGH)

-----------------------

Main Script

-----------------------

Use BCM GPIO references

instead of physical pin numbers

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

Define GPIO to use on Pi

GPIO_TRIGGER = 4
GPIO_ECHO = 18
GREEN = 17
YELLOW = 27
RED = 22

Speed of sound in cm/s at temperature

temperature = 25
speedSound = 33100 + (0.6*temperature)

print(“Ultrasonic Measurement”)
print(“Speed of sound is”,speedSound/100,"m/s at ",temperature,“deg”)

Set pins as output and input

GPIO.setup(GPIO_TRIGGER,GPIO.OUT) # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN) # Echo
GPIO.setup(GREEN,GPIO.OUT) # Green LED
GPIO.setup(YELLOW,GPIO.OUT) # Yellow LED
GPIO.setup(RED,GPIO.OUT) # Red LED

Set trigger to False (Low)

GPIO.output(GPIO_TRIGGER, False)

Allow module to settle

time.sleep(3)

Wrap main content in a try block so we can

catch the user pressing CTRL-C and run the

GPIO cleanup function. This will also prevent

the user seeing lots of unnecessary error

messages.

try:
while True:

distance = measure_average()
print("Distance : {0:5.1f}".format(distance))
time.sleep(0.1)
if distance >= 90:
        no_light()
elif 88 > distance > 40:
        green_light()
elif 38 > distance > 16:
         yellow_light()
elif  distance <=14:
         red_light()

except KeyboardInterrupt:

User pressed CTRL-C

Reset GPIO settings

GPIO.cleanup()

Google Photos Link - https://photos.app.goo.gl/HFCBzBYbQXewVT4F7

Again, a big thanks to Stephen for putting up with all my silly questions and for all the help along the way.

2 Likes

Great work Shane!

Hi.
When I enter the code in. I get the issue that says:
Syntax Error: ‘return’ outside function. Can you please tell me how to fix this?

Hi Stephen.
This is in regards to the original code that Shane53869 put up (the one with the images) Forum Reply number 6

When I enter the code in on my raspberry pi and on Thonny. i format the code etc. when i try to run it I get the issue that say:
Syntax Error: ‘return’ outside function. Can you please tell me how to fix this?
Is this an issue caused by me formatting the code? If possible can you upload this code again but in the right way?

Hi Neehal,

Its been a good while since I put this project together, and we’ve since moved house so it’s actually just sitting in my shed doing nothing.

Also, its been ages since I looked at this, or any other python code and in all honesty, I don’t pretend to know what I’m doing with python so I can’t really offer much help. I suspect its probably an issue with how the formatting has translated, when I originally cut and paste it to the forum.

Let me know if you’re still having trouble, and I could dig it out, fire it up and copy the python file up here for you.