Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
LIVE SESSION (Preeti MAM)
PROJECT - 2
OBJECTIVE : Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
GOALS :
- Measuring the distance of an object using Ultrasonic Distance Sensor (HC-SR04)
- Usage of Input Capture Mode
So, let's understand what is the usage of HC-SR04 Sensor :
HC-SR04 ultrasonic sensor measures distance by using inaudible ultrasonic sound waves of 40KHz frequency. Like sound waves, ultrasonic waves travel through the air and if there is any obstacle in front of them, they reflect according to their angle of incidence. Moreover, if an object is placed parallel to an ultrasonic transmitter, ultrasonic waves reflect exactly at an angle of 180 degrees. Therefore, for distance measurement with HC-SR05 sensor, we place the object under test exactly in a parallel position with an ultrasonic sensor .

SOURCE CODE :
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#define LCD_Data_Dir DDRD
#define LCD_Command_Dir DDRC
#define LCD_Data_Port PORTD
#define LCD_Command_Port PORTC
#define EN PC2
#define RW PC3
#define RS PC4
void LCD_Command (char);
void LCD_Char (char);
void LCD_Init (void);
void LCD_String (char*);
void LCD_String_xy (char,char,char*);
void LCD_Command (char cmd)
{
LCD_Data_Port = cmd;
LCD_Command_Port &= ~((1<<RS)|(1<<RW));
LCD_Command_Port |= (1<<EN);
_delay_us(1);
LCD_Command_Port &= ~(1<<EN);
_delay_ms(3);
}
void LCD_Char (char char_data)
{
LCD_Data_Port = char_data;
LCD_Command_Port &= ~(1<<RW);
LCD_Command_Port |= (1<<EN)|(1<<RS);
_delay_us(1);
LCD_Command_Port &= ~(1<<EN);
_delay_ms(1);
}
void LCD_Init (void)
{
LCD_Command_Dir |= (1<<RS)|(1<<RW)|(1<<EN); // Make LCD command port direction as o/p
LCD_Data_Dir = 0xFF; // Make LCD data port direction as o/p
_delay_ms(20);
LCD_Command (0x38); // Initialize 16X2 LCD in 8bit mode
LCD_Command (0x0C); // Display ON, Cursor OFF command
LCD_Command (0x06); // Auto Increment cursor
LCD_Command (0x01); // Clear LCD command
LCD_Command (0x80); // 8 is for first line and 0 is for 0th position
}
void LCD_String (char *str) /* Send string to LCD function */
{
for(int i=0;str[i]!=0;i++) // Send each char of string till the NULL
{
LCD_Char (str[i]); //Call LCD data write
}
}
void LCD_String_xy (char row, char pos, char *str)
{
if (row == 1)
LCD_Command((pos & 0x0F)|0x80); // Command of first row and required position<16
else if (row == 2)
LCD_Command((pos & 0x0F)|0xC0); // Command of Second row and required position<16
LCD_String(str);
}
#define Trigger_pin PA0
int TimerOverflow = 0;
ISR(TIMER1_OVF_vect)
{
TimerOverflow++; // Increment Timer Overflow count
}
int main(void)
{
char string[10];
long count;
double distance;
DDRA = 0x01; /* Make trigger pin as output */
PORTB = 0xFF; /* Turn on Pull-up */
LCD_Init();
LCD_String_xy(1, 0, "Ultrasonic");
sei(); // Enable global interrupt
TIMSK = (1 << TOIE1);
TCCR1A = 0;
while(1)
{
// Give 10us trigger pulse on trig. pin to HC-SR04
PORTA |= (1 << Trigger_pin);
_delay_us(10);
PORTA &= (~(1 << Trigger_pin));
TCNT1 = 0;
TCCR1B = 0x41; //For configuring Capture on rising edge, No prescaler
TIFR = 1<<ICF1; // Clearing ICP flag (Input Capture flag)
TIFR = 1<<TOV1; // Clearing Timer Overflow flag
//Calculate width of Echo by Input Capture (ICP)
while ((TIFR & (1 << ICF1)) == 0);
TCNT1 = 0;
TCCR1B = 0x01; //Capture on falling edge, No prescaler
TIFR = 1<<ICF1; // Clear ICP flag (Input Capture flag)
TIFR = 1<<TOV1; // Clear Timer Overflow flag
TimerOverflow = 0; // Clear Timer overflow count
while ((TIFR & (1 << ICF1)) == 0); // Wait for falling edge
count = ICR1 + (65535 * TimerOverflow);
// 8MHz Timer freq, sound speed =343 m/s
distance = (double)count / 466.47;
dtostrf(distance, 2, 2, string); // distance (A float value) to a string
strcat(string, " cm "); //For Concatenating unit i.e.cm
LCD_String_xy(2, 0, "Dist = ");
LCD_String_xy(2, 7, string);
_delay_ms(500);
}
}
OUTPUT :
