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 lighting 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.
    • Handheld units that can be pointed on vehicles to measure their speed.
    • Fixed unit installed in check booths that can click pictures of over
      speeding vehicles (Remember NFS Most Wanted?)
Ultrasonic Range Finder

Ultrasonic Range Finder Module

The reason for using ultrasonic wave are:-

  • 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.

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.

TCCR1A=0X00;

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
0
0
0
No Clock Source (Timer/Counter Stopped)
0
0
1
clki/o/1 (No Prescaling)
0
1
0
clki/o/8 (No Prescaling)
0
1
1
clki/o/64 (No Prescaling)
1
0
0
clki/o/256 (No Prescaling)
1
0
1
clki/o/1024 (No Prescaling)
1
1
0
See data sheet page 110
1
1
1
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

TCCR1B=(1<<CS11);

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
result=TCNT1;
//Stop Timer
TCCR1B=0x00;

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 time-out
    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.


1     /********************************************************************
2
3     Example program to learn interfacing Ultra Sonic Range Finder Module
4     with AVR ATmega32 Microcontroller.
5      
6                                          NOTICE
7                                --------
8     NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
9     WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
10    OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
11    HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN 
12    COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.
13
14
15    WRITTEN BY:
16    AVINASH GUPTA
17    me@avinashgupta.com
18    ********************************************************************/
19
20    #include <avr/io.h>
21    #include <util/delay.h>
22
23    #include "lcd.h"
24
25    /********************************************************************
26
27    Configuration Area.
28    UltraSonic (US) sensor connection.
29
30    in this example it is connected to PORTA bit 0
31
32    Adjust the following to connect is to different i/o
33
34    ********************************************************************/
35
36    #define US_PORT PORTA
37    #define  US_PIN   PINA
38    #define US_DDR    DDRA
39
40    #define US_POS PA0      //PORTA0
41
42
43    /********************************************************************
44
45    This function measusers the width of high pulse in micro second.
46
47    ********************************************************************/
48
49    #define US_ERROR 0xffff
50    #define  US_NO_OBSTACLE 0xfffe
51
52    uint16_t getPulseWidth()
53    {
54       uint32_t i,result;
55
56       //Wait for the rising edge
57       for(i=0;i<600000;i++)
58       {
59          if(!(US_PIN & (1<<US_POS))) continue; else break;
60       }
61
62       if(i==600000)
63          return 0xffff; //Indicates time out
64
65       //High Edge Found
66
67       //Setup Timer1
68       TCCR1A=0X00;
69       TCCR1B=(1<<CS11); //Prescaler = Fcpu/8
70       TCNT1=0x00;       //Init counter
71
72       //Now wait for the falling edge
73       for(i=0;i<600000;i++)
74       {
75          if(US_PIN & (1<<US_POS))
76          {
77             if(TCNT1 > 60000) break; else continue;
78          }
79          else
80             break;
81       }
82
83       if(i==600000)
84          return 0xffff; //Indicates time out
85
86       //Falling edge found
87
88       result=TCNT1;
89
90       //Stop Timer
91       TCCR1B=0x00;
92
93       if(result > 60000)
94          return 0xfffe; //No obstacle
95       else
96          return (result>>1);
97    }
98
99    void Wait()
100   {
101      uint8_t i;
102      for(i=0;i<10;i++)
103         _delay_loop_2(0);
104   }
105   void main()
106   {
107      uint16_t r;
108
109      Wait();
110
111      //Initialize the LCD Module
112      LCDInit(LS_NONE);
113
114      Wait();
115
116      LCDClear();
117      LCDWriteString("Ultra Sonic");
118      LCDWriteStringXY(0,1,"Sensor Test");
119
120      Wait();
121      Wait();
122      Wait();
123      Wait();
124      Wait();
125      Wait();
126
127      LCDClear();
128
129
130      while(1)
131      {
132
133         //Set Ultra Sonic Port as out
134         US_DDR|=(1<<US_POS);
135
136         _delay_us(10);
137
138         //Give the US pin a 15us High Pulse
139         US_PORT|=(1<<US_POS);   //High
140
141         _delay_us(15);
142
143         US_PORT&=(~(1<<US_POS));//Low
144
145         _delay_us(20);
146
147         //Now make the pin input
148         US_DDR&=(~(1<<US_POS));
149
150         //Measure the width of pulse
151         r=getPulseWidth();
152
153         //Handle Errors
154         if(r==US_ERROR)
155         {
156            LCDWriteStringXY(0,0,"Error !");
157         }
158         else  if(r==US_NO_OBSTACLE)
159         {
160            LCDWriteStringXY(0,0,"Clear !");
161         }
162         else
163         {
164
165            int d;
166
167            d=(r/58.0); //Convert to cm
168
169            LCDWriteIntXY(0,0,d,4);
170            LCDWriteString(" cm");
171
172            Wait();
173         }
174      }
175
176   }

