Difference between revisions of "ECE 110/Equipment/Ping Sensor"

From PrattWiki
Jump to navigation Jump to search
(Sample Code)
(Sample Code)
Line 104: Line 104:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* The above code will round to the nearest inch or centimeter.  If you want higher resolution, you can use floats for those items instead of long integers.  Here is how to change the code:
+
* The above code will round to the nearest inch or centimeter.  If you want higher resolution, you can use floats for those items instead of long integers.  Here is how to change the code to make it more accurate:
 
** replace  
 
** replace  
 
   long duration, inches, cm;
 
   long duration, inches, cm;
Line 119: Line 119:
 
   return microseconds / 29 / 2;
 
   return microseconds / 29 / 2;
 
:: with
 
:: with
   return microseconds / 74.0 / 2.0;
+
   return microseconds / 74.074 / 2.0;
 
:: and  
 
:: and  
   return microseconds / 29.0 / 2.0;
+
   return microseconds / 29.155 / 2.0;
  
 +
Here is a simplified version of the whole code (using 1125 ft/s and 343 m/s as the speed of sound):
 +
<syntaxhighlight lang=C++>
 +
/*
 +
  Ping))) Sensor - higher res
 +
 +
  created 3 Nov 2008
 +
  by David A. Mellis
 +
  modified 30 Aug 2011
 +
  by Tom Igoe
 +
  modified 5 Sep 2022
 +
  by Michael Gustafson
 +
 +
  This example code is in the public domain.
 +
 +
  original: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Ping
 +
*/
 +
#include <Servo.h> 
 +
const int pingPin = 35;
 +
Servo servoLeft;
 +
Servo servoRight;
 +
 +
void setup() {
 +
  Serial.begin(9600);
 +
  pinMode(37, OUTPUT);
 +
  pinMode(39, OUTPUT);
 +
  digitalWrite(37, HIGH);
 +
  digitalWrite(39, LOW);
 +
 
 +
  servoLeft.attach(12);
 +
  servoRight.attach(11);
 +
}
 +
 +
void loop() {
 +
  long duration;
 +
  float inches, cm;
 +
  // short LOW pulse to ensure a clean HIGH pulse:
 +
  pinMode(pingPin, OUTPUT);
 +
  digitalWrite(pingPin, LOW);
 +
  // 2 ms HIGH pulse
 +
  delayMicroseconds(2);
 +
  digitalWrite(pingPin, HIGH);
 +
  // back to LOW
 +
  delayMicroseconds(5);
 +
  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);
 +
 +
  // convert the time into a distance
 +
  inches = microsecondsToInches(duration);
 +
  cm = microsecondsToCentimeters(duration);
 +
 
 +
  Serial.print(inches);
 +
  Serial.print("in, ");
 +
  Serial.print(cm);
 +
  Serial.print("cm");
 +
  Serial.println();
 +
  delay(200);
 +
}
 +
 +
float microsecondsToInches(long microseconds) {
 +
  // The speed of sound is about 1125 ft/s
 +
  // Sound takes about 74.074 us to travel 1 in
 +
  return microseconds / 74.074 / 2;
 +
}
 +
 +
float microsecondsToCentimeters(long microseconds) {
 +
  // The speed of sound is about 343 m/s
 +
  // Sound takes about 29.155 us to travel 1 cm
 +
  return microseconds / 29.155 / 2.0;
 +
}
 +
</syntaxhighlight>
 
=== Alternate Mount ===
 
=== Alternate Mount ===
 
To use the Ping sensor at the front of the CX-Bot, you can mount it to the digital pin header near the front of the bot.  Put the GND pin in 39, 5 V in 37, and SIG in 35.  You will need to put 39 LOW and 37 HIGH for this to work, and you will need to change the pingPin to 35.  The top of the code above can thus be adjusted to:
 
To use the Ping sensor at the front of the CX-Bot, you can mount it to the digital pin header near the front of the bot.  Put the GND pin in 39, 5 V in 37, and SIG in 35.  You will need to put 39 LOW and 37 HIGH for this to work, and you will need to change the pingPin to 35.  The top of the code above can thus be adjusted to:

Revision as of 04:33, 26 September 2022

Introduction

The PING ultrasonic sensor is capable of measuring distances by using ultrasonic signals that it bounces off objects. Based on the time it takes for the signal to go from the transmitter, to the object, and back the the receiver, the sensor can estimate distance travelled and then report half that as the distance away from the object.

Leads

There are two styles of PING sensor - one has three leads and the other has four leads. The CX-Bot has a header in place for the three-pin version so that will be the one used in ECE 110. Information on the four-pin version is also provided below.

For the three-pin version of the PING sensor, going from left to right when looking at the front:

  • GND: Ground
  • VCC: Supply voltage, typically 5 V
  • SIG: Pin to set high to trigger the Ping to send a pulse and to monitor to detect the pulse

For the four-pin version of the PING sensor, going from left to right when looking at the front:

  • VCC: Supply voltage, typically 5 V
  • TRIG: Pin to set high to trigger the Ping to send a pulse
  • ECHO: Pin to read to detect the pulse
  • GND: Ground

Operation

Sample Code

The following code is adapted from https://docs.arduino.cc/built-in-examples/sensors/Ping; the only change is the the CX-Bot uses pin 50 to communicate with the sensor.

/*
  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

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Ping
*/

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

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
}

void loop() {
  // establish variables for duration of the ping, and the distance result
  // in inches and centimeters:
  long duration, inches, cm;

  // 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);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  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);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}

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: https://www.parallax.com/package/ping-ultrasonic-distance-sensor-downloads/
  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;
}
  • The above code will round to the nearest inch or centimeter. If you want higher resolution, you can use floats for those items instead of long integers. Here is how to change the code to make it more accurate:
    • replace
 long duration, inches, cm;
with
 long duration;
 float inches, cm;
  • replace
 long
in front of the microsecondsToInches and microsecondsToCentimeters functions with
 float
  • replace the integers in the returns with floats; that is:
 return microseconds / 74 / 2;
and
 return microseconds / 29 / 2;
with
 return microseconds / 74.074 / 2.0;
and
 return microseconds / 29.155 / 2.0;

Here is a simplified version of the whole code (using 1125 ft/s and 343 m/s as the speed of sound):

/*
  Ping))) Sensor - higher res

  created 3 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe
  modified 5 Sep 2022
  by Michael Gustafson

  This example code is in the public domain.

  original: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Ping
*/
#include <Servo.h>  
const int pingPin = 35;
Servo servoLeft;
Servo servoRight;

void setup() {
  Serial.begin(9600);
  pinMode(37, OUTPUT);
  pinMode(39, OUTPUT);
  digitalWrite(37, HIGH);
  digitalWrite(39, LOW);
  
  servoLeft.attach(12);
  servoRight.attach(11);
}

void loop() {
  long duration;
  float inches, cm;
  // short LOW pulse to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  // 2 ms HIGH pulse
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  // back to LOW
  delayMicroseconds(5);
  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);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  delay(200);
}

float microsecondsToInches(long microseconds) {
  // The speed of sound is about 1125 ft/s
  // Sound takes about 74.074 us to travel 1 in
  return microseconds / 74.074 / 2;
}

float microsecondsToCentimeters(long microseconds) {
  // The speed of sound is about 343 m/s
  // Sound takes about 29.155 us to travel 1 cm
  return microseconds / 29.155 / 2.0;
}

Alternate Mount

To use the Ping sensor at the front of the CX-Bot, you can mount it to the digital pin header near the front of the bot. Put the GND pin in 39, 5 V in 37, and SIG in 35. You will need to put 39 LOW and 37 HIGH for this to work, and you will need to change the pingPin to 35. The top of the code above can thus be adjusted to:

const int pingPin = 35;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  pinMode(37, OUTPUT);
  pinMode(39, OUTPUT);
  digitalWrite(37, HIGH);
  digitalWrite(39, LOW);
}

Notes

References