Sign In

Published by on

For sensing distance to obstacles, an HC-SR04 sensor module is a great choice. It can give you accurate distance to any obstacle in front of it. This can be used in several projects including high end robotics.

It has an ultrasonic transducer which generates the ultra sonic waves, an ultra sonic receiver and control circuitry built on a small PCB.

hcsr04 sensor

Front View of HC-SR04

hcsr04 sensor

Back View of HC-SR04

For interfacing with microcontroller it provides two lines namely TRIGGER and ECHO. The trigger pin is an input pin, the MCU sends a 10uS high pulse on this line to tell the HC-SR04 to start a taking a measurement.

triggering an HC-SR04 from PIC MCU

As soon as the HC-SR04 receives this pulse it sends out ultrasonic waves and waits for it to goto the obstacle and come back to the sensor. The sensor then emits a pulse on the ECHO line whose width is equal to this time. By simple calculation we can find the distance to obstacle.

hcsr04 echo pulse

Programming

All the programs available in this site is wriiten in C language. For PIC series of microcontrollers I always use the XC8 compiler from microchip. It it available free of charge from them!

To make to program configurable easily, i start off by defining constant for the PORT where we will connect our sensor. So that the user is free to connect the sensor on different i/o port and change the program to adapt is change easily.


#define US_PORT PORTA
#define US_TRIS TRISA

#define US_TRIG_POS  0
#define US_ECHO_POS  1

So now we will refer to the port where the sensor is connected as US_PORT (US stands for ultra sonic). We have also defined the position where the TRIG and ECHO pins are connected. So TRIG is connected to PORTA bit 0 or RA0 in short. In the same way ECHO is connected to RA1 of the PIC16F877A chip.

Then we also define a couple of constant for errors related to sensor.


#define US_ERROR     				-1
#define US_NO_OBSTACLE          	-2

We then define our first function to initialise the system. The initialisation is super simple. Just we need to set the direction of TRIG pin as out (that means RA0). By default all pins of microcontroller are input only, so we do NOT need to set the direction of ECHO pin, as we want it to be input type only.


void HCSR04Init()
{
   US_TRIS&=~(1<<US_TRIG_POS);
}

Problem understanding the above? Then you need basic knowledge about how i/o ports work in PIC16F series. Please see the articles given below for more information ...

We have simply cleared the bit denoted by US_TRIG_POS (that is 0) in the register US_TRIS. US_TRIS is alias for TRISA. Every i/o port in PIC MCU has a assoiated TRIS register that is used to set the direction (input or output) of each individal pin in the port.

Triggering the HS-SR04 Sensor

The next step is to develop a function to trigger the sensor. That means to send a pulse of 10uS (micro second) to the TRIG pin. This is done by the following function.


void HCSR04Trigger()
{
   //Send a 10uS pulse on trigger line
   US_PORT|=(1<<US_TRIG_POS); //high

        __delay_us(15);       //wait 15uS

   US_PORT&=~(1<<US_TRIG_POS);   //low
}

This function simply makes the TRIG pin high, then wait for 15uS and then makes this pin low.

Measuring the Width of Echo Pulse from the Sensor

This is the most complex and challanging task of the whole project. You need to precicly plan this part. I have used TIMER1 to measure the time.

  1. Wait for a rising edge on ECHO line. If edge is found start the timer, else if we have waited to long and seen no edge coming end the function and return error code.
  2. Now the timer is counting in micro second, we wait for the falling edge. As soon as we get a falling edge, stop the timer and return the time elapsed to the calling function. If we waited to long and seen no falling edge that means their are no obstacle in front of the sensor so return an error code.

int16_t GetPulseWidth()
{
   uint32_t i,result;

   //Wait for the rising edge
   for(i=0;i<600000;i++)
   {
      if(!(US_PORT & (1<<US_ECHO_POS)))
                    continue; //Line is still low, so wait
      else
                    break; //High edge detected, so break.
   }

   if(i==600000)
            return US_ERROR;  //Indicates time out

   //Rising Edge Found

   //Setup Timer1
   T1CKPS0=1;  //Prescaller = 1:2
   TMR1=0x00;  //Init counter
   TMR1ON=1;   //Stat timer

   //Now wait for the falling edge
   for(i=0;i<600000;i++)
   {
      if(US_PORT & (1<<US_ECHO_POS))
      {
         if(TMR1 > 60000) break; else continue;
      }
      else
                    break;
   }

   if(i==600000)
            return US_NO_OBSTACLE;  //Indicates time out

   //Falling edge found
   result=TMR1;

   //Stop Timer
   TMR1ON=0;

   if(result > 60000)
            return US_NO_OBSTACLE;  //No obstacle
   else
            return (result * 0.4);  // since period of timer is 0.4uS
}

Calculating distance from Time

Now this function is returning the length of the pulse in microsecond (uS). Its time to convert this to cm. For this we have to refresh our knowledge of Kinematics and recall the relationship of speed, time and distance.

We know that speed = distance traveled / time required to travel the distance.

So

distance = speed x time (simple maths!) Eq. 1

And since actual distance to obstacle is only half of the distance traveled by sound

Distance to obstacle = (speed x time)/2 Eq. 2

Speed of sound in air is

34359cm/sec = 0.034359cm/uS

substituting this value in equation 2 we get

Distance to obstacle = (0.034359 x time) /2

or

Distance to obstacle = (0.01718 x time)

So whenever we require the distance, we multiply time as returned by GetPulseWidth() function by 0.01718

Complete Demo Program

Now we have the distance calculated, but how we are gonna view that? In order to provide a complete demo of the theories taught above. We will create a simple program that will display this reading on the LCD Module. For this the project will also need support of our LCD library.

Hardware

To run this demo you need a PIC 16F877A based development board with LCD module, you can buy it from the link. It has built in LCD mdoule so you don't need to care much about its connecting. Your job is very simple, just to connect four pins of the HC-SR04 sensor to the development board. For that you need single pin female/female burg wires.

HC-SR04 Dev Board
VCC 5V OUT
GND GND (0V)
TRIG RA0
ECHO RA1

hc-sr04 ultrasonic sensor with PIC16F877A

We cordially thanks the following peoples who shared this page on various social networks and insprided us to develop more quality contents!

Subbuvairam, Gemgem, Ultra, MDF, , Lamrrales33, Jaguar601021, Muhammad Syafiq Ab Aziz, Priti, Brand, Azmi, Sridevi, HERMANN, Lorenzo, Bharathesh, QAMAR SHAIKH, Anurag Bisht, Avinash Home FF,

Comments