Project tutorial
Rangefinder for Garage Parking with Arduino

Rangefinder for Garage Parking with Arduino © GPL3+

Park your car safely in the garage with Arduino!

  • 4,543 views
  • 1 comment
  • 15 respects

Components and supplies

A000057 featured
Arduino Leonardo
×1
Matrix display
(find it on internet stores)
×1

Necessary tools and machines

09507 01
Soldering iron (generic)

About this project

This simple project will help you park your car in the garage by displaying the distance from objects in front of your car's bumper. A 'stop' message will tell you when it's time to stop. The project is based on the usual HC-SR04 or Parallax Ping))) (tm) ultrasonic rangefinders and an Arduino board. I used the Leonardo but it should work on any other original or compatible board.

For the display I chose a matrix version for its size and for aesthetic reasons.

Step 1: What You Need...

To build this project you need:

  • An Arduino board:An original or compatible board should work as the code doesn't make use of specialized pins/function.You can find it everywhere on the internet or maybe you have one unused in a drawer in your lab.
  • Soldering skills, of course :)

Step 2: Build the Project...

Download the arduinorangefinder.pdf schematic diagram.You can find attached also the HC-SR04 pdf and the ping))) pdf, only for your reference.The electronic diagram is very simple, follow it exactly.I suggest to extend the wirings for the display and sensor of about 1 meter (see image1) so you can place them more easily later.

In the image2 you can see how to solder the power supply pins for the display and sensor: +5V from the display and Vcc from the sensor needs to be soldered togheter. Every other pin must have its own terminal.

Image5 is the Ping))) version of the project.Go to the next step when ready...

Step 3: Arduino Code...

It's time to work on the Arduino side.

Download the attached fourMatrix-master library (please use this library also if you already have it installed, this one was edited to support more functionalities) and install it from the IDE (sketch->import library).

Now load the MeasureDistanceV102.ino sketch and let's look into it.

There are several lines you can edit:The most important is the sensor type, uncomment only the line that match your sensor.Then choose your preferred measuring unit from centimeters or inches and uncomment only the right one.A warning has been set in the conditional compilation, it will show you what you have chosen.Now set the distances as you prefer, you can modify them later when the project will be in place.

Upload the code and check if all works.If you get trouble please double check wirings and connections.

Update 2017/12/30 - The code has been updated:

> Turn off the display when standstill at STOP distance for more than 10 seconds!

Update 2019/01/10 - The code has been updated:

> Added the possibility to choose the measuring unit from centimeters or inches

Step 4: The Project at Work...

Measure the height of the most prominent part of the bumper of your car from the floor.Attach the sensor close to the wall, to the height you measured.

I used a polystyrene foam sheet in which I made a slot for the sensor (see image).

Now place the display so you can see it from your car.

Try to enter by car and check the distances, adjust them in the Arduino code and reupload it if need.

Enjoy!

Code

fourMatrix-master.zipArduino
Four matrix display library
No preview (download only).
MeasureDistanceV102.inoArduino
Arduino code for this project
/* Arduino Range finder with HC-SR04 or Parallax Ping))) tm Sensor
  -- Changelog --
  2019-01-09 code version V1.02
  -Choose to show distance in centimeters or inches, select the correct #define below.

  2017/12/30 code version V1.01
  -Added a timeout to turn off the display when standstill at STOP distance

  2016/11/12 code version V1.00 open source by AppsByDavideV
  -First release
  --------------

  >Web:       http://appsbydavidev.duckdns.org
  >Facebook:  www.facebook.com/appsbydavidev.devCounter
  >Twitter:   https://twitter.com/appsbydavidev
  >Instagram: https://instagram.com/appsbydavidev/
  >Google+:   https://plus.google.com/112943455419093026838/posts
  >Youtube:   https://www.youtube.com/channel/UCNY3KkW72IEFlLiBgTBdoKw
  >Email:     vdavidex@gmail.com
  @appsbydavidev #appsbydavidev #arduinorangefinder


  This sketch reads a HC-SR04/Ping))) ultrasonic rangefinder and returns the
  distance to the closest object in range. To do this, it sends a pulse
  to the sensor to initiate a reading, then listens for a pulse
  to return.  The length of the returning pulse is proportional to
  the distance of the object from the sensor.

  How it works in this sketch:
  -The sensor checks range every pingDelay (ms)
  -The returned distance is processed with a digital low pass filter to keep it more stable
  -The result is compared with some constants (see #define below)
  -if the result is > OFF_DISTANCE the display is kept off (no messages)
  -If the result is in the range of FAR_DISTANCE to OFF_DISTANCE the message is Far..
  -If the result is below FAR_DISTANCE the distance is shown
  -If the result is below STOP_DISTANCE the message is STOP

*/

