Create a proximity sensor for your garage – Part 1/2 – Measure a distance with a HC-SR04

If you don’t have a reverse backup radar system in your car, or if you park forward in your garage, you probably know this feeling of “am I too close, am I gonna hit the wall??”. Well, in this 2 part tutorial, we’re going to create a simple system to detect how close to the wall your car is.

In this first part we’ll learn how to measure a distance with a HC-SR04 ultrasonic sensor and a microcontroller. A LCD display will be used to test our system. In the next part, we’ll put together a lightweight, intuitive way to display the proximity to the wall. This will allow us to get rid of the LCD display, and make our application much lighter.

Bill of Material

There are many microcontroller options to choose from, but I’ll use a PIC16F88 for this tutorial. Although using an Arduino would be easier, it’s much more interesting to go a bit deeper and discover some more advanced functions of the PIC. In addition to the usual components for a bare PIC circuit (see this tutorial for a reminder), we’re going to need:

  • A 16*2 characters LCD display, preferably based on a HD44780 controller. I use this one from Adafruit, which has the advantage of being sold with a pin header soldered. Also prepare a resistor for the brightness, and a potentiometer for the contrast.
  • A HC-SR04 ultrasonic sensor. Here is a $10 5-pack from Amazon.
  • For part 2 of the tutorial, we’ll need 4 LEDs and 4 resistors.

Build the circuit


Let’s first connect the ultrasonic sensor. It has 4 pins: Vcc, Trig, Echo and Gnd. To use it we’ll generate a high pulse on the trigger pin, and then the echo pin will generate a high signal which duration will tell us how long it took for the sound to go from the module to the obstacle and back.

HC-SR04 ultrasonic sensor

Connect Vcc to your +5V power supply and Gnd to the ground. Connect Trig to the pin RA6 of the PIC (pin 15) and Echo to RA7 (pin 16).

LCD display

Similarly to what we did in this tutorial, we’ll connect the Enable pin to RA0, and the RS pin to RA1. You can tie R/W to ground, as we won’t need to read data from the LCD display. Connect Vss to ground, Vdd to +5V, and Vo to a potentiometer like shown below. If your LCD display has a LED backlight, connect LED+ to +5V with a series resistor (I use 330Ω in this example), and LED- to ground. Now connect the data pins D4-D7 to RB4-RB7 on the PIC. We’re going to use the 4 pin mode to control the LCD display to save 4 pins on the PIC, so we won’t need data pins D0 to D3.

Full circuit

HC-SR04, LCD display and PIC


Some maths

We need to do a bit of math to find out how to get the distance, when the sensor gives us a duration. As a reminder, the HC-SR04 will output a high signal on its Echo pin, and the duration of this signal will be the time it took for the signal to travel from the Trig pin, to the object and back. So we’ll need to divide this time by 2. We’ll see how to calculate a time with the PIC later on. Let’s assume we have this time in seconds.

The speed of sound is v=340.3 m/s, which is v=34030 cm/s. Speed is calculated as v=d/t, with d being the distance, and t the time.

So the distance will be equal to d=v*t, which is d=(34030*t)/2. This gives us d=17015*t.

Logic for the HC-SR04

We are going to use the Timer1 on the PIC. Let’s configure it, using the T1CON register. First, set the clock source to be the internal clock. This means that the frequency of the clock used by the timer will be Fosc/4, in our case 2MHz, as our clock is set to 8MHz. We can disable the timer1 oscillator, as we are using the internal clock as a source. Turn the timer OFF initially, and set the prescaler to 2:1. This means that the frequency of the timer will be half of the clock source, which is 1MHz. That is, every 1us, the timer value will increase.

This gives us time_s = timer_time / 1000000. And so d=17015*timer_time/1000000, which is d=0.017015*timer_time, or d=timer_time/58.77.

Let’s put the code specific to the HC-SR04 into separate dist_measuer.c and .h files. Here is the content of the header file:

Here is the function HCCalculateTime(), which sends a signal on the trigger pin, and calculates the time during which echo stays high.

Finally, here is the function HCCalculateDistance(). It simply calls HCCalculateTime() and divides the time by 58.77.

You’ll notice that I used a type uint16_t for the time and the distance. This is because the timer saved its value in 2 8-bit registers, giving us a size of 16 bits. As for the distance, we could use a type uint8_t, but it would be limited to 255cm, which is 2.55m.

LCD library

We’ve already seen in this tutorial how to interface a HD44780-based LCD display to a PIC. The only difference is that here, we’re using the 4-bit mode to control the display. This means that anytime we want to send data on the data line, we’ll need to send the 4 MSB first, and then the 4 LSB.

To make things easier, I’ve written a small LCD library for 8 bit PIC microcontrollers. You can find it on my Github page. Simply add the files LCD.c and LCD.h to your project, and change the name of the pins in LCD.h if you’re using different pins.

Full code

You can find the full code for this project on this Github repository. Here is the main loop of the program:


Here is the result on a video.

If you have any question, feel free to post a comment below.

1 Trackbacks & Pingbacks

  1. Garage Distance Sensor Kicks Tennis Ball To Curb – High Tech Newz
%d bloggers like this: