INTERFACING HC-SR04 ULTRASOUND SENSOR WITH PIC MICROCONTROLLER

Greetings guys, its been a while since my last post but I’ll try to make it constant now, in our tutorial of today, we are going to be interfacing an ultrasonic distance sensor with a PIC16F877A microcontroller. The program will be written using MikroC Pro for pic.

We will be using the HC-SR04 ultrasound sensor for distance measurement. We are using this sensor because it is a low cost and easily available module. HC-SR04 Ultrasonic Distance Sensor is a popular and low cost solution for non-contact distance measurement function. It is able to measure distances from 2cm to 400cm with an accuracy of about 3mm. This module includes ultrasonic transmitter, ultrasonic receiver and its control circuit. As we can see on the figure below.

HC-SR04-Ultrasonic-Sensor-300x195

the HC-Sr04 ultrasonic sensor has four pins labeled

  • VCC – 5V, positive of the power supply
  • TRIG – Trigger Pin
  • ECHO – Echo Pin
  • GND – negaive of the power supply

The trigger and echo pins can be interfaced with a microcontroller because the function on 0 – 5V.

WORKING PRINCIPLE

                As seen on the datasheet,

  1. Provide TRIGGER signal, atleast 10μS High Level (5V) pulse.
  2. The module will automatically transmit eight 40KHz ultrasonic burst.
  3. If there is an obstacle in-front of the module, it will reflect the ultrasonic burst.
  4. If the signal is back, ECHO output of the sensor will be in HIGH state (5V) for a duration of time taken for sending and receiving ultrasonic burst. Pulse width ranges from about 118μS to 24mS and if no obstacle is detected, the echo pulse width will be about 38ms.

This is a brief summary of how the sensor operates and its exactly what we are going to exploit in order to measure the distance. Other characteristics can be gotten from the datasheet or just search on Google and you’ll find a lot of data on this sensor.

CIRCUIT DIAGRAM

Untitled

On the diagram above I connected the LCD on port B2 – B7, the trigger pin of the hc-sr04 to pin C3 and the echo pin to pin B0 which an external interrupt pin. Any digital pin can be used as trigger but I used B0 as echo because its capability of acting as an external interrupt comes in handy in this application.

PROCEDURE

  1. Send a pulse of at least 10 us through the trigger pin,
  2. Set pin B0 as interrupt on rising edge
  3. When interrupt occurs, clear timer 1 and start timer1
  4. Set pin B0 as interrupt on falling edge
  5. When interrupt occurs, read the value of timer1 and in a variable.
  6. Multiply the value of timer1 by 0.0034 (I’ll explain later)
  7. The final result gives your distance in centimeters. You can now display it

This are the procedures that I followed so I make use of timer 1 which is a 16bit timer, timer1 interrupt and external interrupt. I use timer1 interrupt because I noticed that timer1 overflows before 23 ms, hence it measures only a fraction of the distance. So using the interrupt, I was able to know exactly how many times the timer overflows and added it to the timer value. You will see me do that in the code.

I know you will be wondering where I got the figure 0.0034. lets explain it step by step.

I used 20MHz crystal so I have 20/4 = 5 million instructions per second.

Period = 0.2 us.

So timer increaments every 0.2 us

Time = TIMER1 * 0.2 us.

Distance = velocity*time (speed of sound is 340m/s)

Distance = TIMER1 * 340*0.2*10^-6

Distance = TIMER1*68*10^-6 (but the distance is through and fro. So we divide by 2)

Distance = TIMER1*34*10^-6 (we multiply by 100 to have it in cm)

Distance = TIMER1*0.0034.

Hope the calculation is explicit enough. Contact me if there is any doubt and note that for a different value of crystal, the values will change. Just follow the steps above and all will be fine.

SOURCE CODE

/*

distance measurement using hc-sr04 ultrasound sensor

using PIC16F877A

code written by Joel NGONGA

http://www.blogelect.wordpress.com

04-01-2016

The comments will guide you

*/

 

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;

sbit LCD_D5 at RB5_bit;

sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

 

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;

sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

 

sbit TRIG at RC3_bit;

sbit TRIG_Direction at TRISC3_bit;

sbit ECHO at RC2_bit;

sbit ECHO_Direction at TRISC2_bit;

 

unsigned long int dist=0,cnt;

unsigned char txt[15];

 

void interrupt() {

     if (INTCON.INTF == 1){         // detect rising edge

       if (OPTION_REG.INTEDG ==1){

           T1CON.TMR1ON = 1;      // put on timer1

           OPTION_REG.INTEDG = 0; // set interrupt on falling edge

           }

       else if (OPTION_REG.INTEDG == 0){ // detect falling edge

             T1CON.TMR1ON = 0;           // put off timer1

             dist =((65536*cnt)+(TMR1L | (TMR1H<<8)))*0.0034;

             TMR1L=0;   // clear timer1L

             TMR1H=0;   // clear timer1H

             cnt=0;   // clear cnt variable

             OPTION_REG.INTEDG = 1; // set interrupt on rising edge

             }

       INTCON.INTF = 0;

 

       }

       else if (PIR1.TMR1IF == 1){   // timer1 overflow

       cnt++;

       PIR1.TMR1IF =0;

         }

}

 

void main() {

OPTION_REG.INTEDG = 1; //INTERRUPT ON RISING EDGE

T1CON = 0x09;     // timer control register

INTCON = 0xD0;   // interrupt control register

PIE1.TMR1IE=1;   // timer1 interrupt enable bit

T1CON.TMR1ON = 0; // timer1 0ff initially

trisb0_bit=1;

trisc=0;

portc=0;

lcd_init();

Lcd_Cmd(_Lcd_Clear);

Lcd_Cmd(_Lcd_Cursor_off);

Lcd_out(1,1,”hello joel’s lab”);

Lcd_out(2,1,”distance measurm”);

delay_ms(1000);

Lcd_Cmd(_Lcd_Clear);

Lcd_out(2,1,”distance = “);

do{

   Inttostr(dist,txt);

   Ltrim(txt);

   Lcd_out(2,11,txt);

   Lcd_out_cp(” cm “);

   TRIG=1;

   delay_us(10);

   TRIG=0;

   delay_ms(100);

   }while(1);

}

You can download the proteus library for hc-sr 04 from this link, the complete project can be downloaded from this link. I designed it using proteus 8.3. comment if you need the diagram with an earlier version of proteus

If any of the links are unavailable, just comment with your email and I will send you the project. Thanks for reading through and please leave a comment.

by   Joel NGONGA

26 Comments

  1. nice project and very good explanation.
    i wanted to interface pic16f84A with ultrasonic module. the microcontroller uses only timer0, how can i implement the same project using timer0? can you elp

    Like

  2. there is one thing i dont understand bro, have made the function void interrupt in the starting of the code before the main fnction. but in your d0 loop you havnt called that function for even once… i dont think that code would work. coz i chked it in my breadboard..you need to call that inrerrupt function again and again to calculate the distance every time… plz correct me if i m wrong..

    Like

Leave a comment