Synchronous and asynchronous library for ultrasonic distance measurement for the device HC-SR04 with error handling functionality (out of range detection, HW error detection). Main features: "echo" puls duration measurement, distance measurement from "echo" pulse duration, detection of "echo" signal malfunction, timeout detection, detection of measured values outside reliable limits (min, max)

Dependents:   TEST_Dist_lib

Files at this revision

API Documentation at this revision

Comitter:
dzoni
Date:
Mon Dec 21 21:01:53 2015 +0000
Child:
1:a2bf338e3698
Commit message:
Functionality completed and tested.

Changed in this revision

Distance_HC_SR04.cpp Show annotated file Show diff for this revision Revisions of this file
Distance_HC_SR04.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 4fbf332e6759 Distance_HC_SR04.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Distance_HC_SR04.cpp	Mon Dec 21 21:01:53 2015 +0000
@@ -0,0 +1,181 @@
+#include "Distance_HC_SR04.h"
+
+
+    /** Create Distance_HC_SR04 instance
+     */
+    Distance_HC_SR04::Distance_HC_SR04(PinName trig, PinName echo, uint32_t tout_us, float coeff,
+            uint32_t tmin_us, uint32_t tmax_us) :
+            _trig(trig), _echo(echo), _tout_us(tout_us), _coeff(coeff), _tmin_us(tmin_us), _tmax_us(tmax_us) {
+        _trig = 0;
+        _state = IDLE;
+    }
+
+    /** Start the measurement.
+     *
+     */
+    void Distance_HC_SR04::trigger(void) {
+        if (_state == IDLE && _echo == 0) {
+            _timeout.detach();
+            _echo.rise(NULL);
+            _echo.fall(NULL);
+            _timer.stop();
+            _timer.reset();
+
+            _trig = 1;
+            wait_us(TRIG_PULSE_US);
+            _trig = 0;
+
+            if (_echo == 0) {
+                _state = STARTED;
+                _timeout.attach_us(this, &Distance_HC_SR04::_tout, TIMEOUT_DELAY_US);
+
+                _echo.rise(this, &Distance_HC_SR04::_rising);
+                _echo.fall(this, &Distance_HC_SR04::_falling);
+
+                return;
+            }
+        }
+
+        if (_state == IDLE) {
+            _state = ERROR_SIG;
+            _ticks_us = 0;
+        }
+
+        return;
+    }
+
+    /** Returns a state measurement FSM is currently in.
+     *
+     */
+    Distance_HC_SR04_state Distance_HC_SR04::getState(void) {
+        return _state;
+    }
+
+    /** Resets whole device and prepares for triggering next measurement. FSM set to IDLE state.
+     *
+     */
+    void Distance_HC_SR04::reset(void) {
+        _state = IDLE;
+        _echo.rise(NULL);
+        _echo.fall(NULL);
+        _timeout.detach();
+        _timer.stop();
+        _timer.reset();
+    }
+
+    /** Returnes duration of "echo" pulse (microseconds) in case thate state is "COMPLETED".
+     *
+     */
+    uint32_t Distance_HC_SR04::getTicks(void) {
+        return _ticks_us;
+    }
+
+    /** Returns a distance of the obstacle in milimeters calculated from duration of "echo" pulse.
+     *
+     */
+    float Distance_HC_SR04::getDistance(void) {
+        return _ticks_us*_coeff;
+    }
+
+    /** Return actual value of coefficient used to calculate distance from "echo" pulse duration.
+     *
+     */
+    float Distance_HC_SR04::getCoeff(void) {
+        return _coeff;
+    }
+
+    /** Set the actual value of coefficient used to calculate distance from "echo" pulse duration.
+      *
+      * @param coeff Coeficient for multiplication with pulse duration in microseconds
+      * @returns
+      *   void
+      */    
+    void Distance_HC_SR04::setCoeff(float coeff) {
+        _coeff = coeff;
+    }
+
+    /** Measure and return the distance.
+      *
+      * @param void -
+      * @returns
+      *   float value of distance > 0.0f in case of a success,
+      *   0.0f in case of an error
+      */    
+    float Distance_HC_SR04::measureDistance(void) {
+        return measureTicks()*_coeff;
+    }
+
+    /** Measure and return "echo" pulse duration.
+      *
+      * @param void -
+      * @returns
+      *   uint32_t value of distance > 0 in case of a success,
+      *   0 in case of an error
+      */    
+    uint32_t Distance_HC_SR04::measureTicks(void) {
+        reset();
+        trigger();
+
+        while (_state == STARTED)
+            ;
+
+        _echo.rise(NULL);
+        _echo.fall(NULL);
+        _timeout.detach();
+
+        switch (_state) {
+            case COMPLETED:
+                break;
+            default:
+                _ticks_us = 0;
+                break;
+        }
+
+        return _ticks_us;
+    }
+
+    /** Timeout callback function.
+      *
+      * @param void -
+      * @returns
+      *   void -
+      */    
+    void Distance_HC_SR04::_tout(void) {
+        if (_state == STARTED)
+            _state = TIMEOUT;
+    }
+
+    /** Rising edge callback function.
+      *
+      * @param void -
+      * @returns
+      *   void -
+      */    
+    void Distance_HC_SR04::_rising(void) {
+        if (_state == STARTED) {
+            _timer.start();
+        }
+    }
+
+    /** Falling edge callback function.
+      *
+      * @param void -
+      * @returns
+      *   void -
+      */    
+    void Distance_HC_SR04::_falling(void) {
+        if (_state == STARTED) {
+            _timer.stop();
+            _ticks_us = _timer.read_us();
+
+            if (_ticks_us < _tmin_us) {
+                _ticks_us = 0;
+                _state = OUT_OF_RANGE_MIN;
+            } else if (_ticks_us > _tmax_us) {
+                _ticks_us = 0;
+                _state = OUT_OF_RANGE_MAX;
+            } else {
+                _state = COMPLETED;
+            }
+        }
+    }
diff -r 000000000000 -r 4fbf332e6759 Distance_HC_SR04.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Distance_HC_SR04.h	Mon Dec 21 21:01:53 2015 +0000
@@ -0,0 +1,54 @@
+#ifndef MBED_DISTANCE_HC_SR04_H
+#define MBED_DISTANCE_HC_SR04_H
+ 
+#include "mbed.h"
+ 
+#define TIMEOUT_DELAY_US    (25000)
+#define CALC_COEFF          (340.0f/(2.0f*1000.0f))
+#define TICKS_RANGE_MAX     (15000)
+#define TICKS_RANGE_MIN     (150)
+#define TRIG_PULSE_US       (50)
+
+typedef enum { IDLE, STARTED, COMPLETED, TIMEOUT, OUT_OF_RANGE_MIN, OUT_OF_RANGE_MAX, ERROR_SIG } Distance_HC_SR04_state;
+
+/** Distance_HC_SR04 class.
+ *
+ *  Library for interfacing ultrasonic distance measurement device HC-SR04.
+ *  Functionality includes detection of error in echo signal, detection of timeout and limits of reliable measurement.
+ *
+ */
+class Distance_HC_SR04 {
+
+public:
+    Distance_HC_SR04(PinName trig, PinName echo, uint32_t tout_us = TIMEOUT_DELAY_US, float coeff = CALC_COEFF,
+            uint32_t tmin_us = TICKS_RANGE_MIN, uint32_t tmax_us = TICKS_RANGE_MAX);
+    void trigger(void);
+    Distance_HC_SR04_state getState(void);
+    void reset(void);
+    uint32_t getTicks(void);
+    float getDistance(void);
+    float getCoeff(void);
+    void setCoeff(float coeff);
+    float measureDistance(void);
+    uint32_t measureTicks(void);
+
+    void _tout(void);
+    void _rising(void);
+    void _falling(void);
+
+private:
+    DigitalOut  _trig;
+    InterruptIn _echo;
+    uint32_t    _tout_us;
+    float       _coeff;
+    uint32_t    _tmin_us;
+    uint32_t    _tmax_us;
+
+    Timer       _timer;
+    Timeout     _timeout;
+
+    volatile Distance_HC_SR04_state _state;
+    uint32_t                        _ticks_us;
+};
+ 
+#endif
\ No newline at end of file