#include "Arduino.h"
#include <fourMatrix.h>     //display library

// Choose the sensor type
#define SENSOR_PING 1       //uncomment if you are using an Parallax PING))) tm range finder
//#define SENSOR_HCSR04 1   //uncomment if you are using an HC-SR04 range finder

// Choose the measuring unit
#define DISTANCE_CM 1       //uncomment for distance in centimeters
//#define DISTANCE_IN 1       //uncomment for distance in Inches

//Conditional compilation, thanks to:
//https://www.deviceplus.com/how-tos/arduino-guide/arduino-preprocessor-directives-tutorial/
//Note: to show compilation warnings you must go to preferences and set compiler warnings to 'default'
#if defined (DISTANCE_CM) && defined(DISTANCE_IN)
  #error "You must choose ONLY one #define for centimeters or inches"
#elif defined (DISTANCE_CM)
  #warning "Info: you choose distance in centimeters, compiling..."
  const String mUnit="cm ";
  const int OFF_DISTANCE = 120;   // Distance in cm for no messages (display off)
  const int FAR_DISTANCE = 70;    // Distance in cm for FAR message on display
  const int STOP_DISTANCE = 15;   // Distance in cm for STOP message on display
#elif defined (DISTANCE_IN)
  #warning "Info: you choose distance in inches, compiling..."
  const String mUnit="in ";
  const int OFF_DISTANCE = 50;    // Distance in inches for no messages (display off)
  const int FAR_DISTANCE = 28;    // Distance in inches for FAR message on display
  const int STOP_DISTANCE = 6;   // Distance in inches for STOP message on display
#else
  #error "You must choose a #define for centimeters or inches"
#endif


//Sensor pins for HC-SR04 or Ping)))
const int triggerPin = 6;       // Trigger pin, only for HC-SR04 sensor
const int echoPin = 7;          // Echo pin on HC-SR04 or SIG pin on Ping)))

//Measurement
unsigned int pingDelay = 100;   // How frequently are we going to send out a ping (in milliseconds).
unsigned long nextPing;         // Holds the next ping time.
unsigned long displayOff;       // Holds the timeout to turn off the display when at Stop position
const unsigned long DISPLAY_OFF = 10000; //time in mSec after that the display will be off

//Matrix display pin assignment
const int latchPin = 9;
const int clockPin = 8;
const int dataPin = 10;
const int checkPin = 13;        //arduino led on pin 13

unsigned int lastDistance = 0;
unsigned int val = 0;            //raw centimeters
unsigned int LPval = 0;          //centimeters after low pass filter
float lp = 0.4;                 //low pass smooth
boolean stopFlag = false;

fourMatrix m(dataPin, latchPin, clockPin, 4); // (datapin,latchpinn, clockpin,number of modules)

void setup() {
#if defined(SENSOR_PING)
  //setup for Parallax Ping))) tm
  pinMode(echoPin, OUTPUT);
  digitalWrite(echoPin, LOW);
#endif

#if defined(SENSOR_HCSR04)
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
#endif

  Serial.begin(57600);
  m.init(); //initialize display
  m.printMsgToMatrix(" Wait ", 0);

  nextPing = millis() + pingDelay;           // schedule next ping
}

void loop() {
  if (millis() >  nextPing) {           // time expired, make measurement
    val = pingVal(5);                   // make 5 readings from the sensor and calculate the arithmetic average
    LPval = LowPass(val, lp, LPval);    //smoothed value
    nextPing = millis() + pingDelay;    // schedule next ping  with last delay in case LPcm doesn't change value
    Serial.println("Average: " + String(LPval) + " ,Real: " + String(val) + mUnit);    //debug only, comment after test

    if (LPval != lastDistance) {
      lastDistance = LPval;                    //save new value

      if (LPval == 0) {
        //Reading error, check sensor connections
        m.clearMatrix();
        m.printMsgToMatrix("Error ", 0);
        stopFlag = false;
        pingDelay = 5000;
        nextPing = millis() + pingDelay;           // schedule next ping

      } else if (LPval > FAR_DISTANCE && LPval < OFF_DISTANCE) {
        //Far distance, show the 'FAR...' message if distance is between FAR & OFF
        m.printMsgToMatrix("Far... ", 0);
        stopFlag = false;
        pingDelay = 250;
        nextPing = millis() + pingDelay;           // schedule next ping

      } else if (LPval < STOP_DISTANCE) {
        //Stop distance, show a fixed stop message
        if (stopFlag == false) {
          m.clearMatrix();
          m.printMsgToMatrix("Stop!!! ", 0);
          stopFlag = true;
          pingDelay = 100;
          displayOff = millis() + DISPLAY_OFF;
          nextPing = millis() + pingDelay;           // schedule next ping
        } 

      } else if (LPval >= OFF_DISTANCE) {
        //Off distance, turn off display & slow down ping interval
        m.clearMatrix();
        stopFlag = false;
        pingDelay = 1000;
        nextPing = millis() + pingDelay;           // schedule next ping

      } else {
        //Distance in range of measurement, show distance on display & speed up ping interval
        String Blank = "    "; //4x spaces
        Blank.remove(0, String(LPval).length()); //adjust message length
        m.printMsgToMatrix(Blank + String(LPval) + mUnit, 0);
        stopFlag = false;
        pingDelay = 100;
        nextPing = millis() + pingDelay;           // schedule next ping
      }
    }
  }
  // Do other stuff here not related to ping
 
  //check if it's time to turn off the display
  if ((millis() > displayOff) && (stopFlag==true)) {
      m.clearMatrix();
   }
        
}


