In this Tutorial we will learn how the HC-SR04 Ultrasonic Sensor works and how to use it with the PIC16F877A Microcontroller. 

You can watch the following video or read the written tutorial below.

 

 

The HC-SR04 Ultrasonic module is a contactless distance measurement sensor. It can measure distance from 2cm to 400cm with are ranging accuracy up to 3mm. The HC-SR04 module has two part Ultrasonic Transmitter and ultrasonic Receiver. The  Transmitter emit the ultrasound and  receiver receives that the reflected sound. It  operates 5 volt DC supply. 

 

 

 

How it works - HC-SR04 Ultrasonic module 

It emit a ultrasound at 40 KHz which travels through the air and if there is an objects or obstacle on it path it will bounce the back to the module. Considering the travel time and the speed of the sound you can calculate the distance.

 

 

 

 

The SC-SR04 Ultrasonic module has 4 pins, Vcc, GND, Trig and Echo. The circuit schamatic is very esay and quick simple. The Vcc and GND pins are connected with 5 volt DC supply. Here The Trig and Echo pins of module is connected RB0 and RB4 pins of Microcontroller.

 

 

 

In order to generate the ultrasound you need to set the Trig on a High State for 10 µs. That will send out an 8 cycle sonic burst which will travel at the speed sound and it will be received in the Echo pin. The Echo pin will output the time in microseconds the sound wave traveled.

 

 

 

For example, if the object is 10 cm away from the sensor, and the speed of the sound is 340 m/s or 0.034 cm/µs the sound wave will need to travel about 294 µ seconds. But what you will get from the Echo pin will be double that number because the sound wave needs to travel forward and bounce backward.  So in order to get the distance in cm we need to multiply the received travel time value from the echo pin by 0.034 and divide it by 2.

 

 

If the sonic pulse is not reflected back them the Echo signal will timeout after 38mS and return low. This produced a 38mS pulse that indicates no obstruction within the range of the sensor.

 

 

Source Code

// Lcd module connetions
sbit LCD_RS at RC0_bit;
sbit LCD_EN at RC1_bit;
sbit LCD_D4 at RC2_bit;
sbit LCD_D5 at RC3_bit;
sbit LCD_D6 at RC4_bit;
sbit LCD_D7 at RC5_bit;

sbit LCD_RS_Direction at TRISC0_bit;
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D4_Direction at TRISC2_bit;
sbit LCD_D5_Direction at TRISC3_bit;
sbit LCD_D6_Direction at TRISC4_bit;
sbit LCD_D7_Direction at TRISC5_bit;
// End Lcd module connections

unsigned int duration;
float distance;
char text[15];
void interrupt(){
	if(RBIF_bit){
  		RBIE_bit = 0;         // disable the port change interrupt
  		if(RB4_bit==1){
  			TMR1L  = 0;
  			TMR1H  = 0;       // Clear the timer resistor
  			T1CON.TMR1ON = 1;           // Enable the Timer1
  		}
  		if(RB4_bit==0){
  				duration = (TMR1H<<8) | (TMR1L) ;
  				T1CON.TMR1ON = 0;        // Disable the timer1
  		}
  		RBIF_bit = 0;        // Clear the interrupt flag bit
	}
	RBIE_bit = 1;          // Enable the port change interrupt
}

void main() {
   TRISB0_bit = 0;      // Trig pin
   PORTB.F0 = 0;         // Set Trig pin low state
   TRISB4_bit = 1;      // Echo pin
   PORTB.F4 = 0;         // Clear Echo pin
   Lcd_Init();          // Initialize the Lcd module
   Lcd_Cmd(_LCD_CLEAR);     // Clear the Lcd display
   Lcd_Cmd(_LCD_CURSOR_OFF);      // Cursor of the Lcd display
   Lcd_Out(1,1,"Developed by");
   Lcd_Out(2,1,"MINA TECHNOLOGY");
   delay_ms(1000);            // 1second delay
   Lcd_Cmd(_LCD_CLEAR);           // Clear the lcd display

   INTCON.GIE = 1;           // Enable the gloabal interrupt
   INTCON.RBIE = 1;          // Enable the port change
   T1CON.TMR1ON = 0;              // Disable timer1
   T1CON.TMR1CS = 0;        // Timer1 internal clock source (Fosc/4)
   T1CON.T1CKPS1 = 0;        // 1:2 Presclar value
   T1CON.T1CKPS0 = 1;
   duration = 0;
   distance = 0;

   while(1){
		PORTB.F0 =1;    // Generate 10us Trig pulse
		delay_us(10);
		PORTB.F0 = 0;
		while(RB4_bit==0);   // Wait for Echo pulse
		distance = duration * (0.034 / 2);
		if( distance >=2 && distance <=400 ) {   // Check condition 
			Lcd_Out(2,7,"cm");
			Lcd_Out(1,1,"Distance:");
			floatToStr(distance,text);
			Ltrim(text);
			text[5] =0;
			Lcd_Out(2,1,text);
		}
		else {
			Lcd_Cmd(_LCD_CLEAR);
			Lcd_Out(1,1,"Out of Range");                      
		}
		delay_ms(500);
  	}
}

 

 

Code Explain:

We have written the code in mikro c pro for pic compiler.

This is our simple code. Here we have included conversion and Lcd library. In the define section of the program we have defined Lcd module connection. We have defined some variable and array. we have created void interrup() function for interrupt service routine(isr)  executions.  

 

In main section of the program we have defined Trig and Echo pins by Clearing or Setting TRISB or PORTB resister. We have defined Lcd module and then we have wrote some Lcd command for Lcd operations. Next we have Enabled Global and PORTB change interrupt by setting INTCON register. Then we have wrote some code for Timer1 module.

 

In the loop for generating the Ultra sound wave we have to set the trigPin on HIGH State for 10 µs. Then we have created a while loop which wait for Echo pulse. While Echo pulse comes from the module then the PORTB change interrupt occur. When Echo pulse goes Low to High then The timer1 module starting to count the time and  goes High to Low the Timer 1  is stopped. Here we easlay read the TMR1H and TMR1L register value. For getting the distance we will multiply the duration by 0.034 and divide it by 2 as we explained this equation previously. Here we have created a statement of valid distance. When the statement is true then print the distance on Lcd otherwise the Lcd will show "Out of Range".

 

 

Download free source code

 

download