Interfacing PIC16F84A with HC-SR04 Ultrasonic Sensor
This post shows how to interface PIC16F84A microcontroller with HC-SR04 ultrasonic sensor and make a distance meter.The ultrasonic sensor HC-SR04 can measure distances form 2cm to 400cm with an accuracy of 3mm. This sensor module includes ultrasonic transmitter, ultrasonic receiver and control circuit.
The HC-SR04 ultrasonic sensor has 4 pins as shown below where:
VCC - Positive power supply (+5V)
Trig - Trigger input pin
Echo - Echo output pin
GND - Ground (0V)
HC-SR04 ultrasonic sensor timing diagram:
The timing diagram of the HC-SR04 ultrasonic sensor is shown below.
First we have to supply the sensor trigger pin with a pulse of 10µs and the sensor will automatically send 8 cycles burst of ultrasound at 40 kHz and raise its echo pin. The Echo is a distance object that is pulse width and the range in proportion. You can calculate the range through the time interval between sending trigger signal and receiving echo signal. Formula: uS / 58 = centimeters or uS / 148 =inch; or:
the range = high level time * velocity (340M/S) / 2.
PIC16F84A with HC-SR04 ultrasonic sensor example circuit:
The following circuit schematic show he connection between the microcontroller PIC16F84A and the HC-SR04 sensor.
The 1602 LCD is used to display the measured distance in cm.
PIC16F84A with HC-SR04 ultrasonic sensor example CCS C code:
Here is the C code used for this project.
Timer0 is configured to increment by 1 every 1 us ( with mcu frequency of 8MHz). Timer0 is used the measure the pulse widths come from Echo pin of the HC-SR04 sensor.
Because of the Timer0 is an 8-bit timer only I used its interrupt (Timer0 interrupt) to count times more than 256us, and for that purpose I added a variable called count. So the pulse time of the Echo pin equals to :
count * 256 + get_timer0()
// Interfacing PIC16F84A with HC-SR04 ultrasonic sensor CCS PIC C code // http://ccspicc.blogspot.com/ // electronnote@gmail.com //LCD module connections #define LCD_RS_PIN PIN_B0 #define LCD_RW_PIN PIN_B1 #define LCD_ENABLE_PIN PIN_B2 #define LCD_DATA4 PIN_B3 #define LCD_DATA5 PIN_B4 #define LCD_DATA6 PIN_B5 #define LCD_DATA7 PIN_B6 //End LCD module connections #include <16F84A.h> #fuses HS,NOWDT,PUT,NOPROTECT #use delay(clock = 8000000) #include <lcd.c> #use fast_io(A) unsigned int8 count; unsigned int16 i, distance; #INT_TIMER0 void timer0_isr(){ count++; clear_interrupt(INT_TIMER0); } int1 wait_sensor(){ i = 0; set_timer0(0); count = 0; // Reset Timer0 while(!input(PIN_A1) && (i < 1000)) i = count * 256 + get_timer0(); if(i > 990) return 0; else return 1; } unsigned int16 get_distance(){ i = 0; set_timer0(0); count = 0; while(input(PIN_A1) && (i < 25000)) i = count * 256 + get_timer0(); return i; } void main(){ output_a(0); set_tris_a(2); // Configure RA1 as input lcd_init(); // Initialize LCD module lcd_putc('\f'); // LCD clear clear_interrupt(INT_TIMER0); enable_interrupts(GLOBAL); enable_interrupts(INT_TIMER0); setup_timer_0 (T0_INTERNAL | T0_DIV_2); // Configure Timer0 module lcd_gotoxy(4, 1); // Go to column 4 row 1 lcd_putc("Distance:"); while(TRUE){ // Send 10us pulse to HC-SR04 Trigger pin output_high(PIN_A0); delay_us(10); output_low(PIN_A0); // Read pulse comes from HC-SR04 Echo pin if(wait_sensor()) { distance = get_distance(); if(distance > 24990) { lcd_gotoxy(3, 2); // Go to column 3 row 2 lcd_putc("Out Of Range"); } else { distance = i/58; // Calculate the distance lcd_gotoxy(3, 2); // Go to column 3 row 2 lcd_putc(" cm "); lcd_gotoxy(6, 2); // Go to column 6 row 2 printf(lcd_putc,"%3Lu",distance); } } else { lcd_gotoxy(3, 2); // Go to column 3 row 2 lcd_putc(" Time Out "); } delay_ms(100); } }Example Video: