Challenge

Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)

Overview of the Project:

In this project, the implementation of code for “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

Key Highlights of the Project:

  • Measuring the distance travelled by the wave to the object and gets bounced back from the object to sensor.
  • Measuring Pulse width using Input Capture Mode

Deliverables of this project:

  • The distance travelled by a wave to the object for which we want to measure the distance using Ultrasonic Distance Sensor (HC-SR04).
  • Measuring Pulse width using Input Capture Mode of Timer 1

Expected Outcomes:

The students will get the Knowledge on Ultrasonic sensor (HC-SR04) to measure the distance travelled by wave to the object, the hardware connection of Atmega328p and HC-SR04 and how to use input capture mode of Timer1

Working Principal

We are going to use PB0 (Input Capture Pin1) for the echo terminal of the HC_SR04 Ultrasonic sensor. As ICP1 will be used for Timer 1 interrupt so when the echo pin will be in the falling edge then an interrupt will be generated.

/////////////////////////////// Code //////////////////////////////


#include <avr/io.h> // avr library
#define F_CPU 16000000
#include <util/delay.h> // for using delay functions
#include "avr/interrupt.h" // include interrupt library for using global interrupts
#define ECHO 0 //Input, It is a ICP1 PIN (Input Capture Pin)
#define TRIG 3 // Output

#define rs_high() PORTB |=(1<<7); // reset pin of lcd
#define rs_low() PORTB &= ~(1<<7);

#define en_high() PORTB |= (1<<6); // enable pin of lcd
#define en_low() PORTB &= ~(1<<6);

#define lcdport PORTD // deffining port for writting data


// below are various functions declaration for lcd operation
void lcd_command(unsigned char cmd);

void lcd_data(unsigned char data);

void lcd_init();

void cursorpos(char x, char y);

void lcd_print(char row, char column, unsigned int value, int digits);

void lcd_out(char x, char y, char *str);


long count;
int main(void)
{

int distance= 0;
DDRB |= (1<<TRIG); // CONFIGURED AS OUTPUT
DDRB &= ~(1<<ECHO); // CONFIGURED AS INPUT
lcd_init(); // initializing the lcd.
sei(); // Enable global interrupt
TIMSK1 |= (1<<ICIE1); // Enable required Timer1 interrupt

TCCR1A = 0x00;
TCCR1B &= ~(1<<ICES1); // Falling Edge Capture

while (1)
{
PORTB &= ~(1<<TRIG); // off
_delay_us(2);
PORTB |= (1<<TRIG); // turn on Trigger to generate pulse
_delay_us(10); // keep the trigger "ON" for 10 micro seconds
PORTB &= ~(1<<TRIG); // Turn off trigger to stop pulse
// If pulse reached the receiver echoPin
// become high Then ultrasonic_time() returns the
// time taken by the pulse to reach the receiver

TCCR1B |= (1<<1); // Timer 1 in normal mode, 8 prescalar
// 16 MHz/8 = 2MHz => T= 0.5 microseconds.
TCNT1 = 0; // timmer counter start

// total time = counts * 0.5 micro second (Time_period) = count/2
// d = (total_time/2) * speed ==> distance = (count *speed)/4

distance = (count * 0.0344)/4;
lcd_out(1,3,"Dis = "); // for string printing in row 1
lcd_print(1,9,distance,3); // for digit print in row 1
lcd_out(1,12,"cm"); // for string printing in row 1

lcd_out(2,1,"ICRvalue= "); // for string printing in row 2
lcd_print(2,11,count,5); // for digit print in row 2

_delay_ms(250); // for stable operation
}
}

// Implement ISR Function

ISR (TIMER1_CAPT_vect)
{
count = ICR1; // transfer input capture register value to variable count
TCCR1B &= ~(1<<1); // Stop Timer1
}


///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/////////////////////////////// Functions for LCD ////////////////////////

void lcd_command(unsigned char cmd)
{
// function for giving predefined commands to lcd
lcdport = cmd;
rs_low();
en_high();
_delay_ms(1); // delay
en_low();
}

void lcd_data(unsigned char data)
{
// function for giving data to lcd in form of ASCI value
lcdport = data;
rs_high();
en_high();
_delay_ms(1);
en_low();
}

void lcd_init()
{
// using lcd function previously made for initialization purpose
lcd_command(0x38);_delay_ms(500);
lcd_command(0x02);_delay_ms(500);
lcd_command(0x01);_delay_ms(5);
lcd_command(0x0c);_delay_ms(5);
lcd_command(0x06);_delay_ms(5);
lcd_command(0x80);_delay_ms(5);

}

void cursorpos(char x, char y)
{
// set cursor of lcd to desired location
if( (x < 1 || x > 2) || (y < 1 || y > 16) )
{
x = 1;
y = 1;
}
if(x == 1)
lcd_command(0x80+y);
else
lcd_command(0xC0+y);

}

void lcd_print(char row, char coloumn, unsigned int value, int digits)
{
// printing integer values of sensor and variables
unsigned int temp;
unsigned int unit;
unsigned int tens;
unsigned int hundred;
unsigned int thousand;
unsigned int million;

unsigned char flag=0;

if(row==0||coloumn==0)
{
cursorpos(1,1);
}
else
{
cursorpos(row,coloumn);

}


if(digits==5|| flag==1)
{
// adding 48 last to make itEquivalent to ASCI decimal value of digits.
million=value/10000+48;
lcd_data(million);
flag=1;
}
if(digits==4 || flag==1)
{
// flag is used for ladder logic implementation
temp = value/1000;
thousand = temp%10 +48;
lcd_data(thousand);
flag=1;
}
if(digits==3 || flag==1)
{
// for 3rd digit number
temp = value/100;
hundred = temp%10 +48;
lcd_data(hundred);
flag=1;
}
if(digits==2 || flag==1)
{
// for 2nd digit number
temp = value/10;
tens= temp%10 +48;
lcd_data(tens);
flag=1;
}
if(digits==1 || flag==1)
{
// for 1st digit number
unit = value%10 + 48;
lcd_data(unit);
}
if(digits>5)
{// print error if digits are more then 5
lcd_data('e');
}
}
void lcd_out(char x,char y,char *str)
{
// for printing string on lcd screen
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.