Ultrasonic Distance Sensor

From Open Source Ecology
Jump to: navigation, search


Tech Support


  • Ultrasonic sensor on plasma table - [5]


  • From EMC list [6] - Banner Engineering sensor PDF - 1-11" range - [7]
  • Making a better HC-SR04 distance sensor - Emil - [8]

Here is a good starting template Arduino sketch (code measuring distance) for the HC-SR04: https://www.arduino.cc/en/tutorial/ping Also present on the top of that page is an accurate visual circuit diagram of how the wires should be connected to work with the sketch. Connect the USB / serial cable from your computer to the Arduino, go to the Tools menu, select the port that you will use. I am using the Genuino Arduino IDE - the official IDE developed by the Arduino team. Select the arrow under the File menu option to upload the sketch to the Arduino. If you have an error message, it is likely you selected the wrong port (also verify you have a light on the Arduino, an LED should light up if the cable is connected) or you may not have run the IDE with administrator rights (on Linux you will likely have to use "sudo"). If you are using Ubuntu, here is the page I used to look up the error I had: https://askubuntu.com/questions/646254/arduino-serial-port-com1-problem

Once you are able to upload the sketch to the Arduino without an error, it's actually running right away. In order to see the output of the program, go to the Tools menu and select "serial monitor". A window will come up where you can see the instantaneous distance measurements scrolling.

The code templates available are not actually giving very accurate readings - typically they print out the distance in centimeters, or even worse, inches. We need millimeters. In order to get millimeters, we have to modify the code and add another division to go from cm to mm (divide by 100). However, this is not enough if it'll only ever return the same thing it did but listed as in millimeters.

Let's first review some physics: http://learn.parallax.com/support/reference/speed-sound-air-vs-temperature Short summary: sound leaves the ultrasonic wavelength speaker on the sensor, bounces off whatever surface it hits, and hopefully comes back toward the microphone. The Arduino measures the time between when the sound leaves the speaker and when it is detected by the microphone. It uses the following equation to convert from the delay time to the calculated distance. Note that the speed of sound in air is dependent on temperature more than anything else. A difference of 10 degrees Fahrenheit will change the speed of sound by approx 4.64 meters per second, which will affect the calculated distance as well. In other words, we are going to have to include temperature in the equation, and we should enter the temperature or get it using another sensor before depending on the readings for precise measurements.

Here is the equation: Let C be speed of sound in air Let Tc be temperature in degrees Celsius Let Tf be temperature in degrees Fahrenheit

The starting equation is in Celsius (from the link above): C = 331.5 + (0.6 * Tc) m/s

To convert to Tf, we use this equation: Tc = (Tf - 32) / 1.8 and substitute that for Tc in the first equation: C = 331.5 + (0.6 * (Tf - 32) / 1.8) m/s

Simplified: C = 331.5 + ((0.6/1.8) * (Tf - 32) = 331.5 + (1/3)*Tf - 32/3 C = 320.83333 + 1/3Tf

OK, now for the code to go along with the above - open a new Arduino sketch and paste this code in:--------------

/* Ping))) Sensor

  This sketch reads a PING))) ultrasonic rangefinder and returns the
  distance to the closest object in range. To do this, it sends a pulse
  to the sensor to initiate a reading, then listens for a pulse
  to return.  The length of the returning pulse is proportional to
  the distance of the object from the sensor.
  The circuit:
   * +V connection of the PING))) attached to +5V
   * GND connection of the PING))) attached to ground
   * SIG connection of the PING))) attached to digital pin 7
  created 3 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe
  modified 20 Apr 2017
  by Jacob Johnson
  This example code is in the public domain.

// this constant won't change. It's the pin number // of the sensor's output: const int pingPin = 7;

long duration = 0;

//Change this to the current temp before running the sensor. //We will get this from a temp sensor later. const int tempF = 78; //In degres Fahrenheit

void setup() {

 // initialize serial communication:


void loop() {

 //convert the time into a distance
 //inches = microsecondsToInches(duration);
 //cm = microsecondsToCentimeters(duration);
 float sum = 0.0000;
 int counter = 0;
 while (counter < 20){
   duration = pingAndGetDurationFromEcho();
   float mm = microsecondsToMillimeters(duration, tempF);
   sum += mm;
 float averageMillimeters = sum / 20;
 Serial.print("duration: ");
 Serial.print(", millimeters: ");


long pingAndGetDurationFromEcho(){

 // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 digitalWrite(pingPin, HIGH);
 digitalWrite(pingPin, LOW);
 // The same pin is used to read the signal from the PING))): a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 pinMode(pingPin, INPUT);
 duration = pulseIn(pingPin, HIGH);
 return duration;


long microsecondsToInches(long microseconds) {

 // According to Parallax's datasheet for the PING))), there are
 // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
 // second).  This gives the distance travelled by the ping, outbound
 // and return, so we divide by 2 to get the distance of the obstacle.
 // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
 return microseconds / 74 / 2;


long microsecondsToCentimeters(long microseconds) {

 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance travelled.
 return microseconds / 29 / 2;


//All the math for calculating distance in millimeters, starting //from the equations at: //http://learn.parallax.com/support/reference/speed-sound-air-vs-temperature float microsecondsToMillimeters(long microseconds, int temperature) {

 //The above calculations do not take temperature into account.
 //A 10F difference causes a 4.64 m/s difference in sound velocity.
 //long metersPerSecond = 331.5 + (0.6 * (temperature - 32)/1.8);
 long metersPerSecond = 320.8334 + (0.333 * temperature);
 float millimetersPerSecond = metersPerSecond * 1000.0000;
 float millimetersPerMicroSecond = millimetersPerSecond / 1000000.00000;
 float millimeters = millimetersPerMicroSecond * microseconds;
 return millimeters;



  • Maxbotics - 1 mm resolution options, not water protected - 12" minimum distance - $40 - [9]. Adafruit has it.
  • Microptik - 3 mm resolution - http://www.micropik.com/PDF/HCSR04.pdf - 2-400 cm range - services@elecfreaks.com. Sample Arduino sketch - [10]
  • HC-SR04 - appears to get 3 mm accuracy - [11]. Sparkfun has the sensor + code - [12]
  • Video shows 15 cm measurement, with oscillation +- 1mm - and text says well within 2% accuracy. 2% of 15 cm is 3 mm - so this would do for measurements of torch height for 1/2" steel easily (12 mm thickness).




  • VexIQ - sensor for robots - [14]
  • 4-30 cm - $99 - [15]
  • 1-100 inch - $25 - [16]
  • $4 Sparkfun - 6"-10' - [17]
  • $6 - .5 cm accuracy - [18]