Projects

Parking Pal

The Ultrasonic Parking Sensor

Johann Wyss

Issue 20, March 2019

This article includes additional downloadable resources.
Please log in to access.

Log in

Take the guesswork out of parking your car in the garage with this easy to build ultrasonic parking assistant.

BUILD TIME: 2 Hours
DIFFICULTY RATING: Intermediate

Many of us have been in the situation where we’ve driven into the garage only to realise we didn’t drive in far enough because the garage door won’t fully close. Or worse, where you’ve driven too far in and touch parked against the wall or workbench! With this simple device, you can take away the guesswork and know exactly when you’re in far enough to close the garage door.

This is a relatively simple project. It uses an ultrasonic sensor to calculate the distance to your car, then when you are within a set distance, it lights up. To make the device useful, we have given it four distinct settings; Red, Yellow. Green and all off.

HOW IT WORKS

The two major components of this project are the distance sensing module and the display. I chose the HC-SR04 ultrasonic distance sensor because it is commonly available, affordable and versatile. Whilst other options like lidar and infrared sensors are available, they are generally much more expensive or don’t have the capabilities to measure the distances we required for this project.

The display side of things was not as easy to decide. We considered many options including 7 segment displays that would display the distance in centimetres, and even a series of LEDs to light up according to the distance. Both of which would require added circuitry to drive them. In the end, we decided to take the simplistic approach and use the Adafruit Neo pixel strip.

ULTRASONIC DISTANCE SENSOR

The HC-SR04 ultrasonic distance sensor is very simple to use. It works by emitting a non-audible pulse, which bounces back to the receiver if there is an object in front of the sensor. Since we know the speed at which the pulse travels, the sensor simply measures how long it takes for the signal to bounce back and then converts the time into a distance figure. This figure is then simply divided by two, giving us a fairly accurate distance measurement.

ADAFRUIT NEOPIXEL STRIP

The Adafruit NeoPixels are, by far, the easiest individually addressable LED string I have ever used. They have all the driving circuitry built-in and are controlled via a single wire interface. This means these LEDs each have their own controller built into them, making it possible to control each individual LED. You can change any of the individual LEDs colour, brightness or turn them on or off all using one pin of a microcontroller. The task of controlling the strings is made very easy for us thanks to the Library from Adafruit.

The Fundamental Build:

The Prototype

prototype
One of Johann's earlier prototypes with a single Neo Pixel LED connected.
fritzing
Parts Required:JaycarAltronicsCore Electronics
1 × Arduino Compatible NanoXC4414Z6372CE05101
1 × 8 RGB LED Strip ModuleXC4380-ADA1426
1 × Ultrasonic Distance SensorXC4442Z6322CE05112
1 × 330 Ohm 1/4W Resistor*RR0560R0040PRT-14490
1 × 1000µF Electrolytic CapacitorRE6316R5182COM-08982

Parts Required:

The first task for me was to build a basic prototype. I used a Neopixel LED strip, an ultrasonic distance sensor, and an Arduino Nano to get everything working together. Both the ultrasonic sensor and the Neo Pixels require very precise timing, so I was concerned that there would be interference between the timers that could affect performance. It seems that the two libraries worked together nicely, and I had absolutely no issues getting the two devices to interact together with the Arduino.

schematic

ELECTRONICS

Following the guidelines from Adafruit, I learned that it is highly recommended to have a very high value capacitor as close as possible to the Neo Pixel strip. This is, I assume, to prevent momentary dips in voltage created by sudden current fluctuations, which could cause the LED controllers to reset.

The Neopixel strip datasheet suggests that the module can quickly draw currents up to 500mA. However, my prototype averaged about 200–250mA at my chosen brightness settings.

The datasheet states it is also mandatory to have a resistor in series with the data input signal. I assume this is to protect the data input pin from excessive current.

THE CODE

The code can be downloaded from the Resources section of our website. The code has been written so it is easy for our readers to modify. The constant variables can each be changed to suit your own specific needs.

SAMPLES: Refers to the number of times the program will read the distance and is used for averaging the sensor values. The HC-SR04 is fairly accurate but it is prone to sporadic and intermittent false readings. Therefore, averaging the readings will help to avoid the unit being affected by false readings. Having a higher number of readings will slow down the program but will make it much less prone to false positives.

STOPTHRESH: The threshold at which point the sign will glow red, telling the driver to stop. This can be changed to reflect how far from the device you need to park. Simply park your car in the optimum position and measure the distance between the front bumper and the sensor in centimetres (cm) and enter it here.

