Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
In this project, the implementation of code for “Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
#include <avr/io.h>
#define F_CPU 16000000ul
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#define lcd_data_dir DDRD // define lcd data port direction
#define lcd_command_dir DDRC // define lcd command port direction
#define lcd_data_port PORTD //define lcd data port
#define lcd_command_port PORTC // define lcd data port
#define EN PC2 // define enable
#define RW PC3 // define read/write
#define RS PC4 // define register select
void lcd_command(char); // lcd command write function
void lcd_char(char); // lcd data write function
void lcd_init(void); // lcd initialize function
void lcd_string(char*); // send dtring to lcd
void lcd_string_xy (char,char,char*); // send row postion
void lcd_command (char cmd) // lcd command write function
{
lcd_data_port = cmd; // write command to lcd data port
lcd_command_port&=~((1<<RS)|(1<<RW)); // make RS low and RW low
lcd_command_port|= (1<<EN); // high to low transition on EN
_delay_ms(1);
lcd_command_port&=~(1<<EN);
_delay_ms(2); // delay provided
}
void lcd_char(char char_data) // lcd data write function
{
lcd_data_port= char_data; // write data to lcd data port
lcd_command_port&=~(1<<RW); // make RW low(write)
lcd_command_port|=((1<<EN)|(1<<RS)); // make RS high and high to low tnasition
_delay_ms(1);
lcd_command_port&=~(1<<EN);
_delay_ms(1);
}
void lcd_init(void) // lcd initialize function
{
lcd_command_dir|= (1<<RS)|(1<<RW)|(1<<EN); // lcd command port direction as output
lcd_data_dir = 0xff; //make lcd data port direction as output
_delay_ms(20); // wait
lcd_command(0x38); // 16x2 lcd 8 bit
lcd_command(0x0C); // display On
lcd_command(0x06); // auto increment cursor
lcd_command(0x01); // clear lcd command
lcd_command(0x80); // 8 is the line and 0 is oth position
}
void lcd_string(char *str) // send string to lcd function
{
int i;
for(i=0;str[i]!=0;i++) // sending each char string till tje null
{
lcd_char (str[i]); // call lcd data write
}
}
void lcd_string_xy(char row,char pos,char *str) // send string to lcd function
{
if (row == 1)
lcd_command((pos & 0x0f)|0x80);
else if (row == 2)
lcd_command((pos & 0x0f)|(0xC0));
lcd_string(str); // call lcd string function
}
#define trigger_pin PA0 // trigger pin
int TimerOverFlow = 0;
ISR(TIMER1_OVF_vect)
{
TimerOverFlow++; // increment timer overflow count
}
int main (void)
{
char string[10];
long count;
double distance;
DDRA = 0x01; // make trigger pin as output
PORTB = 0xff; // pull-up turn on
lcd_init();
lcd_string_xy(1,0,"ultrasonic");
sei(); // enable global interrupt
TIMSK = (1<< TOIE1); // enable timer 1 overflow interrupt
TCCR1A = 0; // set all bit to zero normal position
while(1)
{
PORTA |= (1<< trigger_pin);
_delay_ms(10);
PORTA &=(~(1<< trigger_pin));
TCNT1 = 0; //clear timer counter
TCCR1B = 0x41; // capture on rising edge,no pre scaler
TIFR = 1<<ICF1; // clear ICP flag
TIFR = 1<<TOV1; // clear timer overflow flag
while ((TIFR & (1<<ICF1)) == 0); // wait for rising edge
TCNT1 = 0; //clear timer counter
TCCR1B = 0x01; // capture on falling edge , no pre scaler
TIFR = 1<<ICF1; // clear ICP flag
TIFR = 1<<TOV1; // clear timer overflow flag
TimerOverFlow = 0; // clear timer overflow count
while ((TIFR & (1<< ICF1))== 0); // wait for falling edge
count = ICR1 +(65535 * TimerOverFlow); // take count
distance = (double)count/466.47;
dtostrf(distance,2,2,string); // distance to string
strcat(string,"cm"); // count unit
lcd_string_xy(2,0,"dist= ");
lcd_string_xy(2,7,string); // print distance
_delay_ms(200);
}
}
comments
Hardware setup: Connect the HC-SR04 sensor to the microcontroller according to the pinout diagram. The sensor requires four connections: Vcc, GND, Trig, and Echo. Connect Vcc and GND to the microcontroller's power supply and ground, respectively. Connect Trig to a digital output pin on the microcontroller and Echo to a digital input pin.
Trigger pulse: To start a distance measurement, send a 10us trigger pulse to the Trig pin of the HC-SR04 sensor. This can be achieved by setting the Trig pin high for 10us and then setting it low again.
Wait for echo: The sensor emits an ultrasonic wave and waits for it to reflect off an object and return to the sensor. The time it takes for the wave to travel to the object and back can be measured by monitoring the Echo pin of the sensor. Wait for the Echo pin to go high, indicating that the ultrasonic wave has been emitted.
Measure pulse width: Measure the duration of the high pulse on the Echo pin by timing how long the pin stays high. This duration is proportional to the time it took for the ultrasonic wave to travel to the object and back.