Introduction: Ultrasonic Garage Parking Assistant With Arduino and an ATtiny85

Hello fellow makers, I want to share with you a simple project that I have put together. I am new to prototyping/circuits and only took two semester of Java courses, so when I went looking for simple projects to build my skills, I was disappointed at how complex some of the code I saw was. While there are many other projects out there, with almost exactly the same in functionality, they were just too complex for the simplicity of the project. I believe I have put together a version that is much simpler and one that anyone can follow. In doing so, there may be some sacrifices in robustness(delay haters) but It works great so who really cares. 

Let's talk about the exact functionality. We are sensing distance all the time and have an rgb LED to indicate whether to keep coming, slow down, stop, or go back. A button is used to store the current distance as the desired parking distance. Even though the LED is super low power consumption, I am an environmentalist, so lets program in a power save mode to turn off the LED when there is no car in the garage and around 30 seconds after the car has parked in the right spot. Also, we cannot expect that the car will be parked at the exact, down to the inch, distance it was set at, so we will include a range of about 6 inches. You don't want to end up moving back and forth a dozen times before you get in right*. This is a big improvement over ones you can buy at Home Depot that only have 1, 2, and 3 foot distance settings and only 3 indicator stages. Plus, all the big box store ones look cheap and all have this ugly two part design where the LED or sensor are on a pull string. Not what I want in a classy garage.

If you then want to make it smaller, cheaper and more permanent, plus, not have to leave your Arduino in it, flash the software over to an ATtiny85-20PU.  We will go over all the required steps to use the Arduino as the ISP to load the software to the ATtiny.


First lets gather some parts along with some approximate prices
$15 - Arduino(any will do)
Projet housing
$3 - HC-SR04 Ultrasonic distance sensor
$4 - Breadboard
$1 - RGB LED (I prefer one that has a high brightness rating and is frosted) 
$2 - Button
$1 - 3 resistors ~ 220 ohm (this all really depends on the strength of the LED you choose)
      1 resistor ~ 10k ohm ( button)
$1 - Jumpers 
$3 - Power supply - You have a few options here depending on whether you chose to leave the Arduino board inside or use the ATtiny85

If you choose to use the ATtiny then you will need
$2 - ATtiny85
$2 - DC input jack
$1 - 5V regulator
$1 - 2x 10uf electrolytic capacitors 

~ or ~

$4 - Breadboard power supply



Step 1: Build a Project Box

A great project box for this tupperware. It is particularly good because it is most of the time transparent and even better, it is often frosted. This is all important in spreading the light of the LED to make it as visible as possible. Also, its widely available, cheap and easy to cut. I used the plastic box that came with my Arduino starter kit, which turned out to work quite nicely.

Cut two holes for the ping sensor

This by far the trickiest part. You want try to get them as snug as possible so that you dont have to get out the hot glue gun. The sensors are 16mm wide, so its doubtful that the average person has a drill bit of that nature lying around. This may not be the most orthodox method of cutting holes but with the soft plastic, it worked for me. 

First, I drilled a pilot hole in the exact center of where each whole needed to be.

Using some sharp scissors, I pushed it through the hole and twisted* allowing the wedge shape of the scissor blade to widen the hole as I twisted until it was wide enough for the sensor to fit through.

Repeat for the other sensor hole.


Cut a hole for the button

Placing the button on the exterior of the box is crucial for easy access to setting your desired distance. A button with threads and a nut are perfect for this. 


Cut a hole for the power plug

Depending on how you plan to power the device will affect what kind of hole you make, I used a 5.5x2.1mm DC power jack to connect it to  a 9V power adapter.

Step 2: Wiring the Circuit

To make this easier to understand lets break the circuit into 3 parts. The LED, the Button and the Ping sensor.
Note, in the photos, I have wired my rails backwards. This is to accomodate the 5V regulator(optional). I realize now that I could have turned it around, used the other rails to not have it backwards but owell.

UPDATE: Adjustment have been made to the circuit diagram. (not reflected in photos) The LED has been routed to pins 0 & 1 in order to use PWM for brightness control. This is important in getting a nice yellow color. 

