Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
/*
* measure_distance_using_ultrasonic.c
*
* Created: 21-Jun-23 5:30:25 AM
* Author : Anbudan Balaji
*/
#define F_CPU 8000000UL //cpu freq
#include <avr/io.h> //for input and output
#include <avr/interrupt.h> //for sei
#include <util/delay.h> //for delay
#include <stdlib.h> //for distance to string function
#define EN_high PORTC |= (1<<2) //configuring lcd enable pin as high
#define EN_low PORTC &=~ (1<<2) //configuring lcd enable pin as low
#define RS_high PORTC |= (1<<4) //configuring lcd register pin as high
#define RS_low PORTC &=~ (1<<4) //configuring lcd register pin as low
int TimerOverflow = 0; //variable declaration
char string[10];
long count;
double distance;
void lcd_command (unsigned char cmd) //function to write command on lcd
{
PORTD = cmd; //giving cmd to the LCD through port D
RS_low; //rs=0,to select command register
EN_high; //set enable high
_delay_ms(1); //delay
EN_low; //set enable low
}
void lcd_data (unsigned char data) //function to write data on lcd
{
PORTD = data; //giving data to the LCD through port D
RS_high; //rs=1,to select data register
EN_high; //set enable high
_delay_ms(1); //delay
EN_low; //set enable low
}
void lcd_init () //initialize lcd display
{
lcd_command (0x38);_delay_ms(5); //8 bit LCD mode
lcd_command (0x02);_delay_ms(5); //return cursor to home
lcd_command (0x01);_delay_ms(5); //clear screen
lcd_command (0x0C);_delay_ms(5); //display ON, cursor OFF
lcd_command (0x06);_delay_ms(5); //increment cursor
lcd_command (0x80);_delay_ms(5); //force cursor to begin at the 1st line
}
void cursor_position(char x, char y) //set cursor position
{
if ((x<1||x>2)||(y>16||y<1)) //condition to check 2 rows and 16 columns
{
x = 1; //force to start 1st line
y = 1; //force to start 2nd line
}
if (x == 1)
{
lcd_command(0x80+y); //start 1st line(1st row + 1st column)
}
else
{
lcd_command(0xC0+y); //start 2nd line(2nd row + 1st column)
}
}
void lcd_out(char x, char y, char *str) //lcd string output function
{
cursor_position(x, y);
while (*str) //check cursor position
{
lcd_data(*str); //send the data to lcd function with string as argument
str++; //increment the string
}
}
void trigger_pulse() //trigger function
{
DDRA =0x01; //declare port A pin0 as output
PORTA |= (1 <<0); //set pin A0 as high for trigger pin
_delay_us(10); //trigger pulse delay
PORTA &= (~(1 <<0)); //set pin A0 as low for trigger pin
}
void capture_raising_edge() //function for capture raising edge
{
TCNT1 = 0; //clear Timer counter
TCCR1B = 0x41; //capture on rising edge, no prescaler
TIFR = 1<<ICF1; //clear ICP flag (Input Capture flag)
TIFR = 1<<TOV1; //clear Timer Overflow flag
}
void capture_falling_edge() //function for capture falling edge
{
TCNT1 = 0; //clear Timer counter
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
}
ISR(TIMER1_OVF_vect) //function for interrupt service routine
{
TimerOverflow++; //increment Timer Overflow count
}
int main(void)
{
DDRD = 0xFF; //set portD as output
DDRB = 0x01; //declaring port B pin0 as input from echo pin of sensor
lcd_init(); //call lcd initialization function
lcd_out(1, 1, "Ultrasonic"); //print 1st row and 1st column
sei(); //enable global interrupt
TIMSK = (1 << TOIE1); //enable Timer1 overflow interrupts
TCCR1A = 0; //set normal operation condition
while(1)
{
trigger_pulse(); //call trigger pulse function
capture_raising_edge(); //call capture raising edge function
while ((TIFR & (1 << ICF1)) == 0); //wait for rising edge
capture_falling_edge(); //call capture falling edge function
while ((TIFR & (1 << ICF1)) == 0); //wait for falling edge
count = ICR1 + (65535 * TimerOverflow); //take count
distance = (double)count / 466.47; //distance=((sound velocity*timer)/2), so distance=timer value/466.47cm, 8MHz Timer freq, sound velocity =343m/s(34300cm/s)
dtostrf(distance,2,2,string); //distance to string function
lcd_out(2, 1, "Dist="); //print 2nd row and 1st column
lcd_out(2, 6, string); //print 2nd row and 6th column
lcd_out(2, 11, "cm"); //print 2nd row and 11th column
_delay_ms(200); //delay
}
}

