Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Measuring distance of an object using ultrasonic sensor (HC-SR04)
- Ultrasonic Module HC-SR04 works on the principle of SONAR and RADAR system.
- HC-SR-04 module has an ultrasonic transmitter, receiver, and control circuit on a single board.
- The module has only 4 pins, Vcc, Gnd, Trig, and Echo.
- When a pulse of 10µsec or more is given to the Trig pin, 8 pulses of 40 kHz are generated. After this, the Echo pin is made high by the control circuit in the module.
- The echo pin remains high till it gets an echo signal of the transmitted pulses back.
- The time for which the echo pin remains high, i.e. the width of the Echo pin gives the time taken for generated ultrasonic sound to travel towards the object and return.
- Using this time and the speed of sound in air, we can find the distance of the object using a simple formula for distance using speed and time.
Calculation (distance in cm) (H1)
Sound velocity = 343.00 m/s = 34300 cm/s
The distance of Object (in cm) = (Sound Velocity×Timer)/2
= (34300×Timer)/2
=17150×Timer
Now, here we have selected an internal 8 MHz oscillator frequency for ATmega32, with No-presale for timer frequency. Then time to execute 1 instruction is 0.125 us.
So, the timer gets incremented after 0.125 us time elapse.
= 17150 x (Timer value) x 0.125 x 10^-6 cm
= 0.125 x (Timer value)/58.30 cm
= (Timer value) / 466.47 cm
CODE
Here the lcd is operating in 4-bit mode to save IO pins of microcontroller,so we can use those ports for other functions.
#include <avr/io.h>//I/O registers for avr
#define F_CPU 8000000UL//clock frequency of 16MHz
#include <util/delay.h>//delay functions
#include //for string handling
#include // general purpose standard library of C for memory allocation, process control, conversions
#include <avr/interrupt.h>//interrupt functions
#define lcdport PORTD //lcd data line
#define rs_high PORTC |= (1<<0);//pin 0 of portC is used as register select(RS) of lcd
#define rs_low PORTC &= ~(1<<0);
#define en_high PORTC |= (1<<1);//pin 1 of portC is used as Enable pin(En) of lcd
#define en_low PORTC &= ~(1<<1);
#define RW_high PORTC |= (1<<2);
#define RW_low PORTC &= ~(1<<2);
#define triggerpin_high PORTA |=(1<<0);//set trigger pin of ultrasonic sensor (pin0 of portA)
#define triggerpin_low PORTA &=~(1<<0);
void lcd_cmd(unsigned char cmd);//command function for lcd
void lcd_data(unsigned char data);//data function for lcd
void lcd_init();//initialization function for lcd
void cursor_pos(char x,char y);//function for entering cursor position
void lcd_out(char x,char y,char *str);//function for printing string characters
int timer_overflow=0;
ISR(TIMER1_OVF_vect)//Increment Timer Overflow count on each timer1 OVF interrupt
{
timer_overflow++;
}
int main(void)
{
DDRA=0X01;//set trigger pin as output
PORTB=(1<<0);//enable internal pull up resistor
char string[10];
long count;
double distance;
lcd_init();//initialize lcd
sei();//Enable global interrupt
TIMSK=(1<<TOIE1);//enable timer1 overflow interrupt
TCCR1A=0;//set as normal mode
lcd_out(1,0,"Ultrasonic");
while (1)
{
triggerpin_high;//set trigger pin of HC-SR04 high for min 10 microseconds and then set low
_delay_us(10);
triggerpin_low;
TCNT1=0;//clear timer counter
TCCR1B=0X41;//set input capture at rising edge and clock select with no prescaling
TIFR=(1<<TOV1);
TIFR=(1<<ICF1);//clear ICF1 flag and Timer/Counter0 Overflow Flag
while((TIFR & (1<<ICF1))==0);//wait for ICF in rising edge mode
TCNT1=0;
TCCR1B=0X01;//set input capture at falling edge with no prescaling
TIFR=(1<<TOV1);
TIFR=(1<<ICF1);//clear ICF1 flag and Timer/Counter0 Overflow Flag
timer_overflow=0;//clear timer overflow count
while((TIFR & (1<<ICF1))==0);//wait for ICF in falling edge mode
count=ICR1+(65535*timer_overflow);//ICR1 value is added with no of times TOV1 occurred with 65535
distance=(double)count/466.47;//Timer freq of 8MHz ,no prescaler and speed of sound of 343m/s
dtostrf(distance,2,2,string);//distance to string
strcat(string," cm ");//Concat unit cm
lcd_out(2,1,"Dist = ");//display distance value in cm on lcd
lcd_out(2,7,string);
_delay_ms(100);
}
}
void lcd_cmd(unsigned char cmd)//command function for lcd
{
lcdport=(lcdport & 0x0F) | (cmd & 0xF0);//data is assigned to lcdport in 4-bit lcd mode(send upper nibble)
RW_low;
rs_low;
en_high;
_delay_ms(1);// 1 Millisecond delay
en_low;
_delay_ms(2);// 2 Millisecond delay
lcdport=(lcdport & 0x0F) | (cmd<<4);//send lower nibble
en_high;
_delay_ms(1);// 1 Millisecond delay
en_low;
_delay_ms(2);// 2 Millisecond delay
}
void lcd_data(unsigned char data)//data function for lcd
{
lcdport=(lcdport & 0x0F) | (data & 0xF0);//data is assigned to lcdport in 4-bit lcd mode(send upper nibble)
RW_low;
rs_high;
en_high;
_delay_ms(1);// 1 Millisecond delay
en_low;
_delay_ms(2);// 2 Millisecond delay
lcdport=(lcdport & 0x0F) | (data<<4);//send lower nibble
en_high;
_delay_ms(1);// 1 Millisecond delay
en_low;
_delay_ms(2);// 2 Millisecond delay
}
void lcd_init()//initialization function for lcd
{
DDRC=(1<<0)|(1<<1)|(1<<2);//set RS,En,RW pins as output
DDRD=0XFF;//set all pins of portD as output for lcd data
_delay_ms(20);
lcd_cmd(0X02); // send for 4 bit initialization of LCD
lcd_cmd(0X28); // 2 line, 5*7 matrix in 4-bit mode
lcd_cmd(0X0C); // Display on cursor off
lcd_cmd(0X06); //Increment cursor (shift cursor to right)
lcd_cmd(0X01); // Clear display screen
_delay_ms(2);
}
void cursor_pos(char x,char y)//function for entering cursor position
{
if((x<1 || x>2) || (y<1 || y>16))//if cursor row selected is beyond its max or min range it gets reseted
{
x=1;
y=1;
}
if(x==1)
{
lcd_cmd(0x80+y);//force cursor begin 1st line
}
else
{
lcd_cmd(0xC0+y); //force cursor begin 2nd line lcd_cmd((y & 0X0F)|0xC0)
}
}
void lcd_out(char x,char y,char *str)//function for printing string characters
{
cursor_pos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
Code screenshots






Simulation in SimulIDE

Waveform in LogicAnalyzer