The LED
Connect the common cathode (longest pin) of the LED to a 5V rail on your breadboard. The other 3 pins, require a resistor between them and the connection to the arduino I/O pin. Here is a helpful website to find the kind of resistor you will need http://led.linear1.org/1led.wiz. This is a pull up style circuit so the code will be inverted, high will be off and low will be on. You may use a resistor on the common cathode to not have this situation. I did this because I did not realize the ATtiny85 had pwm pins and I wanted to dim the green LED some by adding 2 resistors. When using red and green to make yellow, green was just too dominant over red an it looked yellow-green. A future fix is to move the green connection to a pwm pin and dim the green via pwm. Here's a link to a more complete tutorial on LED circuits http://www.ladyada.net/learn/arduino/lesson3.html

The Button
Connect 5V to a lead of the button. Connect a 10k ohm resistor between ground and the other lead on the button. Connect a jumper from the arduino to the ground lead of the button. While a common breadboard button will work okay, but if you plan to move it into a project box, it may be a hassle to reach the button. We want to have easy access to the button so that you won't have to move the sensor to press the button, that would make setting your distance quite difficult. I used a threaded momentary button from radio shack. Im not sure if it needs the resistor like the smaller breadboard button but I left it in and it works fine.  Here's a link to a more complete tutorial on buttons http://arduino.cc/en/tutorial/button

The Ping Sensor
Simply connect 5V and GND to your corresponding rails and the echo and trigger pins to the arduino.
Here is a link to the NewPing library which describes all the functions of sensor. http://playground.arduino.cc/Code/NewPing.

Congratulations, your circuit is finished! 

 

Step 3: Upload the Code to the Arduino

First off, dowload and install the latest Arduino IDE (1.0.5) here's a link to the download page http://arduino.cc/en/Main/Software.
We now what to install the NewPing library, Here is a link on instructions to download and install the NewPing library http://playground.arduino.cc/Code/NewPing.

If you plan on using the ATtiny then part of the file NewPing.cpp must be edited. There are two big section of the code devoted to timers, comment all of this out. NewPing.h can be left alone.

It is important to use this library and NOT to perform the distance measurement manually. The reason is because when the ping sensor cannot return a distance, it will delay for a full second instead of multiple times per second like it should. This is a problem when pulling the car in and there is no response from the unit for a brief period. In that time a car can move several feet and make the device useless. This library fixes that issue thus maintaing responsiveness. 


The pin arrangement will be however you chose to connect up your arduino board, so be sure to adjust this code to work with your circuit. Remember, if you want to use pwm to get your color brightness just right be sure to use pins with a ~ symbol for your LED or refer to the ATtiny85 pinout diagram for pwm pins. I did not include any use of the blue pin, simply because the ATtiny85 does not have enough pins without reprograming the reset pin to be I/O. I didn't bother to do so.

You may want to add some new colors or change it up to suit your mood. If you need a more precise indication, you may want to lower the range value to 1 or 2 (keep in mind that its +/-, so a 2 for the range variable will give a 4 inch range) or bring it up higher if you have room to spare. You may also want to edit the distances at which each color of LED will change. I found 120 and 50 inches to be just right. 


UPDATE: LED has been moved to pins 0 & 1. The yellow() method has been updated to include PWM. You may have to find which values work best with your LED. 


Code

#include <NewPing.h>            //include the NewPing library

//I/O pins

int rLED = 0;
int gLED = 1; 
int buttonPin = 2;
int echo = 3;
int trigger = 4;



//values to keep track of
int distance = 0;
int set = 0;
int upper = 0;             
int lower = 0;
int range = 3;                                   //range is +/- so it is double the value in inches
int count = 0;
boolean lastButton = LOW;          //keep track of button status
boolean currentButton = LOW;
int previous = 0;                              //keep track of distances to identify when car is parked
int current = 0;

NewPing sonar(0, 1, 500);       //constructor for NewPing sonar(triggerPin, echoPin, max_CM)

