Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
#include <avr/io.h> //we are using I/O registers of AVR
#define F_CPU 16000000L // define the crystal frequency
#include "avr/interrupt.h" // we are using external interrupt pin
#include <util/delay.h> // delay function purpose
#define lcd_port PORTB //PORTB pins are for LCD data
#define RS_high PORTD |= (1<<0) // d0 pin is used for Register Select(RS)
#define RS_low PORTD &=~ (1<<0) // d0 pin is used for RS
#define EN_high PORTD |= (1<<1) // d1 pin is used for Enable
#define EN_low PORTD &=~ (1<<1) // d1 pin is used for En.
unsigned int tov=0,count,distance;
void lcd_cmd(unsigned char cmd) //command for lcd display
{
lcd_port = cmd;
RS_low;
EN_low;
_delay_ms(1);
EN_high;
}
void lcd_data (unsigned char data) //send the data to lcd
{
lcd_port = data;
RS_high; //access data register
EN_low;
_delay_ms(1);
EN_high;
}
void lcd_init()
{
lcd_cmd(0x38);
_delay_ms(5);
lcd_cmd(0x02); // return home
_delay_ms(5);
lcd_cmd(0x01); // clear screen
_delay_ms(5);
lcd_cmd(0x0C); // display on cursor off
_delay_ms(5);
lcd_cmd(0x06); // increment the display cursor
_delay_ms(5);
lcd_cmd(0x80); // force cursor to begin from 1st line
_delay_ms(5);
lcd_cmd(0xC0); // force cursor to begin from 2st line
_delay_ms(5);
}
void cursorpos(char x,char y)
{
if((x<1 || x>2) || (y>16 || y<1 )) //condition will checks the 2 rows and 16 columns
{
x=1; //x= row
y=1; //y= column
}
if(x==1)
{
lcd_cmd(0x7F + y); //{ 80-1 = 7F} for starting the 1st line hex decimal value (80) {y we r using the 7F+y means we need to dtart from that column}
}
else //(x==2)
{
lcd_cmd(0xBF + y); //{0C-1 = 0B} for starting the 2nd line, 2nd row.
}
}
void lcd_out(char x, char y, char *str) //here we are checking which position we want to print
{
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
void lcd_print(char row, char coloumn, unsigned int value, int digits)
{
unsigned int temp,unit,tens,hundred,thousand,million;
unsigned char flag=0;
if(row==0||coloumn==0)
{
cursorpos(1,1);
}
else
{
cursorpos(row,coloumn);
}
if(digits==5|| flag==1)
{
million=value/10000+48;
lcd_data(million);
flag=1;
}
if(digits==4 || flag==1)
{
temp = value/1000;
thousand = temp%10 +48;
lcd_data(thousand);
flag=1;
}
if(digits==3 || flag==1)
{
temp = value/100;
hundred = temp%10 +48;
lcd_data(hundred);
flag=1;
}
if(digits==2 || flag==1)
{
temp = value/10;
tens= temp%10 +48;
lcd_data(tens);
flag=1;
}
if(digits==1 || flag==1)
{
unit = value%10 + 48;
lcd_data(unit);
}
if(digits>5)
{
lcd_data('e');
}
}
int main(void)
{
DDRB=0xff; //Port B as output
DDRD |=(0<<6); //Port D pin 6 as input from echo pin of sensor
DDRC |=(1<<0); //Port C 0 as output
sei(); //Enable global interrupt
lcd_init();
TCCR1A=0x00; //Normal mode
TIMSK|=(1<<2);
while(1)
{
PORTC|=(1<<0);//Trigger sensor
_delay_us(10);
PORTC&=~(1<<0);
TCCR1B=0x41; //ICF Enable, no prescaling
TCNT1=0;
TIFR=(1<<ICF1);
TIFR=(1<<TOV1);
tov=0;
while((TIFR&(1<<ICF1))==0); //check timer flow condition
TCNT1=0;
TCCR1B=0x01;
TIFR=(1<<ICF1);
TIFR=(1<<TOV1);
tov=0;
while((TIFR&(1<<ICF1))==0);
count = ICR1 +(65535 * tov);
distance = (unsigned int)count /932.87;
lcd_print(1,1,distance,4);
lcd_out(1,6,"cm");
}
}
ISR(TIMER1_OVF_vect)
{
tov++;
}