UltraSonicDistance

UltraSonic Distance Measurement


SRF06-450.jpg
Size about 1.75x.75 in, 4.5x2.0 cm
Small low-cost ultrasonic distance measurement modules like this: HC-SR04
are an effective way to sense the presence of nearby objects and the distance to them. Often Robots use these to sense objects or collisions and take appropriate action.

See code for the US-100 type sensor HERE

Here's how these modules work:

They have two transducers, basically a speaker and a microphone.

Ultrasound is a high frequency sound (typically 40 KHz is used). A short burst of sound waves (often only 8 cycles) is sent out the "Transmit" transducer (left, above). Then the "Receive" transducer listens for an echo. Thus, the principle of ultrasonic distance measurement is the same as with Radio-based radar.

Distance is calculated as: L = C × T/2 , where L is the length, C is the speed of sound in air, T is the time difference from the transmission from the transmitter to the receiver. This is divided by 2 for the two-directions the sound travels. Speed of sound is about: C = 344m / s (20 degrees C room temperature).

Speed of sound in air velocity is affected by the air density, and for high accuracy the temperature must be taken into account, either within the module electronics (In the SRF-06 module we have) or in the Arduino software.

We have a page HERE with much more information about Ultrasonics and Echo Location.

Ultrasonic-2-512.jpgThe module in our example has 4 pins:
  1. Vcc Operating voltage: 5.0V
  2. Trig the transmit signal pin
  3. Echo the received echo pin
  4. Gnd Ground

Accuracy??

It's hard to get good information from the manufacturers. Here are numbers derived from some extensive tests done by "RiGonz" on the Arduino Forum:
As per my measurements the facts regarding the HC-SR04 are:
- FOV (full cone): horizontal ~20º, vertical ~13º
- Spatial resolution (full cone): ~0.6-1.4º
- Range: tested from 5 to 200 cm
- Accuracy: relative error ~0/5% (-1.3 ±4.6 %); absolute error ~-0.5/-1.5 cm (-0.4 ±1.2 cm).
- Precision: standard deviation ~0.1/0.5 cm (0.3 ±0.6 cm)

Note: The US-100 module has 5 pins but two are ground and 1 to 4 are the same.

To test a module with the following Software Sketch, connect 5.0V and Ground to your Arduino, and Trig to Arduino pin 11 and Echo to Arduino pin 10. This photo shows the easy way to do this using a YourDuinoRobo1 and part of a flat cable jumper:

Software will do the following:
  • Turn the Trig pin on and off to send out a sound pulse
  • Monitor and time how long until the Echo pin sees the echo
  • Calculate the distance as shown above, possibly correcting for temperature

Following is an example Arduino Software Sketch to show how this works. It uses a library called NewPing. See it / get it HERE: This library can give you the Time, or the distance in cm or Inches. You will need to copy this to your computer, UnZip the file and copy the folder and its contents to the "libraries" folder on your computer. This is typically like:
C:\Users\(yourname)\Documents\Arduino\libraries. If you're already running the Arduino development software, you will have to restart it in order for it to see the new library.

NOTE: At the bottom of this page is another example showing how to make decisions based on distance.

Detailed Information on Tim Eckel's NewPing Library and Timers etc. (Click)

Here is the Software Sketch (New Version 2.0 January 2013) you can cut and paste into a New window on your Arduino IDE:

/* YourDuino SKETCH UltraSonic Serial 2.0
 Runs HC-04 and SRF-06 and other Ultrasonic Modules
 Open Serial Monitor to see results
 Reference: http://playground.arduino.cc/Code/NewPing
 Questions?  terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <NewPing.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define  TRIGGER_PIN  11
#define  ECHO_PIN     10
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters).
                         //Maximum sensor distance is rated at 400-500cm.
/*-----( Declare objects )-----*/
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
/*-----( Declare Variables )-----*/
int DistanceIn;
int DistanceCm;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  Serial.println("UltraSonic Distance Measurement");
  Serial.println("YourDuino.com  terry@yourduino.com");
}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(100);// Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
  DistanceIn = sonar.ping_in();
  Serial.print("Ping: ");
  Serial.print(DistanceIn); // Convert ping time to distance and print result 
                            // (0 = outside set distance range, no ping echo)
  Serial.print(" in     ");
  
  delay(100);// Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
  DistanceCm = sonar.ping_cm();
  Serial.print("Ping: ");
  Serial.print(DistanceCm); 
  Serial.println(" cm");  

}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/

// None
//*********( THE END )***********



After downloading this to your Arduino, open the Serial Monitor and you should see output like this:
UltraSonic Distance Measurement
YourDuino.com  terry@yourduino.com
64cm   25inches
64cm   24inches
63cm   24inches
64cm   25inches
64cm   25inches
64cm   24inches
64cm   25inches
63cm   24inches
64cm   25inches
64cm   25inches
64cm   25inches
64cm   24inches
 
 
Move some flat object like a book in front of the sensor and move it in and out to see the changing distance.

Different objects will reflect a different amount of the Ultrasonic wave, so results will vary a lot. Here are a few examples:

1 ball-point pen, 200mm
2 Hand, 400mm
3.1mm thick plastic sleeve with a wire, 30mm
4. Vernier caliper, 450mm
5. The body (wearing thick clothes), 400mm
6. Wall, 1200mm
7. 1mm thickness soft cotton: undetectable
8. bamboo toothpick, 40mm
9. Stationary Cat ???

Questions or comments welcome
Regards, Terry King
terry@yourduino.com

Example code showing how to make decisions on distance:

/* YourDuino SKETCH UltraSonic Serial 2.0
*** Modified to find distance < 3 inches (7cm)
*** Frances Mae Gerpacio
 Runs HC-04 and SRF-06 and other Ultrasonic Modules
 Open Serial Monitor to see results
 Reference: http://playground.arduino.cc/Code/NewPing
 Questions?  terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <NewPing.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define  TRIGGER_PIN  11
#define  ECHO_PIN     10
#define MAX_DISTANCE  14 // Maximum distance we want to ping for (in centimeters).
                         //Maximum sensor distance is rated at 400-500cm.
/*-----( Declare objects )-----*/
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
/*-----( Declare Variables )-----*/
int DistanceIn;
int DistanceCm;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  Serial.println("UltraSonic Distance Measurement");
  Serial.println("YourDuino.com  terry@yourduino.com");
}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(100);// Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
  DistanceIn = sonar.ping_in();
  Serial.print("Ping: ");
  Serial.print(DistanceIn); // Convert ping time to distance and print result 
                            // (0 = outside set distance range, no ping echo)
  Serial.print(" in     ");
  
  delay(100);// Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
  DistanceCm = sonar.ping_cm();
  Serial.print("Ping: ");
  Serial.print(DistanceCm); 
  Serial.println(" cm");  
  if ( (DistanceCm <= 7) && (DistanceCm != 0) )
  {
  Serial.println("3 Inches or closer! ");
  }

}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/

// None
//*********( THE END )***********





US-100 ULTRASONIC SENSOR:

This sensor has temperature compensation and is more accurate over a range of air temperatures.

Using the US-100 Distance Sensor in Serial Data Mode:

Place the jumper block on the operating mode selection pins to choose serial data mode. Attach the module to a serial port on your microcontroller. The Trig/TX pin connects to your microcontroller's TX serial transmit line. The Echo/RX pin connects to your microcontroller's RX serial receive line. Set the microcontroller's serial port to use 9600 baud at 8-N-1 (eight data bits, no parity, one stop bit).

To start measuring the distance, output a 0x55 over the serial port and read back the two byte distance in high byte, low byte format. The distance returned is measured in millimeters. Use the following formula to obtain the distance as millimeters:
Millimeters = FirstByteRead * 256 + SecondByteRead

This module can also output the temperature when using serial output mode. To read the temperature, delay 1ms or more and then output a 0x50 byte over the serial port and read back a single temperature byte. The actual temperature is obtained by using the following formula:
Celsius = ByteRead - 45

Here is an example sketch by David Todd, who found the delay before reading temperature is necessary..

/* 
 *  us100.ino
 *  Program to test US-100 ultrasonic distance sensor module in UART mode
 *  Connect pin 2 of Nano to US100 trigger/Tx pin
 *  Connect pin 3 of Nano to US100 Echo/Rx pin
 *  Connect US100 pin 1 to Vcc and pins 4&5 to GND
 *  
 *  Program reports distance from sensor to closest object in mm
 *  and sensor temp in degrees Celsius and Farenheit
 *  
 *  Written by HDTodd@gmail.com, 2018\01\01
 */

#include <SoftwareSerial.h>

#define txPin    2              // Connect pin 2 of Nano to US100 trigger/Tx
#define rxPin    3              // Connect pin 3 of Nano to US100 Echo/Rx
#define getDist  0x55           // send this to get distance in mm
#define getCels  0x50           // send this to get temp
#define loopTime 2000           // delay time in ms between loop iterations
#define maxWait  1000           // max time to wait for US100 response 

SoftwareSerial us100(rxPin,txPin);  // Set Nano for UART signaling 
int     mmDist;                 // measured distance in mm
uint8_t highDist,lowDist;       // bytes read in from US100
int     cTemp;                  // temp in Celsius for reporting
float   fTemp;                  // temp in Farenheit for reporting

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);           // talk to the controlling device
  pinMode(rxPin, INPUT);        // Set pin directions for US100 communications
  pinMode(txPin, OUTPUT);
  us100.begin(9600);            // and start SoftSerial service
}

void loop() {
  Serial.println("Start sampling loop for US-100 testing");

  us100.flush();
  us100.write(getDist);         // ask US-100 to get distance; wait for response
  for ( int i=0; (i<maxWait) && !us100.available(); i++ ) delay(1);
  if (us100.available()) {
    highDist = us100.read();    // get high byte
    for ( int i=0; (i<maxWait) && !us100.available(); i++ ) delay(1);
    if (us100.available()) {
      lowDist = us100.read();   // get low byte
      mmDist = highDist*256 + lowDist;
      }
    else {
      Serial.println("Incomplete response to distance request");
      mmDist = 0;
    }
  }
  else {
    Serial.println("No response to distance request");  
    mmDist = 0;
    };
    
  delay(1);                     // let US100 catch its breath, otherwise won't respond
  us100.flush();
  us100.write(getCels);
  for ( int j=0; (j<maxWait) && !us100.available(); j++ ) delay(1);
  if (us100.available()) {
    cTemp = us100.read() - 45;
    fTemp = cTemp * 1.8 + 32;
    }
    else {
      Serial.println("No response to temp request");
      cTemp = 0;
      fTemp = 0.0;
    };

  Serial.print("Distance = ");  Serial.print(mmDist);
  Serial.print(" mm    Temp = ");  Serial.print(cTemp);
  Serial.print(" C = ");  Serial.print(fTemp);  Serial.println(" F");

  delay(loopTime);
}