In our previous tutorial, we saw how to use ADC in a pic microcontroller by displaying the ADC counts on a character LCD. In this tutorial, we will learn how to interface Ultrasonic Sensor with PIC microcontroller along with character LCD.
Ultrasonic sensor
An ultrasonic sensor is used to measures distance using sound waves. It transmits a series of sound waves which collide with the object in its path and are reflected back to the sensor. The time interval between the transmitted wave and received reflected wave is used to measure the distance of an object. The ultrasonic sensor transmits sound waves at a much higher frequency beyond 20Khz. Such a high frequency is inaudible, as the audible frequency range for human beings is in between 20Hz to 20Khz. These sound waves are best reflected off a Hard surface. Softer surfaces will cause some of the sound energy to be absorbed.
The ultrasonic sensor that we will be using is HC-SR04. So let us look into the details of HC-SR04.
HC-SR04 Ultrasonic sensor and its working
The HC-SR04 uses an ultrasonic transmitter and receiver for transmitting ultrasound and receiving its echo. The module consists of 4 pins, Vcc, Trigger, Echo and Gnd. Vcc and Gnd pin are used to power the module with 5v. The trigger pin is used to initiate the ultrasound transmission. This pin must be pulled high for at least 10us to initiate transmission. When a transmission is initiated, the module automatically sends 8 short pulses at a frequency of 40Khz in quick succession.
If an obstacle or a surface is encountered the ultrasound is reflected and its echo is received by the ultrasonic receiver. On receiving the echo, the Echo pin will be pulled high by the ultrasonic module. The duration for which the echo pin will be pulled high by the ultrasonic module is exactly equal to the duration between the transmitted wave and its received echo. Thus by reading the status of the echo pin, you can find the time required for the ultrasound to reflect back.
Once you find out the time, you can use the distance formula to calculate distance.
Velocity = Distance/Time
Distance = Velocity x Time
The velocity of Ultrasound in Air is 340m/s.
The only unknown you have here is Distance. But since the time for which the Echo pin stays high is the duration of ultrasound from the sensor to object and object to the sensor, time will be divided by 2.
Specifications of HC-SR04 ultrasonic module
- Input supply: 5 volts DC
- Supply current consumption: 15mA
- Working frequency: 40Khz
- Maximum distance: 4m
- Minimum distance: 2cm
- Measuring angle: 15 degrees
Circuit connection of Ultrasonic sensor with PIC16F887 along with 16*2 LCD
Calculations for Ultrasonic sensor and Microcontroller’s timer.
Now, let us see how to make the necessary calculations for the ultrasonic sensor. Here we are using pic16f887 microcontroller’s internal oscillator which by default runs on 4Khz. In pic16f887, the internal timer/counter module increments at a frequency of Fosc/4 when configured as a timer. So the Timer module will increment at every 1 microsecond as T=(1/F) where F is 1Khz(Fosc/4). Here we will be using timer 1 module of pic16f887.
As we already know, Distance is a product of Speed and Time, the formula becomes,
Distance = (34000cm/s x 0.000001s x (Timer 1 register value))/2
On reducing the above equation, we get,
Distance = 0.017*(timer 1 register value)
The reason we divide the above formula by 2, is because the total duration is the sum of the time required for the ultrasound to travel from the sensor to object and then reflect back from the object and return to the sensor.
Here distance will return a float value which is typecasted to an integer and then printed on the LCD.
The program for the ultrasonic sensor with pic16f887 is given below.
#include <xc.h> #include<pic.h> #include<pic16f887.h> #define _XTAL_FREQ 4000000 void lcd_cmd(unsigned char c); void lcd_data(unsigned char d); void lcd_init(void); void enable(void); char print[] = "Distance in cm."; void lcd_print(char *p); void display_dist(void); float distance; int read_value, print_dist; int main() { TRISD = 0x00; // Set PORTD as output TRISB = 0x01; // setting the echo pin as input and trigger pin as output ANSELH = 0x00; // Disabling analog inputs on RB0 and RB1 TRISC = 0x00; // Setting PORTC as output lcd_init(); // Function call to initialize LCD lcd_cmd(0x80); // Setting cursor position to 1st location lcd_print(print); // Print message "Distance in cm." __delay_ms(5); T1CON = 0x00; // Initializing timer1 module while(1) { TMR1H = 0x00; TMR1L = 0x00; RB1 = 1; //Raise trigger pin to 1 __delay_us(10); //Wait for 10 microsecond RB1= 0; //Pull trigger pin to 0 while(!RB0); // Wait till Echo pin goes high TMR1ON = 1; //Start timer when echo pin goes high while(RB0); // wait till echo pin goes low TMR1ON = 0; // Stop timer when echo pin goes low read_value = ((TMR1H<<8)|TMR1L); // Read Timer value distance = (0.017*read_value); print_dist = (int)distance; // Type cast float into integer display_dist(); // Call function to display print_dist __delay_ms(300); } } void lcd_init(void) { // LCD initial initialization __delay_ms(15); lcd_cmd(0x03); __delay_ms(5); lcd_cmd(0x03); __delay_ms(5); lcd_cmd(0x03); __delay_ms(5); lcd_cmd(0x02); __delay_ms(5); // LCD command setting initialization lcd_cmd(0x28); // 4 bit interface length. 2 rows enabled. __delay_ms(5); lcd_cmd(0x10); // Move cursor or shift display __delay_ms(5); lcd_cmd(0x0c); // Enable display. Cursor off. __delay_ms(5); lcd_cmd(0x06); // Increment cursor position after each byte __delay_ms(5); lcd_cmd(0x01); // clear display __delay_ms(5); } void lcd_cmd(unsigned char c) { RD7 = 0; RD6 = 0; PORTC = (PORTC&0x0f)|(0xf0&c); enable(); PORTC = ((PORTC&0x0f)|(0x0f&c)<<4); enable(); } void lcd_data(unsigned char d) { RD7 = 1; RD6 = 0; PORTC = (PORTC&0x0f)|(0xf0&d); enable(); PORTC = ((PORTC&0x0f)|(0x0f&d)<<4); enable(); } void enable(void) { RD5 = 1; __delay_ms(5); RD5 = 0; } void lcd_print(char *c) { while(*c != '\0') { lcd_data(*c); c++; } } void display_dist(void) { lcd_cmd(0xc0); lcd_data((print_dist/100)+48); print_dist = print_dist%100; lcd_data((print_dist/10)+48); print_dist = print_dist%10; lcd_data(print_dist+48); }
0 Comments