void setup()
{
pinMode(gLED, OUTPUT);
pinMode(rLED, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop()
{
  distance = sonar.ping_in();                  //detect distance in inches
  if(distance == 0) distance = 500;          //if no distance is read, set at max distance
  current = distance;                                //to check how long car has been parked in order to enter power save
 
  delay(100);                                             //Slow program down - save battery?
 
  currentButton = debounce(lastButton);            //reads button status and performs debounce, fixes unexpected button behavior
 
  if(lastButton == LOW && currentButton == HIGH)          //when button pushed, set desired distance for parking
  {
    set = distance;                                //new variable for distance measured
    flashGreen();                                  //flicker green LED 3 times
    flashGreen();
    flashGreen();
  }
 
  lastButton = currentButton;            //reset button status
 
  upper = set + range;                        //  +/- inch tolerance range 
  lower = set - range; 
 
  if(distance <= upper && distance >= lower)            //within set area, stop!
  {
    //distance fluctuates some resulting in false movement detection
    if(current == previous || current == previous + 1 || current == previous - 1 )
    {
      count++;                           //increase count if car has not moved
    }
    else
    {
      count = 0;                          //resent count if there is a significat change in distance
    }
   
    // if distance doest change for 250 cycles (30 sec) turn off LED -> power saving mode
    if(count >= 250)
    {
      off();
      count = 250;                        //dont increment forever
    }
    else
    {
      red();                                   // within range, stop. red LED on
    }
   
  }
  if(distance > upper)
  { 
    count = 0;                            //if car moves slow enough, it may never reset the count in above code, we reset again, just in case
                                       
    if(distance >= set+120)              //sensor becomes innacurate at distances much further than 120 inches
    {                                                   //no car in garage turn LED off 
      off();
    }                                              
    if(distance < set+120 && distance > set+50)                  //car is detected
    {                                                                                           //if distance is less than set + 120 inches and greater than set +50 inches
      green();
    }
    if(distance <= set+50 && distance > upper)                  //wihtin 50 inches of set distance, slow down
    { 
      yellow();
    } 
  }
  if(distance < lower)                                                           //car is too close, you must back up
  {
    count = 0;                                                                         //same situation for if car moves very slowly
    flashRed();
  }
 
  previous = distance;                                                        //update distances
}                                                                                            //end of loop

//debounce method to correct for voltage spikes that cause unexpected behavior
boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(buttonPin);
  }
  return current;
}

//color methods;
void green()
{
   digitalWrite(rLED, HIGH);                 //because of pull-up resistor circuit, code is inverted
   digitalWrite(gLED, LOW); 
}
void red()
{
  digitalWrite(gLED, HIGH);   
  digitalWrite(rLED, LOW);
}
void yellow()
{
  digitalWrite(rLED, 0); 
  digitalWrite(gLED, 100);
}
void flashRed()
{
  digitalWrite(gLED, HIGH);                     //flash red LED
  digitalWrite(rLED, LOW);
  delay(100);
  digitalWrite(rLED, HIGH);
  delay(100);
}
void flashGreen()
{
  digitalWrite(rLED, HIGH);
  digitalWrite(gLED, LOW);                  //flicker green LED when button pushed
  delay(50);
  digitalWrite(gLED,HIGH);
  delay(50);
}
void off()
{
  digitalWrite(gLED, HIGH);                  //turn off the LED
  digitalWrite(rLED, HIGH);
}


End of Code



Copy and Paste the code into the Arduino IDE and hit upload.

Again, be sure to edit the pin numbers to accomodate your circuit and make whatever changes you wish. 




Step 4: Uploading the Software to an ATtiny85

In order to make this project more permanent, cheaper, smaller and all around more legit. I will show you the steps required to shrink all of this down to a chip the size of your thumbnail.

First we need to install ATtiny support to Arduino IDE. 
Locate your Arduino sketchbook folder (you can find its location in the preferences dialog in the Arduino software)
Create a new sub-folder called “hardware” in the sketchbook folder, if it doesn’t exist already.
Download attiny-master.zip folder from below and copy the “attiny” folder (not the attiny-master folder) from the unzipped ATtiny master.zip to the “hardware” folder. You should end up with folder structure like Documents > Arduino > hardware > attiny
Restart the Arduino development environment.
You should see ATtiny entries in the Tools > Board menu.
A great tutorial to this can be found here http://hlt.media.mit.edu/?p=1695


