Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Aim:
In this project, the implementation of code for “Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
Circuit:

Code:
#include <avr/io.h> //includes appropriate I/O definitions for the device
#define F_CPU 16000000 //tells compiler the CPU frequency to use for various delays
#include <util/delay.h> //Function where actual time values rather than a number of cycles to wait for
#include <stdlib.h> //standard library
#define LCD_PORT PORTD //defines which PORT of ATmega will be used to interface LCD
//RS bit tells whether we are going to send an Instruction or a piece of data
#define RS_HIGH PORTB |= (1<<0); //for data
#define RS_LOW PORTB &= ~(1<<0); //for instruction
//RW bit used for read and write operation
#define RW_HIGH PORTB |= (1<<1);
#define RW_LOW PORTB &= ~(1<<1);
//EN bit enables writing to the registers if HIGH
#define EN_HIGH PORTB |= (1<<2);
#define EN_LOW PORTB &= ~(1<<2);
//global variables
#define Delay 1500000
int distance = 0;
//commands to run when the LCD RS bit is LOW
void LCD_COMMAND (unsigned char cmd)
{
LCD_PORT = cmd;
RS_LOW;
RW_HIGH;
EN_HIGH;
_delay_ms(1);
EN_LOW;
}
//Commands to process the data of LCD RS bit is HIGH
void LCD_DATA (unsigned char data)
{
LCD_PORT = data;
RW_LOW;
RS_HIGH;
EN_HIGH;
_delay_ms(1);
EN_LOW;
}
//Commands to initialize the LCD display
void LCD_INIT()
{
RW_HIGH;
RS_HIGH;
EN_HIGH;
LCD_PORT = 0xff;
LCD_COMMAND(0x38);
_delay_ms(5);
LCD_COMMAND(0x02);
_delay_ms(5);
LCD_COMMAND(0x01);
_delay_ms(5);
LCD_COMMAND(0x0C);
_delay_ms(5);
LCD_COMMAND(0x06);
_delay_ms(5);
LCD_COMMAND(0x80);
_delay_ms(5);
}
//function to set LCD Display cursor
void CURSOR_POS(char x, char y)
{
if((x<1)|(x>2)||(y<1)|(y>16))
{
x = 1;
y = 1;
}
if(x == 1)
{
LCD_COMMAND(0x7F+y); //to start from 1st line
}
else
{
LCD_COMMAND(0xBF+y); //to start from 2nd line
}
}
void LCD_OUT(char x, char y, char* str) //to display the passed string on LCD
{
CURSOR_POS(x, y);
while(*str)
{
LCD_DATA(*str);
str++;
}
}
void LCD_CLEAR()//to clear the LCD display
{
LCD_COMMAND(0x01);
_delay_ms(2);
LCD_COMMAND(0x80);
}
void SENSOR_Init() //setting the trigger pin as output
{
DDRC |= (1<<0);
}
void SENSOR_Trigger() //making the trigger pin high to low after 15 microseconds
{
PORTC |= (1<<0);
_delay_us(15);
PORTC &= ~(1<<0);
}
uint16_t PULSE_WIDTH() //function definition to calculate the pulse width(timer 1)
{
uint32_t i, result; //local variables
//waiting for some random amount of time(value of Delay)
for(i=0; i<Delay; i++)
{
if(!(PINC & (1<<1))) //if less than the given time then break else continue
continue;
else
break;
}
//checking if timer value is equal to delay given
if(i==Delay)
return 0;
TCCR1A = 0x00;
TCCR1B = (1<<CS11);
TCNT1 = 0x00;
for(i=0; i<Delay;i++)
{
if(PINC & (1<<1))
{
if(TCNT1 > Delay)
break;
else
continue;
}
else
break;
}
if(i==Delay)
return 0;
result = TCNT1;
TCCR1B = 0x00;
//if timer value is greater than the given delay then result value is returned
if(result > Delay)
return 0;
else
return (result>>1);
}
//main function
int main()
{
LCD_INIT();//LCD_INIT function call
char numberstring[4]; //character string
while(1)
{
uint16_t r;
_delay_ms(100);
SENSOR_Init(); //SENSOR_Init function call
while(1)
{
SENSOR_Trigger(); //SENSOR_Trigger function call
r = PULSE_WIDTH(); //storing the result value of function call in variable r
if(r==0)//if no value is returned print error
{
CURSOR_POS(1,1);
LCD_OUT(1,1,"ERROR!");
}
else //if value is returned calculate the distance and print
{
distance = (r*0.034/2.0);
LCD_OUT(1,0,"Distance");
itoa(distance, numberstring, 10); //converts integer into string
LCD_OUT(2,4,numberstring);
LCD_OUT(2,10,"cm");
_delay_ms(30);
}
}
}
}
Code Screenshot:






Output:



