Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
Project 2 Live batch 9
Aim: To implement the code for “Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
- Measure the distance travelled by the wave to the object and gets bounced back from the object to sensor
- Measure Pulse width using Input Capture Mode
Ultrasonic distance sensor (HC-SR04)
- Measure distance by using ultrasonic waves
- The sensor head emits an ultrasonic wave and receives the wave reflected back from the target
- Ultrasonic / level sensors measure the distance to the target by measuring the time between the emission and reception
Code
#include <avr/io.h> //we are using the I/O registers of AVR
#define F_CPU 16000000L // define the CPU frequency
#include <util/delay.h> // delay function
#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 RW_high PORTD |= (1<<1);
#define RW_low PORTD &= ~(1<<1);
#define US_ERROR -1 // check ultrasonic sensor is working or not
#define US_NO_OBSTACLE -2
#define US_PORT PORTC // connect the Ultrasonic sensor on port C (2 pins)
#define US_PIN PINC // initialize the pin resistor
#define US_DDR DDRC // set the direction of data flow input or output
#define US_TRIG_POS PC0 // the trigger pin connected to port C0
#define US_ECHO_POS PC1 // echo pin connected to port C1
int distance, previous_distance;
void lcd_cmd(unsigned char cmd) //lcd_command function
{
PORTB= cmd;
RS_low;
RW_high;
EN_high;
_delay_ms(1);
EN_low;
}
void lcd_data(unsigned char data) //data function
{
PORTB= data;
RW_low;
RS_high;
EN_high;
_delay_ms(1);
EN_low;
}
void lcd_init() //initialization
{
RW_high;
RS_high;
EN_high;
PORTB = 0xff; //make lcd data portB direction as output
lcd_cmd(0x38);_delay_ms(5); //16x2 lcd 8 bit
lcd_cmd(0x02);_delay_ms(5); //
lcd_cmd(0x01);_delay_ms(5); //clear command
lcd_cmd(0x0c);_delay_ms(5); //display on, cursor off
lcd_cmd(0x06);_delay_ms(5); //auto increment
lcd_cmd(0x80);_delay_ms(5); // 8th line, 0th position
}
void cursorpos(char x,char y) //Cursor position
{
if((x<1 || x>2)||(y<1 || y>16)) //condition will checks the 2 rows and 16 columns
{
x=1;
y=1;
}
if (x==1)
{
lcd_cmd(0x7F+y); //{ 80-1 = 7F} for starting the 1st line hex decimal value (80)(7f+y to start from that column)
}
else
{
lcd_cmd(0xBF+y); //{0C-1 = 0B} for starting the 2nd line, 2nd row
}
}
void lcd_out(char a, char b,char *str) //lcd out function, checking position we want to print
{
cursorpos(a,b);
while(*str)
{
lcd_data(*str);
str++;
}
}
void lcd_clear()
{
lcd_cmd (0x01); // clear 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()
{
// setting the trigger pin as output as it will generate ultrasonic sound wave
US_DDR|=(1<<US_TRIG_POS);
}
void HCSR04Trigger()
{ // this function will generate ultrasonic sound wave for 15 microseconds
//Send a 10uS pulse on trigger line
US_PORT|=(1<<US_TRIG_POS); //high
_delay_us(15); //wait 15uS
US_PORT&=~(1<<US_TRIG_POS); //low
}
uint16_t GetPulseWidth()
{
// measure the pulse duration ,When the ultra sound echo back after hitting an object
// read the pulse using the echo pin of the ultrasonic sensor connected to it
uint32_t i,result;
// 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(!(US_PIN & (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
//Setup Timer1
TCCR1A=0X00;
TCCR1B=(1<<CS11); // set the resolution of the timer Maximum of how much value it should count
TCNT1=0x00; // start the counter
for(i=0;i<600000;i++) // the 600000 value is used randomly to denote a very small amount of time, almost 40 milliseconds
{
if(US_PIN & (1<<US_ECHO_POS))
{
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; //store value of the counted pulse time in the TCNT1 register
//Stop Timer
TCCR1B=0x00;
if(result > 60000)
return US_NO_OBSTACLE; //No obstacle
else
return (result>>1);
}
int main(void)
{
lcd_init(); // initializing LCD
char numberString[4]; // we are defining an array of character to store integer to be displayed on the LCD screen
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(); // duration of the ultrasound
//Handle Errors
if(r==US_ERROR) //send US_ERROR variable to -1 if no pulse
{
cursorpos(1, 1); //lcd_setCursor(column, row)
char j[10] = "Error!";
lcd_out(1,1,&j);
}
else
{
distance=(r*0.034/2.0); // distance in centimeters
char f[15]= "Distance = ";
lcd_out(1,0,&f);
itoa(distance, numberString, 10); // distance is an integer number, this line converts integer into array of character
lcd_out(2,4,numberString);
char h[6] = " cm";
lcd_out(2,10,&h);
previous_distance= distance;
_delay_ms(30);
}
}
}
}
Figure 1-7 shows the program code to determine the distance using ultrasonic distance sensor (HC-SR04)







Figure 8 shows the distance obtained on running the program

By changing the potentiometer values we can the change the distance and the ultrasesnsor sense and displays
The trigger and echo pulse are displayed through oscilloscope

Comments
- On getting a trigger pulse, HC-SR04 sends ound waves and the microcontroller waits for rising edge output at the Echo pin
- When the rising edge capture occurs at the Echo pin, start Timer and again wait for a falling edge on the Echo pin
- When falling edge is captured at the Echo pin, the microcontroller reads the count of the Timer
- This time count is used to calculate the distance to an object
- Sound velocity = 343.00 m/s = 34300 cm/s
- The distance of Object (in cm) = Sound velocity *Timer/2
= 32300*Timer/2
= 17150*Timer
- Now, here we have selected an internal 8 MHz oscillator frequency for ATmega16, with No-presale for timer frequency. Then time to execute 1 instruction is 0.125 us
- So, the timer gets incremented after 0.125 us time elapse
= 17150 x (TIMER value) x 0.125 x 10^-6 cm
= 0.125 x (TIMER value)/58.30 cm
= (TIMER value) / 466.47 cm
- 600000 value is used randomly to denote a very small amount of time, almost 40 miliseconds
- For i==600000, error message is received
- for i<600000, high edge detected
- TCNT1 value gets higher than 60000 it means there is not object in the range of the sensor
- Trigger function generate ultrasonic sound waves
- PORTB is connected as data port
- C0 and C1 of PORTC is connected to ultrasonic sensor
- RS,EN and RW is connected to D0,D2,D1 of PORTD
- The program is loaded in the Atmega 32 chip
- LCD pins are connected to the Atmega32 as shown above and the program is loaded
- Osillocope and ultrasonic sensors are connected to view the output
- Ultrasonic sensor helps to detect whether a obstacle is present or not and also measures the distance of the object
Result
- Implemented the code for “Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
- Measured the distance travelled by the wave to the object and gets bounced back from the object to sensor.