Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
#include <avr/io.h>
#define F_CPU 16000000L
#include <util/delay.h>
#define lcdport PORTB
#define rs_high PORTD |=(1<<0); //DEFINE BIT FOR RS_HIGH
#define rs_low PORTD &=~(1<<0); //DEFINE BIT FOR RS_LOW
#define en_high PORTD |= (1<<2); //DEFINE BIT FOR EN_HIGH
#define en_low PORTD &=~(1<<2); //DEFINE BIT FOR EN_LOW
#define US_ERROR -1 // we're defining two more variables two know if the ultrasonic sensor is working or not
#define US_NO_OBSTACLE -2
#define US_TRIG_POS PC0 // the trigger pin of ultrasonic sound sensor is connected to port C pin 0
#define US_ECHO_POS PC1
int distance, previous_distance;
void lcd_cmd(unsigned char cmd)
{
lcdport = cmd;
rs_low;
en_high;
_delay_ms(1);
en_low;
_delay_ms(2);
}
void lcd_data(unsigned char data)
{
lcdport = data;
rs_high;
en_high;
_delay_ms(1);
en_low;
_delay_ms(1);
}
void lcd_init()
{
lcd_cmd(0x38);_delay_ms(5); // 8-bit mode, 2 lines, 5x7 font
lcd_cmd(0x02);_delay_ms(5);
lcd_cmd(0x01);_delay_ms(5); // Clear display
lcd_cmd(0x0C);_delay_ms(5); // Display on, cursor off, blink off
lcd_cmd(0x06);_delay_ms(5); // Increment cursor
lcd_cmd(0x80);_delay_ms(5);
}
void cursorpos(char row, char col)
{
unsigned char position;
if (row == 1)
{
position = 0x80 + col - 1;
}
else if (row == 2)
{
position = 0xC0 + col - 1;
}
lcd_cmd(position);
}
void lcd_out(char a, char b,char *str) //LCD OUT FUNCTION
{
cursorpos(a,b);
while(*str)
{
lcd_data(*str);
str++;
}
}
void lcd_clear()
{
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
}
void HCSR04Init()
{
// we're setting the trigger pin as output as it will generate ultrasonic sound wave
DDRC |= (1 << US_TRIG_POS);
}
void HCSR04Trigger()
{
// this function will generate ultrasonic sound wave for 15 microseconds
//Send a 10uS pulse on trigger line
PORTC |= (1 << US_TRIG_POS); //high
_delay_us(15); //wait 15uS
PORTC &= ~(1 << US_TRIG_POS); //low
}
uint16_t GetPulseWidth()
{
// 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;
// Section - 1: the following lines of code before the section - 2 is checking if the ultrasonic is working or not
// it check 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; i++)
{
if(!(PINC & (1<<US_ECHO_POS)))
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 : 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<<CS11); // This line sets the resolution of the timer. Maximum of how much value it should
count.
TCNT1=0x00; // This line start the counter to start counting time
// Section -3 : This section checks weather the there is any object or not
for(i = 0; i < 600000; i++) // the 600000 value is used randomly to denote a very small amount of
time, almost 40 miliseconds
{
if(PINC & (1<<US_ECHO_POS))
{
if(TCNT1 > 60000) // if the TCNT1 value gets higher than 60000 it means there is not object in the range of
the sensor
break;
else
continue;
}
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);
}
int main()
{
lcd_init(); // we're initializing the LCD
char str[20];
while(1)
{
uint16_t r;
_delay_ms(100); //Let the LCD Module start
//Set io port direction of sensor
HCSR04Init();
while(1)
{
//Send a trigger pulse
HCSR04Trigger(); // calling the ultrasonic sound wave generator function
//Measure the width of pulse
r = GetPulseWidth(); // getting the duration of the ultrasound took to echo back after hitting the object
//Handle Errors
if(r == US_ERROR) // if microcontroller doesn't get any pulse then it will set the US_ERROR variable to -1
// the following code will check if there is error then it will be displayed on the LCD screen
{
cursorpos(1, 1); //lcd_setCursor(column, row)
char j[10] = "Error!";
lcd_out(1,1,&j);
}
else
{
distance=(r*0.034/2.0); // This will give the distance in centimeters
lcd_cmd(0x80);
sprintf(str,"Distance: %3dcm",distance);
for (int i = 0; str[i] != '\0'; i++)
{
lcd_data(str[i]);
}
previous_distance = distance;
_delay_ms(100);
}
}
}
}