Uploading software to ATtiny85
The Arduino board can be used as a programmer for the ATtiny chips. To do so plug the ATtiny chip into a breadboard and wire a breadboard in the following way.
1. With jumpers, connect VCC to 5V and GND to GND. Connect pin 10 to Reset, 11 to pin 0, 12 to pin 1, 13 to pin 2.
2. Open the program ArduinoISP from File -> Examples -> ArduinoISP. Upload it to the board.
3. Connect a 10uf capacitor between Reset and GND of the Arduino board.
4. Now open a blank program, only void() and setup() methods are present and are blank. (Im not sure about this step but I tried doing it with code in it and it broke the ATtiny) 
5. Select from Tools -> Board -> ATtiny85 (internal 8MHz clock)  and select from Tools -> Programmer -> Arduino as ISP. Upload the blank program. (you should see 2 avrdude errors. Not to worry, this is normal)
6. Select from Tools -> burn bootloader. This changes clock speed from its default 1MHz to 8MHz.
7. Now go back to the parking sensor code and upload it. Be sure to have the correct board and programmer selected. (you should see the same two avrdude errors)

If everything went smoothly, carefully pull the ATtiny out and transplant it back into your breadboard circuit.

Next, we need to modify the circuit. Because we are removing the Arduino board from the equation, we are also losing its regulated power supply, so we need to make our own. This will require 2x 10uf electrolytic capacitor and a 5V regulator.


The Regulator
Connect the incoming positive voltage to the input lead and the negative to negative lead of 10 uf capacitor, connect these two leads to their respective input and negative pin on the regulator. Arrange this on the bread board so that a the negative and output pins are plugged into a vertical rail. Add another 10 uf capacitor after the 5V regulator on the vertical rails, to their respective lead, of course. The capacitors smooth out the voltage. I am using a 9V DC power adapter, this is low enough to not require a heat-sink on the regulator but if you go higher, then you might need to add one. Now that the circuit is modified, let's get it on* the ATtiny85. Here is a helpful instructable that I used myself https://www.instructables.com/id/How-to-make-your-own-Arduino-board/step3/Adding-the-5v-regulator/.

All that's left is to connect up a power source!


Future Changes
Switch the 5V regulator to have the correct corresponding +/- rails.
Use the calculated resistors for the LED
Use PWM to adjust brightness to get yellow just right
Add a piezo element for an audible indication
Use an RGB LED strip instead of just one LED.
Construct a bamboo housing.


Comments

author
AliC38 made it!(author)2016-04-30

I made it too. Used an addressable RGB LED which allowed any color from a single data pin. Thanks for posting this! The AtTiny85 bit was the best.

IMG_6875.JPGIMG_6872.JPGIMG_6876.JPGIMG_6886.PNG
author
AliC38 made it!(author)2017-03-10

I've posted my version of the code on Github:

https://github.com/acheaito/arduino-garage-parking

It supports 4 colors/zones and was refactored to improve readability.

author
geocacher2 made it!(author)2016-07-26

I made it also. However, I struggled a bit with the tiny digi board. I ended up just using an arduino uno, and old fashioned wall wart power supply. It works great. The sonar sensor is quite sensitive to the board I screwed it onto ( I just drilled out a piece of wood) . You can't let it touch the edge of the round emitter, or you get lots of bad readings. I used an old Hammond box, and added some blue tape for style.

Thanks for the instructions !

IMG_1943.JPGIMG_1947.JPGIMG_1951.JPGIMG_1952.JPGIMG_1953.JPGIMG_1955.JPG
author
doart made it!(author)2015-12-14

Hi, I have just completed this on the breadboard with the Attiny85 however I could not get it to work the green LED just stays on I have checked and recheck my wiring but could not get it to work need some help and direction to resolve this. Tried it with 2 different IC's but did not help. How can I confirm that the code was uploaded OK. Many thanks

author
dannytaki made it!(author)2014-12-19

Hey I made it! Thanks for the project it was fun, and I learned a lot about soldering :).

P1000343.JPGP1000344.JPGP1000345.JPGP1000339.JPG
author
grumpyboots made it!(author)2014-06-19

Would you be kind enough to post a video of this device in operation, and perhaps a walk through of its operation?

Would love to see this thing run.

Cheers from BC Canada

author
carlos66ba made it!(author)2013-08-01

VERY NICE! Been trying to think on how to use NewPing with the Attiny85. Could you give more details on what needs to be edited on NewPing? (e.g., list the diff file, or the section that needs to be edited). Sorry, I am a Noob :)

