A distance measurement class using ultrasonic sensor HC-SR04.

Dependents:   Esercitazione4_4 HC-SR04 Group10_slave Oled_Gus ... more

The purpose of this library is to encourage students to develope their own classes. Instructions how to follow the development of this library for ultrasonic distance measurement are given here.

Files at this revision

API Documentation at this revision

Comitter:
tbjazic
Date:
Sat Dec 10 08:26:18 2016 +0000
Parent:
5:a667b621f625
Commit message:
Filtering with Ticker object corrected.

Changed in this revision

HCSR04.cpp Show annotated file Show diff for this revision Revisions of this file
HCSR04.h Show annotated file Show diff for this revision Revisions of this file
--- a/HCSR04.cpp	Mon Dec 07 09:57:48 2015 +0000
+++ b/HCSR04.cpp	Sat Dec 10 08:26:18 2016 +0000
@@ -6,52 +6,66 @@
 }
 
 void HCSR04::init() {
-    /** configure the rising edge to start the timer */
-    echo.rise(this, &HCSR04::startTimer);
-    
-    /** configure the falling edge to stop the timer */
-    echo.fall(this, &HCSR04::stopTimer);
-    
     distance = -1;      // initial distance
     minDistance = 2;
     maxDistance = 400;
+    newDataReady = timerStarted = false;
 }
 
 void HCSR04::startTimer() {
-    timer.start(); // start the timer
+    if (!timerStarted) {
+        timer.start(); // start the timer
+        timerStarted = true;
+        echoTimeout.attach_us(this, &HCSR04::stopTimer, 25000); // in case echo fall does not occur
+        echo.fall(this, &HCSR04::stopTimer);
+        echo.rise(NULL);
+    }
 }
 
 void HCSR04::stopTimer() {
     timer.stop(); // stop the timer
+    if (timerStarted) {
+        distance = timer.read() * 1e6 / 58;
+        if (distance < minDistance)
+            distance = minDistance;
+        if (distance > maxDistance)
+            distance = maxDistance;
+        newDataReady = true;
+    }
+    timer.reset();
+    timerStarted = false;
+    echoTimeout.detach();
+    echo.fall(NULL);
+}
+
+void HCSR04::turnOffTrigger() {
+    trigger = 0; 
 }
 
 void HCSR04::startMeasurement() {
     trigger = 1;
-    wait_us(10);
-    trigger = 0;
-    wait_us(23660); // just enough time to measure 400 cm
-    timer.stop(); // just in case echo fall did not occur
-    distance = timer.read() * 1e6 / 58;
-    if (distance < minDistance)
-        distance = minDistance;
-    if (distance > maxDistance)
-        distance = maxDistance;
-    timer.reset();
+    triggerTimeout.attach_us(this, &HCSR04::turnOffTrigger, 10);
+    echo.rise(this, &HCSR04::startTimer);
+    newDataReady = false;
 }
 
 float HCSR04::getDistance_cm() {
-    startMeasurement();
+    newDataReady = false;
     return distance;
 }
 
 float HCSR04::getDistance_mm() {
-    startMeasurement();
+    newDataReady = false;
     return distance * 10;
 }
 
+bool HCSR04::isNewDataReady() {
+    return newDataReady;
+}
+
 void HCSR04::setRanges(float minRange, float maxRange) {
     if (minRange < maxRange) {
-        if (minRange >= 2) 
+        if (minRange >= 2 && minRange < 400) // bug from revs. 4 and 5 corrected
             minDistance = minRange;
         if (maxRange <= 400)
             maxDistance = maxRange;
--- a/HCSR04.h	Mon Dec 07 09:57:48 2015 +0000
+++ b/HCSR04.h	Sat Dec 10 08:26:18 2016 +0000
@@ -9,15 +9,24 @@
  * #include "HCSR04.h"
  *
  * Serial pc(USBTX, USBRX);
+ * Timer timer;
  *
  * int main() {
  *     HCSR04 sensor(p5, p7);
  *     sensor.setRanges(10, 110);
  *     pc.printf("Min. range = %g cm\n\rMax. range = %g cm\n\r",
  *       sensor.getMinRange(), sensor.getMaxRange());
- *     while(1) {
+ *     while(true) {
+ *         timer.reset();
+ *         timer.start();
+ *         sensor.startMeasurement();
+ *         while(!sensor.isNewDataReady()) {
+ *             // wait for new data
+ *             // waiting time depends on the distance
+ *         }
  *         pc.printf("Distance: %5.1f mm\r", sensor.getDistance_mm());
- *         wait_ms(500);
+ *         timer.stop();
+ *         wait_ms(500 - timer.read_ms()); // time the loop
  *     }
  * }
  * @endcode
@@ -32,12 +41,17 @@
      */
     HCSR04(PinName echoPin, PinName triggerPin);
     
-    /** Calculates the distance in cm, with the calculation time of approximatelly 23.7 ms.
+    /** Start the measurement. Measurement time depends on the distance.
+     *  Maximum measurement time is limited to 25 ms (400 cm).
+     */
+    void startMeasurement();
+    
+    /** Returns the distance in cm. Requires previous call of startMeasurement().
      * @returns distance of the measuring object in cm.
      */
     float getDistance_cm();
     
-    /** Calculates the distance in mm, with the calculation time of approximatelly 23.7 ms.
+    /** Returns the distance in mm. Requires previous call of startMeasurement().
      * @returns distance of the measuring object in mm.
      */
     float getDistance_mm();
@@ -58,6 +72,11 @@
      */
     float getMaxRange();
     
+    /** Checks if the new data is ready.
+     * @returns true if new data is ready, false otherwise.
+     */
+    bool isNewDataReady();
+    
     private:
     
     InterruptIn echo;       // echo pin
@@ -66,6 +85,8 @@
     float distance;         // store the distance in cm
     float minDistance;      // minimum measurable distance
     float maxDistance;      // maximum measurable distance
+    Timeout triggerTimeout, echoTimeout;
+    bool newDataReady, timerStarted;
     
     /** Start the timer. */
     void startTimer();
@@ -76,8 +97,7 @@
     /** Initialization. */
     void init();
     
-    /** Start the measurement. */
-    void startMeasurement();
+    void turnOffTrigger();
 };
 
 #endif
\ No newline at end of file