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)
Revision 0:4fbf332e6759, committed 2015-12-21
- 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