CAUTIONTHRESH: The threshold in which the amber light will illuminate. You can pick any value you like here, provided its higher than your stopthresh value and lower than your maximum threshold value. I would pick a figure about 30cm larger than your stop value. That way you know you have 30cm before you must stop.

MAXTHRESH: The threshold in which the green light will illuminate. Make this figure larger than the caution threshold but less than the distance to your door. This way the light will not be illuminated all day while your car isn’t in the garage.

OFFTIME: The figure used to turn off the red illumination. The larger this number the longer it will stay illuminated. This is programmed in so that the device is not illuminated while a car is parked in the garage, and therefore wasting power.

NUM_LIGHTS: Is the number of neo pixels on the strip of LED’s you use. For this project I opted to use an off the shelf 8 LED strip however you can purchase these LEDs in lengths up to 5m, which can be cut every 3 LEDs and used in the exact same way, it’s completely up to what you want to do. Just add the number of LEDs in your strip in the NUM_LIGHTS variable.

This is a very simple code due to the awesome library for the Neo Pixel strip from Adafruit and the HCSR054 Ultrasonic sensor library.

The Adafruit NeoPixel library can be found here: https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation

The HC-SR04 library can be found here: https://github.com/Martinsos/arduino-lib-hc-sr04/blob/master/s

Once the libraries are installed, we need to define which colours we require in our code using:

uint32_t colour = strip.Color(x, x, x);

This sets the RGB value stored in the decimal code (red, green, blue) into a 32 bit register. To change the colour, for example, all you need to do is change the individual RGB values. You can use tools such as rapid Tables RGB chart to select very specific colours:

rgb table

From there we need to request a reading from the ultrasonic Sensor to be placed into a variable using the string:

dist = distanceSensor.measureDistanceCm();

This initiates a function stored in the library in which the sensor lets out a small pulse of non-audible (for human ears) frequency and waits to hear the response. When it receives the response, it calculates the distance using the known speed of sound and the time the response took to return. It then stores the resulting distance in Cm into the dist variable.

I chose to do this 50 times adding each result into a second variable avg so we can get an average result which reduces the potential for sporadic readings causing undesired results.

You simply take the sum of all the readings and divide it by the number of readings taken as shown here.

  while (count < SAMPLES){
    dist = distanceSensor.measureDistanceCm();
      avg = (avg + dist);
    count ++;
    }

After getting the average result it’s just a matter of checking that result against the chosen constant variables we mentioned previously. The program then reacts accordingly either turning the LED’s to a specific colour or off completely using the following code:

for( int i = 0; i<NUM_LIGHTS; i++){ 
  strip.setPixelColor(i, green); 
  strip.show(); 
}

Remember, this LED strip is designed to be individually addressable. Therefore, we need to tell each and every one of the 8 LEDs what colour we want it to be. Since in this project we want all the individual pixels to be the same colour at a given point, we need to tell them all to change to the chosen colour. The easiest way to do that is with this for loop. This loop causes each of the 8 LEDs to get sent the instruction to turn green via the decimal value we stored in the 32 bit register earlier.

So it is really that simple, have a crack yourself however if you get stuck or just want to build the device all of the code is provided on the website.

build

The Main Build:

Complete Parking Sensor

Additional Parts Required:JaycarAltronicsCore Electronics
1 × ATtiny85 IC ZZ8721Z5105COM-09378
1 × 8 Pin IC Socket PI6500P0550-
1 × 100nF Capacitor RC5360R2865CE05188
2 × 100µF Electrolytic CapacitorsRE6130R4825CE05258
1 × Switch SK0984S3210COM-08837
1 × 2.1mm DC Power Jack^ PS0522P0622ADA610
1 × Perfboard# HP9550-FIT0099
6 × 2-Way Screw Terminal Blocks HM3172P2032BPRT-10571
1 × Pack of Mixed Jumper Wires WC6027P1017PRT-14284
1 × 5VDC 1A Mains Power AdaptorMP3144M8903AM8904

Additional Parts Required:

Note: Hook-up wire. heatshrink, cable ties, small screws and crimp lugs are also required.

^3D case is designed for the Core Electronics ADA610 DC Socket

#3D case designed for Core Electronics FIT0099 Perfboard. Jaycar HP9550 will need to be cut down to fit.

schematic

I planned for the final build to be affordable and simple to build. The easiest way to do this, was to swap the Arduino Nano development board using the ATMega168 microcontroller, for the much cheaper and less overkill ATtiny85. Swapping to a 8-pin micro does make it a little more difficult to program the device, but we will explain this further in the prgramming section.

WIRING THE PCB

