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

Committer:
dzoni
Date:
Mon Dec 21 21:01:53 2015 +0000
Revision:
0:4fbf332e6759
Child:
1:a2bf338e3698
Functionality completed and tested.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dzoni 0:4fbf332e6759 1 #include "Distance_HC_SR04.h"
dzoni 0:4fbf332e6759 2
dzoni 0:4fbf332e6759 3
dzoni 0:4fbf332e6759 4 /** Create Distance_HC_SR04 instance
dzoni 0:4fbf332e6759 5 */
dzoni 0:4fbf332e6759 6 Distance_HC_SR04::Distance_HC_SR04(PinName trig, PinName echo, uint32_t tout_us, float coeff,
dzoni 0:4fbf332e6759 7 uint32_t tmin_us, uint32_t tmax_us) :
dzoni 0:4fbf332e6759 8 _trig(trig), _echo(echo), _tout_us(tout_us), _coeff(coeff), _tmin_us(tmin_us), _tmax_us(tmax_us) {
dzoni 0:4fbf332e6759 9 _trig = 0;
dzoni 0:4fbf332e6759 10 _state = IDLE;
dzoni 0:4fbf332e6759 11 }
dzoni 0:4fbf332e6759 12
dzoni 0:4fbf332e6759 13 /** Start the measurement.
dzoni 0:4fbf332e6759 14 *
dzoni 0:4fbf332e6759 15 */
dzoni 0:4fbf332e6759 16 void Distance_HC_SR04::trigger(void) {
dzoni 0:4fbf332e6759 17 if (_state == IDLE && _echo == 0) {
dzoni 0:4fbf332e6759 18 _timeout.detach();
dzoni 0:4fbf332e6759 19 _echo.rise(NULL);
dzoni 0:4fbf332e6759 20 _echo.fall(NULL);
dzoni 0:4fbf332e6759 21 _timer.stop();
dzoni 0:4fbf332e6759 22 _timer.reset();
dzoni 0:4fbf332e6759 23
dzoni 0:4fbf332e6759 24 _trig = 1;
dzoni 0:4fbf332e6759 25 wait_us(TRIG_PULSE_US);
dzoni 0:4fbf332e6759 26 _trig = 0;
dzoni 0:4fbf332e6759 27
dzoni 0:4fbf332e6759 28 if (_echo == 0) {
dzoni 0:4fbf332e6759 29 _state = STARTED;
dzoni 0:4fbf332e6759 30 _timeout.attach_us(this, &Distance_HC_SR04::_tout, TIMEOUT_DELAY_US);
dzoni 0:4fbf332e6759 31
dzoni 0:4fbf332e6759 32 _echo.rise(this, &Distance_HC_SR04::_rising);
dzoni 0:4fbf332e6759 33 _echo.fall(this, &Distance_HC_SR04::_falling);
dzoni 0:4fbf332e6759 34
dzoni 0:4fbf332e6759 35 return;
dzoni 0:4fbf332e6759 36 }
dzoni 0:4fbf332e6759 37 }
dzoni 0:4fbf332e6759 38
dzoni 0:4fbf332e6759 39 if (_state == IDLE) {
dzoni 0:4fbf332e6759 40 _state = ERROR_SIG;
dzoni 0:4fbf332e6759 41 _ticks_us = 0;
dzoni 0:4fbf332e6759 42 }
dzoni 0:4fbf332e6759 43
dzoni 0:4fbf332e6759 44 return;
dzoni 0:4fbf332e6759 45 }
dzoni 0:4fbf332e6759 46
dzoni 0:4fbf332e6759 47 /** Returns a state measurement FSM is currently in.
dzoni 0:4fbf332e6759 48 *
dzoni 0:4fbf332e6759 49 */
dzoni 0:4fbf332e6759 50 Distance_HC_SR04_state Distance_HC_SR04::getState(void) {
dzoni 0:4fbf332e6759 51 return _state;
dzoni 0:4fbf332e6759 52 }
dzoni 0:4fbf332e6759 53
dzoni 0:4fbf332e6759 54 /** Resets whole device and prepares for triggering next measurement. FSM set to IDLE state.
dzoni 0:4fbf332e6759 55 *
dzoni 0:4fbf332e6759 56 */
dzoni 0:4fbf332e6759 57 void Distance_HC_SR04::reset(void) {
dzoni 0:4fbf332e6759 58 _state = IDLE;
dzoni 0:4fbf332e6759 59 _echo.rise(NULL);
dzoni 0:4fbf332e6759 60 _echo.fall(NULL);
dzoni 0:4fbf332e6759 61 _timeout.detach();
dzoni 0:4fbf332e6759 62 _timer.stop();
dzoni 0:4fbf332e6759 63 _timer.reset();
dzoni 0:4fbf332e6759 64 }
dzoni 0:4fbf332e6759 65
dzoni 0:4fbf332e6759 66 /** Returnes duration of "echo" pulse (microseconds) in case thate state is "COMPLETED".
dzoni 0:4fbf332e6759 67 *
dzoni 0:4fbf332e6759 68 */
dzoni 0:4fbf332e6759 69 uint32_t Distance_HC_SR04::getTicks(void) {
dzoni 0:4fbf332e6759 70 return _ticks_us;
dzoni 0:4fbf332e6759 71 }
dzoni 0:4fbf332e6759 72
dzoni 0:4fbf332e6759 73 /** Returns a distance of the obstacle in milimeters calculated from duration of "echo" pulse.
dzoni 0:4fbf332e6759 74 *
dzoni 0:4fbf332e6759 75 */
dzoni 0:4fbf332e6759 76 float Distance_HC_SR04::getDistance(void) {
dzoni 0:4fbf332e6759 77 return _ticks_us*_coeff;
dzoni 0:4fbf332e6759 78 }
dzoni 0:4fbf332e6759 79
dzoni 0:4fbf332e6759 80 /** Return actual value of coefficient used to calculate distance from "echo" pulse duration.
dzoni 0:4fbf332e6759 81 *
dzoni 0:4fbf332e6759 82 */
dzoni 0:4fbf332e6759 83 float Distance_HC_SR04::getCoeff(void) {
dzoni 0:4fbf332e6759 84 return _coeff;
dzoni 0:4fbf332e6759 85 }
dzoni 0:4fbf332e6759 86
dzoni 0:4fbf332e6759 87 /** Set the actual value of coefficient used to calculate distance from "echo" pulse duration.
dzoni 0:4fbf332e6759 88 *
dzoni 0:4fbf332e6759 89 * @param coeff Coeficient for multiplication with pulse duration in microseconds
dzoni 0:4fbf332e6759 90 * @returns
dzoni 0:4fbf332e6759 91 * void
dzoni 0:4fbf332e6759 92 */
dzoni 0:4fbf332e6759 93 void Distance_HC_SR04::setCoeff(float coeff) {
dzoni 0:4fbf332e6759 94 _coeff = coeff;
dzoni 0:4fbf332e6759 95 }
dzoni 0:4fbf332e6759 96
dzoni 0:4fbf332e6759 97 /** Measure and return the distance.
dzoni 0:4fbf332e6759 98 *
dzoni 0:4fbf332e6759 99 * @param void -
dzoni 0:4fbf332e6759 100 * @returns
dzoni 0:4fbf332e6759 101 * float value of distance > 0.0f in case of a success,
dzoni 0:4fbf332e6759 102 * 0.0f in case of an error
dzoni 0:4fbf332e6759 103 */
dzoni 0:4fbf332e6759 104 float Distance_HC_SR04::measureDistance(void) {
dzoni 0:4fbf332e6759 105 return measureTicks()*_coeff;
dzoni 0:4fbf332e6759 106 }
dzoni 0:4fbf332e6759 107
dzoni 0:4fbf332e6759 108 /** Measure and return "echo" pulse duration.
dzoni 0:4fbf332e6759 109 *
dzoni 0:4fbf332e6759 110 * @param void -
dzoni 0:4fbf332e6759 111 * @returns
dzoni 0:4fbf332e6759 112 * uint32_t value of distance > 0 in case of a success,
dzoni 0:4fbf332e6759 113 * 0 in case of an error
dzoni 0:4fbf332e6759 114 */
dzoni 0:4fbf332e6759 115 uint32_t Distance_HC_SR04::measureTicks(void) {
dzoni 0:4fbf332e6759 116 reset();
dzoni 0:4fbf332e6759 117 trigger();
dzoni 0:4fbf332e6759 118
dzoni 0:4fbf332e6759 119 while (_state == STARTED)
dzoni 0:4fbf332e6759 120 ;
dzoni 0:4fbf332e6759 121
dzoni 0:4fbf332e6759 122 _echo.rise(NULL);
dzoni 0:4fbf332e6759 123 _echo.fall(NULL);
dzoni 0:4fbf332e6759 124 _timeout.detach();
dzoni 0:4fbf332e6759 125
dzoni 0:4fbf332e6759 126 switch (_state) {
dzoni 0:4fbf332e6759 127 case COMPLETED:
dzoni 0:4fbf332e6759 128 break;
dzoni 0:4fbf332e6759 129 default:
dzoni 0:4fbf332e6759 130 _ticks_us = 0;
dzoni 0:4fbf332e6759 131 break;
dzoni 0:4fbf332e6759 132 }
dzoni 0:4fbf332e6759 133
dzoni 0:4fbf332e6759 134 return _ticks_us;
dzoni 0:4fbf332e6759 135 }
dzoni 0:4fbf332e6759 136
dzoni 0:4fbf332e6759 137 /** Timeout callback function.
dzoni 0:4fbf332e6759 138 *
dzoni 0:4fbf332e6759 139 * @param void -
dzoni 0:4fbf332e6759 140 * @returns
dzoni 0:4fbf332e6759 141 * void -
dzoni 0:4fbf332e6759 142 */
dzoni 0:4fbf332e6759 143 void Distance_HC_SR04::_tout(void) {
dzoni 0:4fbf332e6759 144 if (_state == STARTED)
dzoni 0:4fbf332e6759 145 _state = TIMEOUT;
dzoni 0:4fbf332e6759 146 }
dzoni 0:4fbf332e6759 147
dzoni 0:4fbf332e6759 148 /** Rising edge callback function.
dzoni 0:4fbf332e6759 149 *
dzoni 0:4fbf332e6759 150 * @param void -
dzoni 0:4fbf332e6759 151 * @returns
dzoni 0:4fbf332e6759 152 * void -
dzoni 0:4fbf332e6759 153 */
dzoni 0:4fbf332e6759 154 void Distance_HC_SR04::_rising(void) {
dzoni 0:4fbf332e6759 155 if (_state == STARTED) {
dzoni 0:4fbf332e6759 156 _timer.start();
dzoni 0:4fbf332e6759 157 }
dzoni 0:4fbf332e6759 158 }
dzoni 0:4fbf332e6759 159
dzoni 0:4fbf332e6759 160 /** Falling edge callback function.
dzoni 0:4fbf332e6759 161 *
dzoni 0:4fbf332e6759 162 * @param void -
dzoni 0:4fbf332e6759 163 * @returns
dzoni 0:4fbf332e6759 164 * void -
dzoni 0:4fbf332e6759 165 */
dzoni 0:4fbf332e6759 166 void Distance_HC_SR04::_falling(void) {
dzoni 0:4fbf332e6759 167 if (_state == STARTED) {
dzoni 0:4fbf332e6759 168 _timer.stop();
dzoni 0:4fbf332e6759 169 _ticks_us = _timer.read_us();
dzoni 0:4fbf332e6759 170
dzoni 0:4fbf332e6759 171 if (_ticks_us < _tmin_us) {
dzoni 0:4fbf332e6759 172 _ticks_us = 0;
dzoni 0:4fbf332e6759 173 _state = OUT_OF_RANGE_MIN;
dzoni 0:4fbf332e6759 174 } else if (_ticks_us > _tmax_us) {
dzoni 0:4fbf332e6759 175 _ticks_us = 0;
dzoni 0:4fbf332e6759 176 _state = OUT_OF_RANGE_MAX;
dzoni 0:4fbf332e6759 177 } else {
dzoni 0:4fbf332e6759 178 _state = COMPLETED;
dzoni 0:4fbf332e6759 179 }
dzoni 0:4fbf332e6759 180 }
dzoni 0:4fbf332e6759 181 }