author
HelmutHound made it!(author)2013-06-05

Very handy! Do you have an estimate of the cost of parts? What are the capabilities of the pinger? Would this build work as a property proximity light (security light)?

And can't wait till you do the additions you are talking about! Would you kindly take photos of the modified bread board once completed? And do a schematic? I find both extremely helpful! Great job!

author
martzsam made it!(author)2013-06-21

I took the risk in ordering one of these ultrasonic sensors from china, and damn has it payed off. They are solid and reliable, and work up to 3m! The only issue I have is they use the 4 pin connector instead of 3 like the Ping)).

author
rclymer made it!(author)2013-06-24

I am using the 4 pin one like you describe, how is it an issue over the 3 pin? An issue in that more pin real estate is taken up or in performance over the Ping?

author
martzsam made it!(author)2013-06-24

I have never used the three pin device because of its price, but as far as I can tell the only downsides are yes the use of space, and the slight added difficulty in programming. There doesn't seem to be any performance issues whatsoever.

author
Ranganathan+Srikanth made it!(author)2013-06-23

Hi, this weekend I attempted to make a similar version and I found that the values from the ping sensor, fluctuate very widely in the garage. inside the room, it was fairly stable. Any ideas how to stabilize the fluctuations?

author
rclymer made it!(author)2013-06-24

Yes, that was one of the problems I ran into while testing. I found that when approaching the sensor, it would begin to sense the car failrly late. I would only see the green light for just a moment and then yellow (appx 50 inches) and some occasional fluctuations between two values while the car is parked in front of it. This would cause it to exit "power save" mode unexpectedly.

I could not reproduce the poor detection at long range when I tested it in my living room. This leads me to believe that because the garage has so many more hard surfaces(cement floor and no furniture) that the sound waves reflect around the garage and these "old" waves will eventually hit the receiver and cause some bad readings. To improve this I could add some softer surface in the garage (rug, curtains, ect.)

I used this if statement to fix the small fluctuations. Because mine were only a difference of one inch I have a +/- 1.

//distance fluctuates some resulting in false movement detection
if(current == previous || current == previous + 1 || current == previous - 1 )

this means that the car must move at least two inches from the previous recorded distance in order to for the program to accurately enter and exit "power save mode". If you back out very slowly it may not break from this statement but that's not really important anyway.

What range of fluctuations are you experiencing? If it is more than a few inches, then you may have a faulty sensor or circuit.

author
HelmutHound made it!(author)2013-06-06

Yes, the bread board, and an amended schematic (I've always liked when peripherals / attachments had different colored wiring than the main body, but that is just my OCD showing). :p

author
rclymer made it!(author)2013-06-05

Thanks for your comment! This is indeed a very inexpensive project, especially if you're willing to wait for parts from China. I will append this into the instructable as well. Soon there will be a kit available with all of the necessary parts including a preprogrammed ATtiny85! Everything you need all in one package, shipped fast from the US. Until then, here is an approx price list.

Arduino UNO ~ $15
Breadboard ~ $4
HC-SR04 Ping Sensor ~ $3
ATtiny85 ~ $2
RGB LED ~ $1
5V regulator ~ $2
Button ~ $2
Resistors ~ $1
Capacitors ~ $2
Jumpers ~ $1
DC power jack ~ $2

I shall get to work on a schematic. The modified circuit is shown in the instructions. I simply added a 5V regulator and two capacitors to allow fro the ATtiny. Do you mean the modified breadboard after I make the future changes?

The ping sensor has some fairly impressive realtime distance measuring capabilities for hard objects that are directly in front of it. If you move your hand just inches away from direct line of sight, or try to detect the distance of something soft, like a pillow, it cannot detect it. If your area you intend to monitor was a sort of bottleneck, like a hallway or doorway, It could act as an effective sonic tripwire, but would not do a good job in a wide area. I would suggest a PIR motion sensor for security uses.
I hope this was helpful, I look forward to more comments.

About This Instructable

44,655views

135favorites

License:

Bio: I burnt the cider.
More by rclymer:Super Secret Lock Box w/ Capacitive TouchUltrasonic Garage Parking Assistant with Arduino and an ATtiny85
Add instructable to: