Interfacing Ultrasonic Rangefinder with AVR

Obstacle detecting sensors are one of the most basic type of sensors that electronic hobbyists use. There are several methods to make cheap obstacle sensors. These simple sensors are made using a IR Rx/Tx pair or Normal LED and LDR pair(this design is most basic and is heavily affected by environment lightings conditions). These sensor may be useful for simple requirement but they have following drawbacks :-

  • Can’t say anything about the real distance of obstacle.
  • Give different result for different coloured obstacles.
  • Need calibration (like setting up a variable resistor).

To solve these problems we have IR Range Finder Module (like one made by Sharp) but they have small range.

  • Sharp GP2D12 Distance Measurement Sensor has a maximum range of 80cm
  • Sharp GP2D120 Distance Measurement Sensor has a maximum range of 30cm only.

To solve all these problem we can use an Ultrasonic Range Finder Module. An Ultrasonic Range Finder Module uses ultrasonic waves (inaudible to humans) to measure distance. These module consist of an Ultrasonic Transmitter (Tx) that emits the ultrasonic wave, the waves after striking any obstacle bounces back and reach the Ultrasonic Receiver (Rx). By measuring the time it take for the whole process to complete and using simple arithmetic we can measure the distance to the obstacle. The Ultrasonic Range Finder Modules has a wide operating range of 1cm to 400cm with an accuracy of 1cm. These specifications makes it ideal for distance measurement application. These can be used for :-

    • Contact less measurement of liquid level in tanks (even 4m deep tank!)
    • Radars for robot.
    • Obstacle sensing in Robotics.

• Speed check in roads.

o Handheld units that can be pointed on vehicles to measure their speed.

o Fixed unit installed in check booths that can click pictures of over speeding vehicles (Remember NFS Most Wanted?)

• The speed of Ultra Sonic waves is 343m/s (Speed of Sound) which is not too fast for MCUs to measure accurately. Compare this with speed of electromagnetic waves (like light or radio waves) which is 30,00,00,000 m/s! So it takes only 20ns (nano second) to go and bounce back from an obstacle which is 3m away! An AVR running at 16MIPS(maximum for most AVRs) takes 62ns to execute a single instruction.

• Ultrasonic waves travels more narrow, like a beam than normal sound wave. This property helps the sensor detect the obstacles that are exactly in line with it only. The sensors can be rotated with steppers or servo motors to get a “image” of obstacle in the surrounding area (like a radar).

• Finally the wave do not disturb any humans nearby!

 Ultrasonic Range Finder Interface.

These modules are designed to be used for microcontroller based applications hence optimized for it. The interface is a single pin called SIG (signal). The MCU is connected to the Ultrasonic Range Finder Module by a single i/o line. The steps required to read distance are :-

  1. Microcontroller make the i/o line output. (by using the DDRx Register in AVR or TRISx Register in PIC)
  2. The i/o line is made low (this may be the default state of i/o pin)
  3. Wait for 10uS
  4. Make the i/o line high.
  5. Wait for 15uS
  6. Make the i/o line low
  7. Wait for 20uS
  8. Now make it input (by using the DDRx Register in AVR or TRISx Register in PIC)
  9. Module will keep it low. Wait till it is low, as soon as it becomes high start the timer.
  10. After that wait till it is high, as soon as it becomes low copy the timer value and stop the timer.
  11. Finally we have the time required for the wave to go hit the obstacle and come back to the module.

If the pulse width is in microseconds, the distance can be calculated by the following formula :-

  • Distance in cm = Pulse width/58
  • Distance in inches = Pulse width/148

Ultrasonic Range Finder Interfacing Sample code for AVR

To understand our code for Ultrasonic Range Finder Interface you need to have basic knowledge about timers in microcontroller. In short a timer is a register which increments it value at predefined intervals without the need of any help from CPU. One of the use of timer is to measure the time accurately. Please note that modern MCUs have sophisticated timers with lots of configuration options and can be used for several purposes. For more details on setup and use of timers please refer to the following articles.

  • Introduction to AVR Timers
  • Timers in Compare Mode

Here we will use TIMER1 of ATmega32 for counting the duration of pulse. The TIMER1 has 15 different waveform generation modes. We will use the default that is called NORMAL mode. The modes are selected using 4 bits called WGM13,WGM12,WGM11,WGM10. We need the NORMAL mode which is applied by setting all four bits to 0. WGM1 stands for Waveform Generation Mode for timer 1.

To setup the TIMER1 we need to setup its control registers properly. They are called

  • TCCR1A – Timer Counter Control Register 1 A
  • TCCR1B – Timer Counter Control Register 1 B

TCCR1A – Timer Counter Control Register 1 A

This register basically deals with the Output Compare Modes so they are used when generating PWM signal from timer. As we are using timer in NORMAL mode we set most Output Compare related bits to 0. This register also has the WGM11 and WGM10, as discussed earlier we need to set all WGM1x bits to 0. This results in all 8 bits in TCCR1A set to 0. The line below is taken from example code.


TCCR1B – Timer Counter Control Register 1 B

This register has bits related to Input Capture, WGM13,WGM12 and the Clock Select Bits (CS12,CS11,C10). We need to set the input capture related bits to 0 and the WGM1x bits to 0 too. The final thing is the CS1x bits. They are used to select a clock source for TIMER1 as per the table below.

CS12 CS11 CS10 Description
No Clock Source (Timer/Counter Stopped)
clki/o/1 (No Prescaling)
clki/o/8 (No Prescaling)
clki/o/64 (No Prescaling)
clki/o/256 (No Prescaling)
clki/o/1024 (No Prescaling)
See data sheet page 110
See data sheet page 110

We are running on CPU speed of 16MHz, so our i/o clock is 16MHz. We divide this by 8 to get a 2MHz clock for our timer. This means the timer increments its value in 0.5 microsecond. We can divide the value by two to get exact 1 microsecond time base. So the TCCR1B is configured by only setting up CS11, this is written in C as follows


After setting up the timer using the two control registers, we clear the counter by writing 0 to it

TCNT1=0x00; //Init counter

After that we wait for the falling edge and as soon as it is detected we put the timer value in a temporary variable called result.

//Falling edge found
//Stop Timer

It is highly recommended to go through the Chapter 16bit timer/counter1 in the datasheet of ATmega32. TCCR1A and TCCR1B is described in page 107 to 110 of the datasheet. Also if you are very new to C programming it is recommend to read the section Operation on Bits (Bit wise Operation) in any good book of C. It is wise to enter the field of embedded programming with good grip on C language. So don’t ask me why the “0X” was prefixed before 00 when we set up TCCR1A or what does the symbol “<<“ stands on the above code line. But to help most of you I have written an article “Programming in C – Tips for Embedded Development.” that may clear some of your doubts.

The code employ some error checking and preprocessor magic that may confuse you but they are necessary for

  • Preventing the code to hang the system if uSonic Module has errors or Not connected. (Waiting forever for rising/falling edges). So we employ a timeout system.
  • Allows you to easily change the PORT and Position where the sensor is connected.

The code depends on our LCD library to handle the 16×2 LCD module which is used to present data.


Related posts:

About author

This article was written by admin

Admin has over twenty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles. Working presently as Development Manager in India. A firm Believer in Knowledge grows when it shared.


Comments (1)
  1. gaurav singh says - Posted: March 31, 2013

    hello sr can u explain TLx&THx in 8051 mcu

Leave your comment

Your email address will not be published. Required fields are marked *