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
Code:-
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include
#include
#define F_CPU 16000000UL
#define lcd_data_dir DDRD
#define lcd_command_dir DDRC
#define lcd_data_port PORTD
#define lcd_command_port PORTC
#define EN PC2
#define RW PC3
#define RS PC4
void lcd_command(char);
void lcd_data(char);
void lcd_init(void);
void lcd_out(char*);
void lcd_print(char, char, char*);
void lcd_command(char cmd)
{
lcd_data_port = cmd;
lcd_command_port &= ~((1 << RS) | (1 << RW));
lcd_command_port |= (1 << EN);
_delay_ms(1);
lcd_command_port &= ~(1 << EN);
_delay_ms(2);
}
void lcd_data(char data)
{
lcd_data_port = data;
lcd_command_port &= ~(1 << RW);
lcd_command_port |= ((1 << EN) | (1 << RS));
_delay_ms(1);
lcd_command_port &= ~(1 << EN);
_delay_ms(1);
}
void lcd_init(void)
{
_delay_ms(20);
lcd_command(0x38);
lcd_command(0x0C);
lcd_command(0x06);
lcd_command(0x01);
lcd_command(0x80);
}
void lcd_out(char *str)
{
while (*str)
{
lcd_data(*str++);
}
}
void lcd_print(char row, char pos, char *str)
{
if (row == 1)
lcd_command((pos & 0x0F) | 0x80); // Move cursor to specified position of the first row
else if (row == 2)
lcd_command((pos & 0x0F) | 0xC0); // Move cursor to specified position of the second row
lcd_out(str); // Display the string at the specified position
}
#define trigger_pin PA0
int TimerOverFlow = 0;
ISR(TIMER1_OVF_vect)
{
TimerOverFlow++;
}
int main(void)
{
char string[10];
long count;
double distance;
lcd_command_dir |= (1 << RS) | (1 << RW) | (1 << EN); // Set control pins as output
lcd_data_dir = 0xFF; // Set data port as output
DDRA = 0x01; // Set PA0 as trigger pin
PORTB = 0xFF; // No need to initialize PORTB
lcd_init(); // Initialize LCD
lcd_print(1, 0, "Ultrasonic"); // Display "Ultrasonic" on the first line
sei(); // Enable global interrupts
TIMSK = (1 << TOIE1); // Enable Timer1 overflow interrupt
TCCR1A = 0; // Configure Timer1 for normal mode
while (1)
{
PORTA |= (1 << trigger_pin); // Generate trigger pulse
_delay_ms(10); // Delay for trigger pulse
PORTA &= ~(1 << trigger_pin); // End trigger pulse
TCNT1 = 0; // Reset Timer1 counter
TCCR1B = 0x41; // Start Timer1 with prescaler 64
TIFR = 1 << ICF1; // Clear Input Capture Flag
TIFR = 1 << TOV1; // Clear Timer1 Overflow Flag
while (!(TIFR & (1 << ICF1))); // Wait for rising edge on Echo pin
TCNT1 = 0; // Reset Timer1 counter
TCCR1B = 0x01; // Start Timer1 with no prescaler
TIFR = 1 << ICF1; // Clear Input Capture Flag
TIFR = 1 << TOV1; // Clear Timer1 Overflow Flag
TimerOverFlow = 0; // Reset Timer1 overflow counter
while (!(TIFR & (1 << ICF1))); // Wait for falling edge on Echo pin
count = ICR1 + (65535 * TimerOverFlow); // Calculate pulse width
distance = (double)count / 466.47; // Calculate distance in centimeters
dtostrf(distance, 2, 2, string); // Convert distance to string
strcat(string, "cm"); // Append "cm" to the distance string
lcd_print(2, 0, "Distance="); // Display "Distance=" on the second line
lcd_print(2, 9, string); // Display the calculated distance on the second line
_delay_ms(200);
}
}
Output:-
