Pastebin is 300% more awesome when you are logged in. Sign Up, it's FREE!
Guest

Parallax Ping)) Sensor Wrapper

By: a guest on Jan 19th, 2012  |  syntax: C++  |  size: 3.36 KB  |  hits: 42  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /**
  2.  * Ping.cpp :: A library for using a Parallax PING))) sensor in robotic applications.
  3.  *
  4.  * @author Tom Malone <tmalone+arduino.software@gmail.com>
  5.  * @copyright Copyright 2012 Tom Malone. Released into the public domain.
  6.  */
  7.  
  8. #include <string.h>
  9. #include "Ping.h"
  10.  
  11. // Constructor
  12. Ping::Ping(uint8_t pin, String distanceUnit) {
  13.     this->_pin = pin;                           // Save the pin number. NOTE: Parallax PING))) sensors are used with DIGITAL pins.
  14.     this->_distanceUnit = distanceUnit;
  15.     this->_centimetersPerSecond = 29.412;
  16. }
  17.  
  18. // Public methods
  19.  
  20. /**
  21.  * Activates the Ping))) senor.
  22.  * From the Ping))) documentation:
  23.  *              "The Ping))) sensor needs a start pulse from the micrcontroller to start its measurement.
  24.  *               A pulse to the sensor's pin that lasts for 10 microseconds is easily detected by the Ping)))
  25.  *               sensor."
  26.  */
  27. void Ping::activate() {
  28.     // Set pin to OUTPUT mode initially, so that it can be triggered during the activate() method.
  29.     pinMode(this->_pin, OUTPUT);
  30.    
  31.     // Ensure the signal pin is set to LOW before attempting to activate it.
  32.     digitalWrite(this->_pin, LOW);
  33.     delayMicroseconds(5);
  34.    
  35.     // Send the trigger pulse.
  36.     digitalWrite(this->_pin, HIGH);
  37.     delayMicroseconds(10);      // This is very important; it IS the trigger.
  38.     digitalWrite(this->_pin, LOW);      // End the trigger pulse.
  39.    
  40.     pinMode(this->_pin, INPUT); // Switch the sensor pin back to INPUT, so the microcontroller can receive the pulse duration.
  41. }
  42.  
  43. unsigned long Ping::ping() {
  44.     // Before taking a distance measurement, be sure to activate the sensor with a brief (10 microsecond) pulse.
  45.     // See the datasheet for more information.
  46.     this->activate();
  47.    
  48.     // Read the pulse duration that represents the time it took the ping echo to travel to the nearest obstacle & back.
  49.     this->_pulseDuration = pulseIn(this->_pin, HIGH);  
  50.    
  51.     if( this->_distanceUnit == "cm" ) {
  52.         return this->pulseTimeToCentimeters(this->_pulseDuration);
  53.     }
  54.    
  55.     if( this->_distanceUnit == "in" ) {
  56.         return this->pulseTimeToInches(this->_pulseDuration);
  57.     }
  58.    
  59.     // Give the Ping))) sensor time to stabilize (i.e. give any
  60.     // resounding ping echos time to subside, before proceeding, so
  61.     // they don't interfere with any subsequent pings).
  62.     delay(250);
  63.    
  64.     return this->_pulseDuration;
  65. }
  66.  
  67. uint16_t Ping::pulseTimeToCentimeters(unsigned long pulseDuration) {
  68.     // The duration of the pulse represents the round trip the ping took.
  69.     // We're only interested in the distance TO the obstacle.
  70.     uint16_t distanceInTime = pulseDuration / 2;
  71.    
  72.     // The speed of sound is approximately 340 meters/second (but it varies based on a number of factors, including altitude, humidity, etc.),
  73.     // or approximately  centimeters per microsecond.
  74.     return uint16_t( round(distanceInTime / this->_centimetersPerSecond) );
  75. }
  76.  
  77. float Ping::pulseTimeToInches(unsigned long pulseDuration) {
  78.     int cmValue = this->pulseTimeToCentimeters(pulseDuration);
  79.     return this->_centimetersToInches(cmValue);
  80. }
  81.  
  82. uint8_t Ping::getCollisionThreshold() {
  83.     return this->_collisionThreshold;
  84. }
  85.  
  86. void Ping::setCollisionThreshold(uint8_t newThresholdValue) {
  87.     this->_collisionThreshold = newThresholdValue;
  88. }
  89.  
  90. // Private methods
  91. float Ping::_centimetersToInches(float cmValue) {
  92.     return cmValue * 0.393700787;
  93. }