I used a standard off-the-shelf Perfboard PCB from Core Electronics to save time designing and milling or etching a PCB. The enclosure is also designed to mount this size board, however, you can easily get the device to fit on a much smaller PCB.

I added a decoupling 100nF capacitor in parallel with a 100µf capacitor, close to the VCC pin of the Attiny. Together, these will filter out high frequency switching noise from the power supply and ensure that there is a nice stable supply for the microcontroller.

I also added a 100µF capacitor to the VCC input of the ultrasonic sensor. Even though it isn’t mandatory to have this, I was just being over cautious given the possibility of a 500mA current draw on the LED strip.

I made tracks by running solder to make traces along the perfboard until all connections are made, as can be seen in the previous image.

3D PRINTED ENCLOSURE

print enclosure

The final stage of the build is the 3D printed enclosure. If you do not have a 3D printer, you will need to use Jiffy boxes or similar.

As always, I tried to make the print files printable without the need for supports to reduce wastage and the time it takes to print. I printed the parts on my Flashforge Creator pro using the Flashprint slicer. I printed everything using PLA at 0.200mm layer height.

BASE

base

I recommend printing the Base_Rev_b file in this orientation. It shouldn’t need support because the wire entry point should be small enough for your printer to easily bridge the gap. This part was designed to just fit into the build area of the Flashforge with a width of 150mm.

FACE

face

If you don’t have a dual extrusion printer you can just print Face_Rev_A and glue or tape cellophane to the rear to show the wording and diffuse the LED brightness.

If you have a dual extrusion printer, you can print the Face and Stop files together. I recommend using a translucent or natural PLA, in conjunction with a neutral colour. This seems to produce an eye-catching result.

I designed the parts to fit together easily. Just using the centre tool in Flashprint will cause both parts to perfectly align.

Take your time with this print because it can be a difficult part to print properly. It took me eight attempts to get the best print. It wasn’t until I turned off the air-conditioning in my workspace to stop the print lifting off the bed. I recommend you ensure your print bed is perfectly level, and there are no draughts in the room that could warp the print.

LED MOUNT

frame

This part is designed to house the LED strip. You simply solder some wire to the VCC, GND, and data in pins and then screw the LED strip to the rear part as you see fit.

REAR

back

The rear panel is designed to be printed flat on the bed. Like the Base, this part is designed to fit on the Flashforge build plate with a width of 150mm. Smaller printers will not be able to print this part without first scaling it to suit your build volume. The part is designed to be glued to the base after attaching to the wall via the screw locating lugs.

BOX

screenshot of box

This part houses the PCB, switch and DC jack components. The box is designed to be printed flat. Whilst you shouldn’t need support due to the small distance of the overhangs, it certainly would help if your settings are not 100%. You can minimise wastage by using the treelike supports in Flashprint.

LID

lid

The lid is designed to print without supports in the shown position. I used some hotglue to secure the Ultrasonic sensor to this part and connected it to the main board via Male – Female jumper wires. The part is then held to the box via a small dab of hotglue.

PROGRAMMING THE ATTINY

If you are new to programming outside of the Arduino environment, then DIYODE has an awesome article titled “Programming the ATtiny85” from Issue 9 that you should read. Furthermore, Issue 14 has a great article showing you how to build a programming shield for ATtiny boards, which simply fits over an Arduino UNO. This device will make it very simple to program the ATtiny microcontrollers. You can buy it as a kit at Altroinics (Part. K9815)

atdev
The completed ATtiny Microcontroller Programmer Kit from issue 14.

Out of the box, the ATtiny85 has its fuses set to run on the 8MHz internal oscillator. This program however relies on much faster timing. Therefore, we need to tell the microcontroller to run on a faster clock setting. i.e. 16MHz or 20MHz.

clock

If you built the Electronic Dice from Issue 19, you can use the same ATtiny, but select the 20MHz internal oscillator option in the Arduino IDE, and then click burn bootloader. That’s it! Nothing too scary huh? Now you can simply upload the program to the ATtiny85 by clicking the upload button.

THE CODE

Like the prototype, the code for this device can be downloaded directly from the website.

The code is almost identical to the prototype code. The only difference is that the pin allocation is designed to work with the ATtiny85 compared to the Arduino Nano.

assembly

ASSEMBLY

The assembly is quite straightforward. Some soldering will be required. You can use heatshrink, like you see in the photo for a much neater appearance.

DISPLAY

To assemble the display, you first attach the LED strip to the rear of the LED display holder using hot glue or other such adhesive. I centred the strip to the lettering in the hope that it would assist in diffusing the light, preventing to obvious hot spotting of the LEDs through the translucent face.

