Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Live batch 5
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
Soln:
HC-SR04 : This is the HC-SR04 ultrasonic distance sensor. This economical sensor provides 2cm to 400cm of non-contact measurement functionality with a ranging accuracy that can reach up to 3mm. Each HC-SR04 module includes an ultrasonic transmitter, a receiver and a control circuit. It works by sending sound waves from the transmitter, which then bounce off of an object and then return to the receiver. You can determine how far away something is by the time it takes for the sound waves to get back to the sensor.
Program :
#include <avr/io.h> //Preprocessor for AVR
#define F_CPU 16000000L //Clock frequency
#include <util/delay.h> //Delay function
#include "avr/interrupt.h"
//define PORTB as the data lines names as lcdport
#define lcdport PORTB //PORTB as LCDport
//define reg selector by setting and clearing the corresponding bit
#define rs_high PORTD|=(1<<0); //PORT D pin 0 making as high
#define rs_low PORTD&=~(1<<0); //PORT D pin 0 making as low
//define enable by setting and clearing the corresponding bit
#define en_high PORTD|=(1<<1); //PORT D pin 1 making as high
#define en_low PORTD&=~(1<<1); //PORT D pin 0 making as low
unsigned int tov=0,count, distance; //global variable declaration and initialization
void lcd_command(unsigned char cmd); //function prototype
void lcd_data(unsigned char data); //function prototype
void lcd_init(); //function prototype
void cursorpos(char x, char y); //function prototype
void lcd_out(char x, char y, char *str); //function prototype
void lcd_print(char row, char coloumn, unsigned int value, int digits); //function prototype
int main(void) //main function
{
DDRB=0xff; //Set the DDRB as output
DDRD=0x03; //Set the DDRD portd pin 3 as output
DDRC |=(1<<0); //set DDRC as trigger input
sei(); // enable the global interrupt
lcd_init(); //caller function
TCCR1A=0x00; //Normal port operation
TIMSK|=(1<<2); //enabling TOIE1 pin ,Timer1 overflow interrupts
while(1) //continuous iteration
{
PORTC|=(1<<0); //enabling the HC-SR04
_delay_us(10); //delay
PORTC&=~(1<<0); //clearing the HC-SR04
TCCR1B=0x41; //Capture on rising edge, No prescale
TCNT1=0; //Clear Timer counter
TIFR=(1<<ICF1); // Clear ICP flag (Input Capture flag)
TIFR=(1<<TOV1); //Clear Timer Overflow flag
tov=0; // Clear Timer overflow count
while((TIFR&(1<<ICF1))==0); //Wait for rising 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
tov=0; // Clear Timer overflow count
while((TIFR&(1<<ICF1))==0); //Wait for falling edge
count = ICR1 + (65535 * tov); //Take count
//16Hz Timer freq, sound speed
distance = (unsigned int)count /932.87; //distance calculation
lcd_print(1,1,distance,4); //distance to sensor
lcd_out(1,6,"cm"); //to display on lcd
}
}
ISR(TIMER1_OVF_vect)
{
tov++; //increment tov
}
void lcd_cmd(unsigned char cmd) //unction definition for lcd command
{
lcdport=cmd; //assigning cmd to lcdport
rs_low; //calling rs_low
en_high; //calling en_high
_delay_ms(1); ////delay
en_low; //calling en_low
}
void lcd_data(unsigned char data) // function definition for lcd data
{
lcdport=data; //assigning data to lcdport
rs_high; //calling rs_low
en_high; //calling en_high
_delay_ms(1); //delay
en_low; //calling en_low
}
void lcd_init()
{
lcd_cmd(0x38);_delay_ms(5); //2 lines 5x7 matrix delay of 5ms
lcd_cmd(0x02);_delay_ms(5); //Return home delay of 5ms
lcd_cmd(0x01);_delay_ms(5); //Clearing screen delay of 5ms
lcd_cmd(0x0c);_delay_ms(5); //Display on ,cursor off delay of 5ms
lcd_cmd(0x06);_delay_ms(5); //Incrementing cursor delay of 5ms
lcd_cmd(0x80);_delay_ms(5); //Force cursor begin 1st line delay of 5ms
lcd_cmd(0xC0);_delay_ms(5); //Display on ,cursor off delay of 5ms
}
void cursorpos(char x, char y) // function definition for lcd cursor position
{
if((x<1||x>2)||(y<1||y>16)) //checking for row and column position
{
x=1;
y=1;
}
if(x==1) //to do when the LCD row is equal to 1
lcd_cmd(0x80+y); //Cursor force to start from 1st row
else
lcd_cmd(0xc0+y); //Cursor force to start from 2nd row
}
void lcd_out(char x,char y, char *str) //create a function definition for accessing/print the string on LCD
{
cursorpos(x,y); //calling the cursor position function
while(*str)
{
lcd_data(*str); //passing the string as parameter
str++; //increment str
}
}
void lcd_print(char row, char coloumn, unsigned int value, int digits) //function definition for print the digital values
{
unsigned int temp,unit,tens,hundred,thousand,million; //variable declarations
unsigned char flag=0;
if(row==0||coloumn==0)
{
cursorpos(1,1); //calling the cursor position function
}
else
{
cursorpos(row,coloumn); //calling the cursor position function
}
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');
}
}
Output :



