Challenge

Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)

Overview of the Project:

This code is designed to measure distance using an ultrasonic sensor (HC-SR04) and display the measured distance on an LCD in the ATMega328 AVR Microcontroller.

#include <avr/io.h> // Include AVR input/output library
#define F_CPU 16000000L // Define the clock frequency to be 16 MHz
#include <util/delay.h> // Include delay library
#include <stdlib.h> // Include standard library

// Define PORTD bits for RS, EN and RW pins of the LCD
#define rs_high PORTD |=(1<<0);
#define rs_low PORTD &=~(1<<0);
#define en_high PORTD |= (1<<2);
#define en_low PORTD &=~(1<<2);
#define rw_high PORTD |= (1<<1);
#define rw_low PORTD &= ~(1<<1);

// Define the Ultrasonic Sensor Pins
#define SENSOR_PORT PORTC // Define the port that the Ultrasonic Sensor is connected to
#define	SENSOR_PIN	PINC // Define the input pin for the Ultrasonic Sensor

#define SENSOR_TRIG	PC0 // Define the trigger pin for the Ultrasonic Sensor
#define SENSOR_ECHO	PC1 // Define the echo pin for the Ultrasonic Sensor



// Function to send LCD commands
void lcd_cmd(unsigned char cmd)
{
	PORTB = cmd; // Set the PORTB to the command value
	rs_low; // Set RS to low to indicate command mode
	rw_high; // Set RW to high to indicate a write operation
	en_high; // Set EN to high to enable the command
	_delay_ms(10); // Wait for the command to be executed
	en_low; // Set EN to low to disable the command
}

// Function to send LCD data
void lcd_data(unsigned char data)
{
	PORTB = data; // Set the PORTB to the data value
	rw_low; // Set RW to low to indicate a write operation
	rs_high; // Set RS to high to indicate data mode
	en_high; // Set EN to high to enable the data
	_delay_ms(10); // Wait for the data to be executed
	en_low; // Set EN to low to disable the data
}

// Function to initialize the LCD
void lcd_init()
{
	rw_high; // Set RW to high to indicate a write operation
	rs_high; // Set RS to high to indicate data mode
	en_high; // Set EN to high to enable the data
	
	PORTB = 0xff; // Set PORTB to all ones
	
	_delay_ms(30); // Wait for the command to be executed
	 lcd_cmd(0x38); // Set the LCD to 2-line mode
     lcd_cmd(0x02); // Set the cursor to the home position
     lcd_cmd(0x01); // Clear the LCD screen
     lcd_cmd(0x0c); // Turn on the display
     lcd_cmd(0x06); // Set the cursor to move right
     lcd_cmd(0x80); // Set the cursor to the beginning of the first line
	_delay_ms(30); // Wait for the command to be executed
}


void cursorpos(char row,char column)//CURSOR POSITION FUNCTION
{
	if((row<1 || row>2)||(column<1 || column>16)) // check if the cursor position is within the limits of the LCD screen
	{
		row=1; // set row position to 1 if out of range
		column=1; // set column position to 1 if out of range
	}
	if (row == 1) 
	{
		lcd_cmd(0x80 + column-1 );
	} 
	else
	 {
		lcd_cmd(0xC0 + column-1 );
	 }

}

void lcd_out(char row, char column,char *str)//LCD OUT FUNCTION
{
	cursorpos(row,column); // set cursor position to a, b
	while(*str)
	{
		lcd_data(*str); // print each character of the string on the LCD
		str++;
	}
}


void HCSR04Trigger()
{  
	SENSOR_PORT |=(1<<SENSOR_TRIG);	// set the trigger pin high
	_delay_us(15);				    // wait for 15 microseconds
	SENSOR_PORT &=~(1<<SENSOR_TRIG);	// set the trigger pin low
}

/*Measure the pulse duration*/
int GetPulseWidth()
{
	// Wait for the echo pin to go high to start measuring the pulse duration
	while (!(SENSOR_PIN & (1 << SENSOR_ECHO)));
	
	//Setup Timer1
	TCCR1A=0X00;
	TCCR1B=(1<<CS11);	// This line sets the resolution of the timer 8 bit prescaler
	TCNT1=0x00;			// This line starts the timer counter to begin counting the duration of the pulse
	
	// Wait for the echo pin to go low to stop measuring the pulse duration
	while (SENSOR_PIN & (1 << SENSOR_ECHO))
	{
		if (TCNT1 > 65535) // If the pulse is too long, break out of the loop to avoid overflow.
		break;
	}
	
	uint16_t result =TCNT1;    // Store the value of the counted pulse time in the TCNT1 register, which represents the pulse width duration.
	TCCR1B=0x00; // Stop the timer
	
	return (result); // Return the pulse width
}

int main()
 {
	lcd_init(); // Initialize the LCD
	char numberString[7]; // Define an array to store char to be display on the LCD
  _delay_ms(100); // Wait for the LCD module to start
		
		while(1)
		 {
			HCSR04Trigger(); // Send a trigger pulse
			uint16_t width = GetPulseWidth(); // Measure the width of the pulse

			// Calculate the distance in centimeters
			int distance = (width * 0.034 / 2.0);//speed * time

			// Display the distance on the LCD
			lcd_out(1, 0, "Distance:");
			itoa(distance, numberString, 10);
			lcd_out(1, 10, numberString);
			lcd_out(2, 10, "cm");

	
			_delay_ms(30);
		}
	
}

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.