Next, using hot glue or similar you need to glue the display face to the front of the display assembly, making sure the hole for the wire is facing the bottom.

Next, you attach the main cable to the LED strip wiring. I used male and female headers to make the connection but you can use any system. i.e. solder, crimp terminals or dedicated plug, etc.

Then it is just a matter of using a few dabs of hot glue to glue the front assembly to the rear. (Don't go overboard on the glue! If you ever want to modify the device you need to be able to remove the front cover easily).

I recommend using a few zip ties on the wire leaving the enclosure. This will work as strain relief preventing the cable from being pulled and disconnecting the connector.

CONTROL BOX

I started assembling the control box by first adhering the ultrasonic sensor to the front of the box using hot glue. I then attached the wiring for the sensor to the screw terminals, as it would be quite difficult to do once the PCB is inserted. I then attached the wiring for the switch and DC jack to the PCB and secured the PCB to the box using screws.

I didn't leave as much room as I would have liked for the switch so getting it in was a little tricky. Just make sure you take it slow and be careful. To connect the switch, I simply routed the cable through the case, attached heatshrink to the cable, and soldered the wire to the switch terminals directly. I then applied heat to the heatshrink for a neat finish.

The DC jack is then connected in the same way. Just make sure you slide the washer and nut onto the wire, then pass the wire through the case. Otherwise, you may have to de-solder the wires and re-do it.

After soldering and shrinking the wires, you simply tighten the nut on the rear securing the jack to the enclosure.

You then simply attach the display wires to the PCB and seal the unit with a dab of hot glue.

I recommend mounting the sensor to the wall, using the four mounting holes, in line with a flat part of the cars bumper bar. This will help to reduce false triggering.

TESTING

The project requires 5VDC to operate. Do not run of a higher voltage to avoid damaging the components. Insert the power supply.

To test the device's operation, I simply put the assembled unit on my kitchen bench. Using a large book with the front facing the sensor and roughly level with the sensor, I would walk toward the sensor to simulate the car approaching. This confirmed that the display was behaving as I intended and changing colours at the desired distances.

Whilst this project works perfectly well for it’s intended use, there are a couple of limitations that I found.

First are the limitations of the ultrasonic sensor. These very inexpensive sensors only have a viewing angle of about 15°, therefore objects with sharper angles tend to bounce the signal back at incorrect angles. This can easily lead the sensor to incorrectly calculate the distance and produce rough results. To counter this limitation, it’s advised to have the sensor facing the car in a position to effectively bounce its sound signals off a flat surface. The front bumper or number plate is an ideal target.

diagram

Another limitation is power supply. In standby, it doesn’t draw much power (about 16mA), but it does consume about 250mA when illuminated. I have designed the project to be powered by a mains adaptor, but this does limit you where you can install it unless you run a power lead. You could consider modifying the project to use rechargeable batteries.

WHERE TO FROM HERE?

The first change I would make if building this project again would be to add a rechargeable cell capable of lasting over a month.

To crudely calculate the size of the battery we would require to power this device, we need to know the average current consumption of the device.

I measured the standby current on the breadboard to be around 16mA. Per day we can assume that the device will be illuminated for less than twenty minutes based on the turn off time and the program design.

This means for 20 minutes out of 1440 minutes, the power will be 250mA and the remaining 1420 minutes will be drawing 16mA.

(250mA × 20/1440) + (16mA × 1420/1440) = 0.01925A

Therefore, the average current is 19.25mA.

To calculate the required battery capacity, we can use the equation:

C = IT

C = Capacity, I = Current (avg) and T = time in hours

If we want to run the device for up to 30 days: T = 30 × 24

We know that I = 19.25mA, so: C = 0.01925 × 30 × 24 = 13.86

Now, this is just a basic calculation and does not take into account the losses in regulating the voltage and internal resistances etc. However, we can see that we would need a battery with a storage capacity exceeding 14Ah to run for 30 days.

Whilst lead acid batteries with this level of storage are inexpensive and readily available, their size makes them less than ideal for the application.

Lithium cells are an option, however, excluding the aforementioned losses you would need an array of six 2600mAh cells in parallel to get the required capacity. This means making the device battery operated is impractical.

Another option to make the device a little more personalised would be to add some animation to the LED module. Rather than suddenly change the colour from red to orange, for example, you could have it “morph” into the next colour by slowly changing the decimal RGB values in the 32 bit register, in relation to distance. However, slow changes don't tell you when to stop the way a sudden colour change does.

The last upgrade option would, of course, be to have it display the distance numerically. We could then display the distance between your sensor and your car. This would take a little more work and would require a larger microcontroller and a 7 segment driver, but it would be pretty cool!