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:
Fri Apr 13 13:42:47 2018 +0000
Revision:
12:5bf5a7e62c5d
Parent:
6:5beda7c318d5
Documentation improvement (including code examples).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dzoni 12:5bf5a7e62c5d 1 /**
dzoni 12:5bf5a7e62c5d 2 * @file Distance_HC_SR04.h
dzoni 12:5bf5a7e62c5d 3 * @author Jan Tetour
dzoni 12:5bf5a7e62c5d 4 * @date 21. Dec 2015
dzoni 12:5bf5a7e62c5d 5 * @brief Library for distance measurement with device HC-SR04 and similar.
dzoni 12:5bf5a7e62c5d 6 *
dzoni 12:5bf5a7e62c5d 7 * 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)
dzoni 12:5bf5a7e62c5d 8 *
dzoni 12:5bf5a7e62c5d 9 * @see https://os.mbed.com/users/dzoni/code/Distance_HC_SR04/
dzoni 12:5bf5a7e62c5d 10 */
dzoni 0:4fbf332e6759 11 #ifndef MBED_DISTANCE_HC_SR04_H
dzoni 0:4fbf332e6759 12 #define MBED_DISTANCE_HC_SR04_H
dzoni 0:4fbf332e6759 13
dzoni 0:4fbf332e6759 14 #include "mbed.h"
dzoni 0:4fbf332e6759 15
dzoni 5:2f6992aad3a0 16 #define TIMEOUT_DELAY_US (25000) // Timeout in microseconds
dzoni 5:2f6992aad3a0 17 #define CALC_COEFF (340.0f/(2.0f*1000.0f)) // Coefficient for distance calculation (distance = coeff * microseconds)
dzoni 5:2f6992aad3a0 18 #define TICKS_RANGE_MAX (15000) // Maximum reliable measurement - echo pulse width in microseconds
dzoni 5:2f6992aad3a0 19 #define TICKS_RANGE_MIN (150) // Minimum reliable measurement - echo pulse width in microseconds
dzoni 5:2f6992aad3a0 20 #define TRIG_PULSE_US (50) // Width of trigger pulse in microseconds
dzoni 0:4fbf332e6759 21
dzoni 12:5bf5a7e62c5d 22 /**
dzoni 12:5bf5a7e62c5d 23 * @brief Definition of measurement FSM states.
dzoni 12:5bf5a7e62c5d 24 *
dzoni 12:5bf5a7e62c5d 25 * Measurement FSM (Finite State Machine) states definition.
dzoni 6:5beda7c318d5 26 *
dzoni 6:5beda7c318d5 27 */
dzoni 12:5bf5a7e62c5d 28 typedef enum {
dzoni 12:5bf5a7e62c5d 29 IDLE, /**< No activity. Ready to start measurement with trigger(). This is state after reset(). */
dzoni 12:5bf5a7e62c5d 30 STARTED, /**< Measurement started and in progress. This is state after trigger(). */
dzoni 12:5bf5a7e62c5d 31 COMPLETED, /**< Measurement succesfuly completed by falling edge of echo signal. Measured values in range. */
dzoni 12:5bf5a7e62c5d 32 TIMEOUT, /**< It was not possible to complete echo pulse width measurement in given time. Measurement cancelled. */
dzoni 12:5bf5a7e62c5d 33 OUT_OF_RANGE_MIN, /**< Measurement completed. Measured distance under reliable range. */
dzoni 12:5bf5a7e62c5d 34 OUT_OF_RANGE_MAX, /**< Measurement completed. Measured distance over reliable range. */
dzoni 12:5bf5a7e62c5d 35 ERROR_SIG /**< Faulty value of echo signal just after trigger pulse (echo != 0). Possible HW fault. */
dzoni 12:5bf5a7e62c5d 36 } Distance_HC_SR04_state;
dzoni 0:4fbf332e6759 37
dzoni 0:4fbf332e6759 38 /** Distance_HC_SR04 class.
dzoni 0:4fbf332e6759 39 *
dzoni 0:4fbf332e6759 40 * Library for interfacing ultrasonic distance measurement device HC-SR04.
dzoni 4:71f01fbc9246 41 * Works in 2 basic modes:
dzoni 6:5beda7c318d5 42 * - blocking (via measureTicks() or measureDistance())
dzoni 6:5beda7c318d5 43 * - non-blocking asynchronous (via reset() + trigger() + getState() + getTicks() or getDistance())
dzoni 4:71f01fbc9246 44 *
dzoni 0:4fbf332e6759 45 * Functionality includes detection of error in echo signal, detection of timeout and limits of reliable measurement.
dzoni 0:4fbf332e6759 46 *
dzoni 0:4fbf332e6759 47 */
dzoni 0:4fbf332e6759 48 class Distance_HC_SR04 {
dzoni 0:4fbf332e6759 49
dzoni 0:4fbf332e6759 50 public:
dzoni 0:4fbf332e6759 51 Distance_HC_SR04(PinName trig, PinName echo, uint32_t tout_us = TIMEOUT_DELAY_US, float coeff = CALC_COEFF,
dzoni 0:4fbf332e6759 52 uint32_t tmin_us = TICKS_RANGE_MIN, uint32_t tmax_us = TICKS_RANGE_MAX);
dzoni 0:4fbf332e6759 53 void trigger(void);
dzoni 0:4fbf332e6759 54 Distance_HC_SR04_state getState(void);
dzoni 0:4fbf332e6759 55 void reset(void);
dzoni 0:4fbf332e6759 56 uint32_t getTicks(void);
dzoni 0:4fbf332e6759 57 float getDistance(void);
dzoni 0:4fbf332e6759 58 float getCoeff(void);
dzoni 0:4fbf332e6759 59 void setCoeff(float coeff);
dzoni 12:5bf5a7e62c5d 60
dzoni 12:5bf5a7e62c5d 61 /**
dzoni 12:5bf5a7e62c5d 62 * @brief Measure (synchronous) distance of the object by reflected ultrasonic signal.
dzoni 12:5bf5a7e62c5d 63 *
dzoni 12:5bf5a7e62c5d 64 * Measure the distance from the object by reflected ultrasonic signal in synchronous
dzoni 12:5bf5a7e62c5d 65 * (blocking) mode. In case of any error, returns 0. Error information can be retrieved via getState() method.
dzoni 12:5bf5a7e62c5d 66 *
dzoni 12:5bf5a7e62c5d 67 * Example of usage:
dzoni 12:5bf5a7e62c5d 68 * @code
dzoni 12:5bf5a7e62c5d 69 * Distance_HC_SR04 dist(PIN_TRIG, PIN_ECHO);
dzoni 12:5bf5a7e62c5d 70 * float distance;
dzoni 12:5bf5a7e62c5d 71 *
dzoni 12:5bf5a7e62c5d 72 * while (true) {
dzoni 12:5bf5a7e62c5d 73 * distance = dist.getDistance();
dzoni 12:5bf5a7e62c5d 74 * lcd.cls();
dzoni 12:5bf5a7e62c5d 75 *
dzoni 12:5bf5a7e62c5d 76 * switch (dist.getState()) {
dzoni 12:5bf5a7e62c5d 77 * case COMPLETED:
dzoni 12:5bf5a7e62c5d 78 * lcd.printf("Dist.: %.3f", dist);
dzoni 12:5bf5a7e62c5d 79 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 80 * lcd.printf("COMPLETED");
dzoni 12:5bf5a7e62c5d 81 *
dzoni 12:5bf5a7e62c5d 82 * break;
dzoni 12:5bf5a7e62c5d 83
dzoni 12:5bf5a7e62c5d 84 * case TIMEOUT:
dzoni 12:5bf5a7e62c5d 85 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 86 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 87 * lcd.printf("TIMEOUR");
dzoni 12:5bf5a7e62c5d 88
dzoni 12:5bf5a7e62c5d 89 * break;
dzoni 12:5bf5a7e62c5d 90 * case ERROR_SIG:
dzoni 12:5bf5a7e62c5d 91 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 92 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 93 * lcd.printf("ERROR_SIG");
dzoni 12:5bf5a7e62c5d 94
dzoni 12:5bf5a7e62c5d 95 * break;
dzoni 12:5bf5a7e62c5d 96
dzoni 12:5bf5a7e62c5d 97 * case OUT_OF_RANGE_MIN:
dzoni 12:5bf5a7e62c5d 98 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 99 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 100 * lcd.printf("OUT_OF_RANGE_MIN");
dzoni 12:5bf5a7e62c5d 101
dzoni 12:5bf5a7e62c5d 102 * break;
dzoni 12:5bf5a7e62c5d 103
dzoni 12:5bf5a7e62c5d 104 * case OUT_OF_RANGE_MAX:
dzoni 12:5bf5a7e62c5d 105 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 106 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 107 * lcd.printf("OUT_OF_RANGE_MAX");
dzoni 12:5bf5a7e62c5d 108
dzoni 12:5bf5a7e62c5d 109 * break;
dzoni 12:5bf5a7e62c5d 110
dzoni 12:5bf5a7e62c5d 111 * default:
dzoni 12:5bf5a7e62c5d 112 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 113 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 114 * lcd.printf("OTHER");
dzoni 12:5bf5a7e62c5d 115
dzoni 12:5bf5a7e62c5d 116 * break;
dzoni 12:5bf5a7e62c5d 117 * }
dzoni 12:5bf5a7e62c5d 118 * wait_ms(100);
dzoni 12:5bf5a7e62c5d 119 * }
dzoni 12:5bf5a7e62c5d 120 * @endcode
dzoni 12:5bf5a7e62c5d 121 * @param -
dzoni 12:5bf5a7e62c5d 122 * @return Object distance in milimeters. 0 in case of error.
dzoni 12:5bf5a7e62c5d 123 * @see -
dzoni 12:5bf5a7e62c5d 124 * @note - Calculation can be influenced by changing _coeff via setCoeff() or Distance_HC_SR04().
dzoni 12:5bf5a7e62c5d 125 * @warning -
dzoni 12:5bf5a7e62c5d 126 */
dzoni 0:4fbf332e6759 127 float measureDistance(void);
dzoni 12:5bf5a7e62c5d 128
dzoni 12:5bf5a7e62c5d 129 /**
dzoni 12:5bf5a7e62c5d 130 * @brief Measure (synchronous) ultrasonic signal travel time.
dzoni 12:5bf5a7e62c5d 131 *
dzoni 12:5bf5a7e62c5d 132 * Measure the ultrasonic signal travel time in microseconds in synchronous
dzoni 12:5bf5a7e62c5d 133 * (blocking) mode. In case of any error, returns 0. Error information can be retrieved via getState() method.
dzoni 12:5bf5a7e62c5d 134 *
dzoni 12:5bf5a7e62c5d 135 * Example of usage:
dzoni 12:5bf5a7e62c5d 136 * @code
dzoni 12:5bf5a7e62c5d 137 * Distance_HC_SR04 dist(PIN_TRIG, PIN_ECHO);
dzoni 12:5bf5a7e62c5d 138 * uint32_t ticks_us;
dzoni 12:5bf5a7e62c5d 139 *
dzoni 12:5bf5a7e62c5d 140 * while (true) {
dzoni 12:5bf5a7e62c5d 141 * ticks_us = dist.measureTicks();
dzoni 12:5bf5a7e62c5d 142 * lcd.cls();
dzoni 12:5bf5a7e62c5d 143 *
dzoni 12:5bf5a7e62c5d 144 * switch (dist.getState()) {
dzoni 12:5bf5a7e62c5d 145 * case COMPLETED:
dzoni 12:5bf5a7e62c5d 146 * lcd.printf("Dist.: %u", ticks_us);
dzoni 12:5bf5a7e62c5d 147 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 148 * lcd.printf("COMPLETED");
dzoni 12:5bf5a7e62c5d 149 *
dzoni 12:5bf5a7e62c5d 150 * break;
dzoni 12:5bf5a7e62c5d 151
dzoni 12:5bf5a7e62c5d 152 * case TIMEOUT:
dzoni 12:5bf5a7e62c5d 153 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 154 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 155 * lcd.printf("TIMEOUR");
dzoni 12:5bf5a7e62c5d 156
dzoni 12:5bf5a7e62c5d 157 * break;
dzoni 12:5bf5a7e62c5d 158 * case ERROR_SIG:
dzoni 12:5bf5a7e62c5d 159 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 160 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 161 * lcd.printf("ERROR_SIG");
dzoni 12:5bf5a7e62c5d 162
dzoni 12:5bf5a7e62c5d 163 * break;
dzoni 12:5bf5a7e62c5d 164
dzoni 12:5bf5a7e62c5d 165 * case OUT_OF_RANGE_MIN:
dzoni 12:5bf5a7e62c5d 166 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 167 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 168 * lcd.printf("OUT_OF_RANGE_MIN");
dzoni 12:5bf5a7e62c5d 169
dzoni 12:5bf5a7e62c5d 170 * break;
dzoni 12:5bf5a7e62c5d 171
dzoni 12:5bf5a7e62c5d 172 * case OUT_OF_RANGE_MAX:
dzoni 12:5bf5a7e62c5d 173 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 174 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 175 * lcd.printf("OUT_OF_RANGE_MAX");
dzoni 12:5bf5a7e62c5d 176
dzoni 12:5bf5a7e62c5d 177 * break;
dzoni 12:5bf5a7e62c5d 178
dzoni 12:5bf5a7e62c5d 179 * default:
dzoni 12:5bf5a7e62c5d 180 * lcd.printf("Dist.: ---");
dzoni 12:5bf5a7e62c5d 181 * lcd.locate(0, 1);
dzoni 12:5bf5a7e62c5d 182 * lcd.printf("OTHER");
dzoni 12:5bf5a7e62c5d 183
dzoni 12:5bf5a7e62c5d 184 * break;
dzoni 12:5bf5a7e62c5d 185 * }
dzoni 12:5bf5a7e62c5d 186 * wait_ms(100);
dzoni 12:5bf5a7e62c5d 187 * }
dzoni 12:5bf5a7e62c5d 188 * @endcode
dzoni 12:5bf5a7e62c5d 189 * @param -
dzoni 12:5bf5a7e62c5d 190 * @return Ultrasonic signal total travel time (including reflected signal) in microseconds. 0 in case of error.
dzoni 12:5bf5a7e62c5d 191 * @see -
dzoni 12:5bf5a7e62c5d 192 * @note -
dzoni 12:5bf5a7e62c5d 193 * @warning -
dzoni 12:5bf5a7e62c5d 194 */
dzoni 12:5bf5a7e62c5d 195 uint32_t measureTicks(void);
dzoni 0:4fbf332e6759 196
dzoni 6:5beda7c318d5 197 private:
dzoni 0:4fbf332e6759 198 void _tout(void);
dzoni 0:4fbf332e6759 199 void _rising(void);
dzoni 0:4fbf332e6759 200 void _falling(void);
dzoni 0:4fbf332e6759 201
dzoni 0:4fbf332e6759 202 DigitalOut _trig;
dzoni 0:4fbf332e6759 203 InterruptIn _echo;
dzoni 0:4fbf332e6759 204 uint32_t _tout_us;
dzoni 0:4fbf332e6759 205 float _coeff;
dzoni 0:4fbf332e6759 206 uint32_t _tmin_us;
dzoni 0:4fbf332e6759 207 uint32_t _tmax_us;
dzoni 0:4fbf332e6759 208
dzoni 0:4fbf332e6759 209 Timer _timer;
dzoni 0:4fbf332e6759 210 Timeout _timeout;
dzoni 0:4fbf332e6759 211
dzoni 0:4fbf332e6759 212 volatile Distance_HC_SR04_state _state;
dzoni 0:4fbf332e6759 213 uint32_t _ticks_us;
dzoni 0:4fbf332e6759 214 };
dzoni 0:4fbf332e6759 215
dzoni 0:4fbf332e6759 216 #endif