Hardware Setup for Ultrasonic Range Finder Test

The test circuit will be built around
ATmega32
microcontroller.
The output device will be a 16×2
lcd modul
e. So we set up a basic ATmega32 circuit. The circuit
will have the following :-

  1. ATmega32 MCU
  2. 16MHz Crystal
  3. Reset Circuit.
  4. 5v Power Supply Circuit.
  5. ISP (For programming)
  6. LCD Module.
  7. LCD Module Contrast adjust pot.
avr and accelerometer circuit

Schematic for AVR ATmega32 and LCD Connection.

Please note that power supply circuit is NOT shown in the above schematic.
You will need a 7805
voltage regulato
r IC in order to generate 5v from any source of 8-18v.

The above circuit is so common that you may require it as a base for several
projects and experiment. For that reason we have made a fully assembled and
tested unit on a professional PCB. You can buy one of them from the following
link.

If you are using the xBoard
v2.0
then you don’t need to built any circuit. Just hookup the
LCD Module as shown below.

A 16×2 Character Alphanumeric LCD Module Supplied with xBoard

 

A 12 PIN Connector is already soldered to the LCD Module

 

12 PIN Header For LCD Module Connection on xBoard.

 

LCD Module Connected.

 

The Whole Setup.


Connect PA0 to SIG Pin on Sensor

Other wise you may also buy a Low
Cost AVR Development Board
, but it does not has in built LCD Module
connector so you need to solder it your self at the free area (and also do the
wiring).

Extra 5v out is available in most development board. Connect the 5v and GND
from the dev board to the Ultrasonic Range Finder. Finally connect the PA0 from
devboard to the SIG pin of uSonic Module.

Compile the above program using AVR Studio (compiler is avr-gcc). And finally
burn the program using any ISP Programmer to the ATmega32. The fuse
bits must be set as following to enable external crystal as clock source.

  • High Fuse = C9 (hex value)
  • Low fuse =FF (hex value)

After burning the HEX file to MCU, finally you are ready to power up the setup.
When powered on, the LCD Screen Should show you the distance of the
obstacle in cm.
This complete our test. You may consult the video at
the end of article for how you can verify the readings.

Troubleshooting

  • NO Display on LCD
    • Make sure AVR Studio Project is set up for clock frequency of 16MHz
      (16000000Hz)
    • Adjust the Contrast Adj. Pot.
    • Press reset few times.
  • Incorrect Reading or Screen Says "Error".
    • Check connection between MCU and Module (PORTA0)
    • Check if Fuse Bits are set as told above or not.
    • Check whether Crystal is 16MHz or not.
  • Compiler Errors
    1. Many people these days has jumped to embedded programming without a
      solid concept of computer science and programming. They don’t know the
      basics of compiler and lack experience. To learn basic of compilers and
      their working PC/MAC/Linux( I mean a desktop or laptop) are great platform.
      But embedded system is not good for learning about compilers
      and programming basics. It is for those who already have these
      skills and just want to apply it.
    2. Make sure all files belonging to the LCD Library are "added"
      to the "Project".
    3. avr-gcc is installed. (The Windows Binary Distribution is called WinAVR)
    4. The AVR Studio project Type is AVR GCC.
    5. Basics
      of Installing and using AVR Studio with avr-gcc is described in this tutorial
    6. How
      to add files to project is described in this tutorial.
  • General Tips for newbies

Video for Ultrasonic Range Finder Test

Reader’s Contribution

Mr. Uttam Dutta has extended the code to include a relay driver that turns on the relay when an object comes nearer than predefined distance. This output is then used to play a audio warning. You can see the Video here.

Downloads

Help Us!

We try to publish beginner friendly tutorials for latest subjects in embedded
system as fast as we can. If you like these tutorials and they have helped you
solve problems, please help us in return. You can donate any amount
as you like securely using a Credit or Debit Card or Paypal
.





We would be very thankful for your kind help.

 

Other Ultrasonic Range Finder Modules

If you are using other ultrasonic range finder module such as the HC-SR04 sensor which has separate trigger and echo line (four pin type), you may refer to the following tutorials.

Ultrasonic Range Finder HC-SR04
Ultrasonic Range Finder HC-SR04

 

Ultrasonic Rangefinder HC-SR04 Interfacing with ATmega8 : This tutorial will show you how to interface this sensor with ATmega8 microcontroller. The distance measured (in cm) is shown on a 16×2 alphanumeric LCD module. In the tutorial you will find hex file ready to burn and complete Atmel Studio 6 project with source code.

By

Avinash Gupta

Facebook,
Follow on Twitter.

www.AvinashGupta.com

me@avinashgupta.com