涂 桂旺 / HCSR04

Fork of HCSR04 by TVZ Mechatronics Team

Revision:
6:cf3e4e307d15
Parent:
4:aae70f15357f
Child:
7:e53b2476821e
diff -r a667b621f625 -r cf3e4e307d15 HCSR04.cpp
--- 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;