Development and testing of ultrasonic distance measurement library for device HC-SR04.

Dependencies:   TextLCD_improved mbed Distance_HC_SR04

Committer:
dzoni
Date:
Mon Dec 21 20:54:09 2015 +0000
Branch:
CLASS_IMPLEMENTATION
Revision:
5:1a69f40177b0
Class implementation completed and successfully tested.

Who changed what in which revision?

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