Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Offline Embedded Batch-2
Measuring distance of an object using ultrasonic distance sensor
#include <avr/io.h>
#include "avr/interrupt.h"
#define F_CPU 16000000L
#include <util/delay.h>
#define lcdport PORTD //object macro for PORTB
#define rs_high() PORTB |= (1<<7); //object macro for PORTB7 set
#define rs_low() PORTB &= ~(1<<7); //object macro for PORTB7 reset
#define en_high() PORTB |= (1<<6); //object macro for PORTB6 0set
#define en_low() PORTB &= ~(1<<6); //object macro for PORTB6 reset
float pulse_width;//to store the pulse width in interrupt capture
void lcd_out(char x,char y,char *str)
{
cursorpos(x,y); // to set cursor position
while(*str)
{
lcd_data(*str); // if string has value it is passed to the data as arg
str++;
}
}
void lcd_print(char row,char column,unsigned int value,int digits)
{
unsigned int temp;
unsigned int unit;
unsigned int tens;
unsigned int hundred;
unsigned int thousand;
unsigned int million;
unsigned char flag =0;
cursorpos(row,column);//to set the cursor position
if (digits == 5 || flag ==1)
{
million = value/10000 +48;
lcd_data(million);
flag=1;
}//prints the million digit
if (digits == 4 || flag ==1)
{
temp = value/1000;
thousand = temp%10 +48;
lcd_data(thousand);
flag=1;
}//prints the thousand digit
if (digits == 3 || flag ==1)
{
temp = value/100;
hundred = temp%10 +48;
lcd_data(hundred);
flag=1;
}//prints the hundred digit
if (digits == 2 || flag ==1)
{
temp = value/10;
tens = temp%10 +48;
lcd_data(tens);
flag=1;
}//prints the tens digit
if (digits == 1 || flag ==1)
{
unit = value%10 +48;
lcd_data(unit);
}//prints the unit digit
if (digits >5)
{
lcd_data('e');
}
}
void lcd_cmd(unsigned char cmd)
{
lcdport = cmd; //send command to the PORTB
rs_low(); //register low to command mode
en_high(); //enable high to feed data
_delay_ms(1);
en_low(); //enable low to stop transfer
}
void lcd_data(unsigned char data)
{
lcdport = data; //send data thru PORTB
rs_high(); //register high to data mode
en_high(); //enable high transfer data
_delay_ms(1);
en_low(); //enable low to stop transfer
}
void lcd_init()
{
lcd_cmd(0x38);_delay_ms(5); // 2 Lines 5x7 matrix Input
lcd_cmd(0x02);_delay_ms(5); //to return home
lcd_cmd(0x01);_delay_ms(5); //to clear screen
lcd_cmd(0x0C);_delay_ms(5); //to display on and cursor blinking
lcd_cmd(0x06);_delay_ms(5); //to increment cursor
lcd_cmd(0x80);_delay_ms(5); //to cursor begin 1st line
}
void cursorpos(char x,char y)
{
if ((x<1 || x>2) || (y<1 || y>16))
{
x=1;
y=1;
} //gives value if wrong input is given
if (x==1)
lcd_cmd(0x7F+y);//position for first line
else
lcd_cmd(0xBF+y);//position for second line
}
void init_timer()
{
lcd_init();
ACSR |= (0<<ACIC);//selecting ICP1 as capture
TIFR1 = (1<<ICF1);//reset input capture flag
TCNT1 = 0;//set counter bottom
TCCR1A |= (0<<WGM11)|(0<<WGM10);//normal mode
TCCR1B |= (0<<ICES1)|(0<<WGM13)|(0<<WGM12)|(1<<CS12);//prescaler 256 set raising edge
TIMSK1 |= (1<<ICIE1);//enable global interrupt
sei();//start interrupt
}
ISR(TIMER1_CAPT_vect)
{
pulse_width = ((ICR1 -12)*10)/625;//usecond
}//capture the pulse
void trigger()
{
PORTB |= (1<<PORTB1); //output 1
_delay_ms(15);//15us delay
PORTB &= ~(1<<PORTB1);//output0
}
int main(void)
{
float distance = 0;
DDRB |= (1<<DDB1); //enable pin as output
while (1)
{
trigger(); //trigger the PORTB1 trigger pin
init_timer();//initiate timer and interrupt
distance = (34*pulse_width)/2;//calculate using recieved pulsewidth
lcd_out(1,1,"distance =");
lcd_print(2,1,distance,4);
lcd_out(2,5,"cm");
//print uisng LCD display
_delay_ms(100);
}
}