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)
Goals:
- Measuring the distance of an object using Ultrasonic Distance Sensor (HC-SR04)
- Usage of Input Capture Mode
Key Highlights of the Project:
- Measuring the distance travelled by the wave to the object and gets bounced back from the object to sensor.
- Measuring Pulse width using Input Capture Mode
Deliverables of this project:
- The distance travelled by a wave to the object for which we want to measure the distance using Ultrasonic Distance Sensor (HC-SR04).
- Measuring Pulse width using Input Capture Mode of Timer 1
Expected Outcomes:
The students will get the Knowledge on Ultrasonic sensor (HC-SR04) to measure the distance travelled by wave to the object, the hardware connection of Atmega328p and HC-SR04 and how to use input capture mode of Timer1
Code:
/*
* Challange : Project 2.c
* Write a c program to receive a character from the serial port of Atmega 32. If it is “a” to “z”, change it to capital letters and send it back.
* Created: 9/14/2023 5:54:35 PM
* Author : Mainak Kumar Das
*/
#include
#include
#define F_CPU 16000000L //Setting the Clock speed of the cpu
//Attaching Ultrasonic sensor
#define US_PORT PORTC //connect the Ultrasonic sensor on port C. to use the ultrasonic we need two pins of the ultrasonic to be connected on port C
#define US_PIN PINC // when we want to take input, we need to initialize the pin resistor .
#define US_DDR DDRC // we need data-direction-resistor (DDR) to set the direction of data flow. input or output. we will define it later, now we're just naming it.
#define US_TRIG_POS PINC5 //Trigger pin of ultrasonic sound sensor is connected to port C pin 5
#define US_ECHO_POS PINC4 //Echo pin of the ultrasonic sound sensor is connected to port C pin 4
#define US_ERROR -1 // we're defining two more variables to know if the ultrasonic sensor is working or not
#define US_NO_OBSTACLE -2 //If no obstacles are there
#define lcdport PORTB //Using PORT B for LCD RS and EN
#define rs_high() PORTD |= (1<<0>
#define en_high() PORTD |= (1<<2>
#define rs_low() PORTD &= ~(1<<0>
#define en_low() PORTD &= ~(1<<2>
int distance, previous_distance; //Essential variables for distance calculation
void HCSR04Init() //Initializing the HCSR04 Ultrasonic sensor
{
// we're setting the trigger pin as output as it will generate ultrasonic sound wave
US_DDR|=(1<
}
void HCSR04Trigger() //Triggering
{ // this function will generate ultrasonic sound wave for 15 microseconds
//Send a 10uS pulse on trigger line
US_PORT|=(1<
_delay_us(15); //wait 15uS
US_PORT&=~(1<
}
uint16_t GetPulseWidth() //Measuring the pulse duration
{
// this function will be used to measure the pulse duration. When the ultra sound echo back after hitting an object
// the microcontroller will read the pulse using the echo pin of the ultrasonic sensor connected to it.
uint32_t i,result; //Variable
// in Section - 1: In the following lines of code before the section - 2 is checking if the ultrasonic is working or not
// it checks the echo pin for a certain amount of time. If there is no signal it means the sensor is not working or not connect properly
for(i=0;i<600000>
{
if(!(US_PIN & (1<
continue; //Line is still low, so wait
else
break; //High edge detected, so break.
}
if(i==600000)
return US_ERROR; //Indicates time out
//High Edge Found
// Section -2 : Here in This section is all about preparing the timer for counting the time of the pulse. Timers in microcontrllers is used for timimg operation
//Setup Timer1
TCCR1A=0X00;
TCCR1B=(1<
TCNT1=0x00; // This line start the counter to start counting time
// Section -3 : This section checks weather there is any object or not
for(i=0;i<600000>
{
if(US_PIN & (1<
{
if(TCNT1 > 60000)
break;
else
continue; // if the TCNT1 value gets higher than 60000 it means there is not object in the range of the sensor
}
else
break;
}
if(i==600000)
return US_NO_OBSTACLE; //Indicates time out
//Falling edge found
result=TCNT1; // microcontroller stores the the value of the counted pulse time in the TCNT1 register. So, we're returning this value to the
// main function for utilizing it later
//Stop Timer
TCCR1B=0x00;
if(result > 60000)
return US_NO_OBSTACLE; //No obstacle
else
return (result>>1);
}
void lcd_cmd(unsigned char cmd) //Create the function for LCD command
{
lcdport = cmd;
rs_low();
en_high();
_delay_ms(1);
en_low();
}
void cursorpos(char x, char y) //Setting the cursor position
{
if((x<1>2)||(y<1>16))
{
x=1;
y=1;
}
if (x==1)
{
lcd_cmd(0x7f+y);
}
else
{
lcd_cmd(0xBf+y);
}
}
void lcd_data(unsigned char data) //Create a function for LCD data
{
lcdport = data;
rs_high();
en_high();
_delay_ms(1);
en_low();
}
void lcd_init() //Create a function to initialize the LCD
{
lcd_cmd(0x38);_delay_ms(5);
lcd_cmd(0x02);_delay_ms(5);
lcd_cmd(0x01);_delay_ms(5);
lcd_cmd(0x0c);_delay_ms(5);
lcd_cmd(0x06);_delay_ms(5);
lcd_cmd(0x80);_delay_ms(5);
}
void lcd_out(char a, char b, char *str) //
{
cursorpos(a,b);
while(*str)
{
lcd_data(*str);
str++;
}
}
void lcd_print(char row, char coloumn, unsigned int value, int digits)
{
unsigned int temp;
unsigned int unit;
unsigned int tens;
unsigned int hundred;
unsigned int thousand;
unsigned int million;
unsigned char flag=0;
if(row==0 || coloumn == 0)
{
cursorpos(1,1);
}
else
{
cursorpos(row,coloumn);
}
if(digits==5 || flag==1)
{
million = value/1000+48;
lcd_data(million);
flag=1;
}
if(digits==4 || flag==1)
{
temp = value/1000;
thousand = temp +48;
lcd_data(thousand);
flag=1;
}
if(digits==3 || flag==1)
{
temp = (value)/100;
hundred = (temp +48);
lcd_data(hundred);
flag=1;
}
if(digits==2 || flag==1)
{
temp = value/10;
tens = temp +48;
lcd_data(tens);
flag=1;
}
if(digits==1 || flag==1)
{
unit = value + 48;
lcd_data(unit);
}
if(digits>>5)
{
lcd_data('o');
}
}
void lcd_clear() //Clearing the LCD
{
lcd_cmd(0x01); // this line clears the LCD screen
_delay_ms(2); // waits for two milliseconds
lcd_cmd(0x80); // this line sets the cursor to the row 1 column 1
}
int main()
{
lcd_init(); //initializing the LCD
while(1) {
uint16_t r; //Variable
_delay_ms(100); //LCD Module starting
HCSR04Init(); //Initializing the sensor
while(1)
{
HCSR04Trigger(); //Sending the trigger pulse, calling the ultrasonic sound wave generator function
r=GetPulseWidth(); //Measuring the width of the pulse, getting the duration of the ultrasound took to echo back after hitting the object
if(r==US_ERROR) //Handling the Errors, if microcontroller doesn't get any pulse then it will set the US_ERROR variable to -1
{
lcd_out(1,1,"Error!");
}
else
{
distance=(r*0.034/2.0); // This Calculation will give the distance in centimeters
if (distance != previous_distance) //Clearing the LCD, whenever its required
{
lcd_clear();
}
lcd_out(1,1,"Distance = "); //Printing the distance and the value of it with unit "cm"
lcd_print(1,11,distance,3);
lcd_out(1,14," cm");
previous_distance = distance;
_delay_ms(30);
}
}
}
}

Since there is No Obstucle to varying the the distance, we are utilizing the Variable Voltage to varying the sensor reading

Changing the simulated distance by adjusting the voltage value