//Routines

//low pass digital filter
float LowPass(float Value, float filterValue, float LastValue) {
  if (filterValue > 1) {
    filterValue = 0.99;
  }
  if (filterValue <= 0)  {
    filterValue = 0;
  }
  return (Value * (1 - filterValue)) + (LastValue * filterValue);
}

//return distance in centimeters
long pingVal(int Reads) {
  //start measurement cycle by 10microsec pulse on trigger pin
  long Buffer[Reads];
  long average = 0;
  for (int i = 0; i < Reads; i++) {
#if defined(SENSOR_HCSR04)
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
#endif
#if defined(SENSOR_PING)
    pinMode(echoPin, OUTPUT);
    digitalWrite(echoPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(echoPin, LOW);
    pinMode(echoPin, INPUT);
#endif
    Buffer[i] = pulseIn(echoPin, HIGH);
    //Serial.print(String(Buffer[i]) + "\t");  //debug only
    delay(25);    //do not remove
  }
  for (int i = 0; i < Reads; i++) {
    average = average + Buffer[i];
  }
  //return the correct measure unit
  #if defined(DISTANCE_CM)
    return ms2cm(average / Reads);
  #elif defined (DISTANCE_IN)
    return ms2In(average / Reads);
  #endif
  
}

////return distance in Inches
//long pingIn(int Reads) {
//  //start meausement cycle by 10microsec pulse on trigger pin
//  long Buffer[Reads];
//  long average = 0;
//  for (int i = 0; i < Reads; i++) {
//#if defined(SENSOR_HCSR04)
//    digitalWrite(triggerPin, HIGH);
//    delayMicroseconds(10);
//    digitalWrite(triggerPin, LOW);
//#endif
//#if defined(SENSOR_PING)
//    pinMode(echoPin, OUTPUT);
//    digitalWrite(echoPin, HIGH);
//    delayMicroseconds(5);
//    digitalWrite(echoPin, LOW);
//    pinMode(echoPin, INPUT);
//#endif
//    Buffer[i] = pulseIn(echoPin, HIGH);
//    //Serial.print(String(Buffer[i]) + "\t");  //debug only
//    delay(25);  //do not remove
//  }
//  for (int i = 0; i < Reads; i++) {
//    average = average + Buffer[i];
//  }
//  return ms2In(average / Reads);
//}

//return Inches from uS
long ms2In(long microseconds) {
  return microseconds / 142;    //initial was 148, adjusted manually
}

//return centimeters from uS
long ms2cm(long microseconds) {
  return microseconds / 58;
}

Comments

Similar projects you might like

Garage Parking Sensor

Project tutorial by Chip McClelland

  • 8,405 views
  • 5 comments
  • 14 respects

Garage Parking Stop Light

Project showcase by Rich Noordam

  • 2,612 views
  • 0 comments
  • 11 respects

Arduino Automated Parking Garage

Project tutorial by ashraf_minhaj

  • 4,178 views
  • 11 comments
  • 24 respects

Automatic Sliding Door for the Garage

Project tutorial by DVDMDN

  • 15,294 views
  • 37 comments
  • 66 respects

The "Tennis Ball" Garage Stop Light

Project tutorial by Team Stuart Mace

  • 9,657 views
  • 2 comments
  • 36 respects

Making a Cheap Laser Rangefinder for Arduino

Project tutorial by iliasam

  • 4,036 views
  • 35 comments
  • 11 respects
Add projectSign up / Login