Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Here is the code
#define F_CPU 8000000UL // Define the system clock frequency as 8 MHz
#include <avr/io.h> // Include AVR input/output header file
#include <avr/interrupt.h> // Include AVR interrupt handling header file
#include <util/delay.h> // Include delay header file
#include <string.h> // Include string handling header file
#include <stdlib.h> // Include standard library header file#define lcdport PORTB
#define lcdport PORTB // Define LCD port as PORTB
#define rs_high PORTD |= (1<<0); // Set RS pin high
#define rs_low PORTD &= ~(1<<0); // Set RS pin low
#define en_high PORTD |= (1<<1); // Set EN pin high
#define en_low PORTD &= ~(1<<1); // Set EN pin low
static volatile int pulse =0; // Declare a global variable for ultrasonic sensor
static volatile int i =0; // Declare a global variable for ultrasonic sensor
// Interrupt service routine for INT0
ISR(INT0_vect)
{
if (i==1) // If i is 1
{
TCCR1B =0; // Stop timer
pulse = TCNT1; // Store timer count in pulse variable
TCNT1=0; // Reset timer count to 0
i=0; // Reset i to 0
}
if (i==0) // If i is 0
{
TCCR1B |=(1<<CS10); // Start timer with no prescaling
i=1; // Set i to 1
}
}
// Function to send command to LCD
void lcd_cmd (unsigned char cmd)
{
lcdport=cmd; // Send command to LCD
rs_low; // Set RS pin low
en_high; // Set EN pin high
_delay_ms(1); // Delay for 1 millisecond
en_low; // Set EN pin low
}
// Function to send data to LCD
void lcd_data (unsigned char data)
{
lcdport=data; // Send data to LCD
rs_high; // Set RS pin high
en_high; // Set EN pin high
_delay_ms(1); // Delay for 1 millisecond
en_low; // Set EN pin low
}
void lcd_init()
{
lcd_cmd(0x38); // 8-bit mode, 2-line display, 5x8 font
_delay_ms(5); // Delay for 5 milliseconds
lcd_cmd(0x02); // Return home
_delay_ms(5); // Delay for 5 milliseconds
lcd_cmd(0x01); // Clear display
_delay_ms(5); // Delay for 5 milliseconds
lcd_cmd(0x0c); // Display on, cursor off
_delay_ms(5); // Delay for 5 milliseconds
lcd_cmd(0x06); // Entry mode: increment address, no display shift
_delay_ms(5); // Delay for 5 milliseconds
lcd_cmd(0x80); // Set DDRAM address to 0x00
_delay_ms(5); // Delay for 5 milliseconds
}
void lcd_print(char *str)
{
unsigned char i=0;
while (str[i]!=0)
{
lcd_data(str[i]); // Send each character of the string to the LCD
i++; // Increment i
}
}
int main(void)
{
DDRD = 0x03; // Set the direction of PORTD pins 0 and 1 as output
// (to be used as trigger and LED pins)
PORTD = 0xFF; // Turn on pull-up resistor for all pins of PORTD
GICR |= (1<<INT0); // Enable external interrupt INT0
MCUCR |= (1<<ISC00); // Set interrupt triggering to occur when INT0 is low
int16_t count_a = 0; // Initialize variable to hold distance measurement
char show_a[16]; // Initialize character array to hold distance measurement as string
sei(); // Enable global interrupts
lcd_init(); // Initialize the LCD
lcd_print("Ultrasonic"); // Display "Ultrasonic" on the LCD
_delay_ms(500); // Wait for 500 milliseconds
lcd_cmd(0x01); // Clear the LCD
lcd_print("Distance Sensor");// Display "Distance Sensor" on the LCD
_delay_ms(500); // Wait for 500 milliseconds
while(1) // Start an infinite loop
{
PORTD |= (1<<PIND3); // Set trigger pin high
_delay_ms(15); // Wait for 15 milliseconds
PORTD &= ~(1<<PIND3); // Set trigger pin low
count_a = pulse/58; // Calculate distance measurement from pulse duration
_delay_ms(1000); // Wait for 1 second
lcd_cmd(0x01); // Clear the LCD
lcd_print("Distance: "); // Display "Distance: " on the LCD
itoa(count_a, show_a, 10); // Convert distance measurement to string and store it in character array
lcd_cmd(0xC0); // Move cursor to second line of LCD
lcd_print(show_a); // Display distance measurement as string on the LCD
lcd_cmd(0xC4); // Move cursor to the end of second line on the LCD
lcd_print("cm "); // Display "cm " on the LCD
}
}