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

Dependencies:   TextLCD_improved mbed Distance_HC_SR04

Committer:
dzoni
Date:
Sun Dec 20 22:29:18 2015 +0000
Branch:
CLASS_IMPLEMENTATION
Revision:
4:bb5819be6ac3
Parent:
3:cb5931861f4e
Child:
5:1a69f40177b0
Class implemented. Basic function and failure states tested. Further testing and optimization required.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dzoni 0:6fd0fbcfc7e1 1 /*
dzoni 4:bb5819be6ac3 2 * MAIN.CPP
dzoni 0:6fd0fbcfc7e1 3 */
dzoni 0:6fd0fbcfc7e1 4 #include "mbed.h"
dzoni 0:6fd0fbcfc7e1 5
dzoni 0:6fd0fbcfc7e1 6 #include "TextLCD.h"
dzoni 0:6fd0fbcfc7e1 7
dzoni 0:6fd0fbcfc7e1 8 #define TIMEOUT_DELAY_US (25000)
dzoni 4:bb5819be6ac3 9 #define CALC_COEFF (340.0f/(2.0f*1000.0f))
dzoni 0:6fd0fbcfc7e1 10 #define TICKS_RANGE_MAX (15000)
dzoni 0:6fd0fbcfc7e1 11 #define TICKS_RANGE_MIN (150)
dzoni 3:cb5931861f4e 12 #define TRIG_PULSE_US (50)
dzoni 2:aba8d0d53190 13
dzoni 2:aba8d0d53190 14
dzoni 2:aba8d0d53190 15 typedef enum { IDLE, STARTED, COMPLETED, TIMEOUT, OUT_OF_RANGE_MIN, OUT_OF_RANGE_MAX, ERROR_SIG } Distance_HC_SR04_state;
dzoni 2:aba8d0d53190 16
dzoni 0:6fd0fbcfc7e1 17
dzoni 0:6fd0fbcfc7e1 18 TextLCD lcd(PA_8, PA_7, PA_9, PA_1, PB_5, PA_10, TextLCD::LCD16x2);
dzoni 0:6fd0fbcfc7e1 19
dzoni 2:aba8d0d53190 20 class Distance_HC_SR04 {
dzoni 2:aba8d0d53190 21 public:
dzoni 4:bb5819be6ac3 22 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) : _trig(trig), _echo(echo), _tout_us(tout_us), _coeff(coeff), _tmin_us(tmin_us), _tmax_us(tmax_us) {
dzoni 2:aba8d0d53190 23 _trig = 0;
dzoni 2:aba8d0d53190 24 _state = IDLE;
dzoni 2:aba8d0d53190 25 }
dzoni 2:aba8d0d53190 26
dzoni 2:aba8d0d53190 27 void trigger(void) {
dzoni 2:aba8d0d53190 28 if (_state == IDLE && _echo == 0) {
dzoni 2:aba8d0d53190 29 _timeout.detach();
dzoni 3:cb5931861f4e 30 _echo.rise(NULL);
dzoni 3:cb5931861f4e 31 _echo.fall(NULL);
dzoni 2:aba8d0d53190 32 _timer.stop();
dzoni 2:aba8d0d53190 33 _timer.reset();
dzoni 2:aba8d0d53190 34
dzoni 2:aba8d0d53190 35 _trig = 1;
dzoni 2:aba8d0d53190 36 wait_us(TRIG_PULSE_US);
dzoni 2:aba8d0d53190 37 _trig = 0;
dzoni 2:aba8d0d53190 38
dzoni 2:aba8d0d53190 39 if (_echo == 0) {
dzoni 2:aba8d0d53190 40 _state = STARTED;
dzoni 4:bb5819be6ac3 41 _timeout.attach_us(this, &Distance_HC_SR04::_tout, TIMEOUT_DELAY_US);
dzoni 2:aba8d0d53190 42
dzoni 2:aba8d0d53190 43 _echo.rise(this, &Distance_HC_SR04::_rising);
dzoni 2:aba8d0d53190 44 _echo.fall(this, &Distance_HC_SR04::_falling);
dzoni 2:aba8d0d53190 45
dzoni 2:aba8d0d53190 46 return;
dzoni 2:aba8d0d53190 47 }
dzoni 2:aba8d0d53190 48 }
dzoni 2:aba8d0d53190 49
dzoni 2:aba8d0d53190 50 if (_state == IDLE) {
dzoni 2:aba8d0d53190 51 _state = ERROR_SIG;
dzoni 2:aba8d0d53190 52 _ticks_us = 0;
dzoni 2:aba8d0d53190 53 }
dzoni 2:aba8d0d53190 54
dzoni 2:aba8d0d53190 55 return;
dzoni 2:aba8d0d53190 56 }
dzoni 2:aba8d0d53190 57
dzoni 2:aba8d0d53190 58 Distance_HC_SR04_state getState(void) {
dzoni 2:aba8d0d53190 59 return _state;
dzoni 2:aba8d0d53190 60 }
dzoni 2:aba8d0d53190 61
dzoni 2:aba8d0d53190 62 void reset(void) {
dzoni 2:aba8d0d53190 63 _state = IDLE;
dzoni 2:aba8d0d53190 64 _echo.rise(NULL);
dzoni 2:aba8d0d53190 65 _echo.fall(NULL);
dzoni 2:aba8d0d53190 66 _timeout.detach();
dzoni 2:aba8d0d53190 67 _timer.stop();
dzoni 2:aba8d0d53190 68 _timer.reset();
dzoni 2:aba8d0d53190 69 }
dzoni 2:aba8d0d53190 70
dzoni 2:aba8d0d53190 71 uint32_t getTicks(void) {
dzoni 2:aba8d0d53190 72 return _ticks_us;
dzoni 2:aba8d0d53190 73 }
dzoni 2:aba8d0d53190 74
dzoni 2:aba8d0d53190 75 float getDistance(void) {
dzoni 4:bb5819be6ac3 76 return _ticks_us*_coeff;
dzoni 2:aba8d0d53190 77 }
dzoni 2:aba8d0d53190 78
dzoni 2:aba8d0d53190 79 float getCoeff(void) {
dzoni 2:aba8d0d53190 80 return _coeff;
dzoni 2:aba8d0d53190 81 }
dzoni 2:aba8d0d53190 82
dzoni 2:aba8d0d53190 83 void setCoeff(float coeff) {
dzoni 2:aba8d0d53190 84 _coeff = coeff;
dzoni 2:aba8d0d53190 85 }
dzoni 2:aba8d0d53190 86
dzoni 2:aba8d0d53190 87 float measureDistance(void) {
dzoni 4:bb5819be6ac3 88 return measureTicks()*_coeff;
dzoni 2:aba8d0d53190 89 }
dzoni 2:aba8d0d53190 90
dzoni 2:aba8d0d53190 91 uint32_t measureTicks(void) {
dzoni 2:aba8d0d53190 92 reset();
dzoni 2:aba8d0d53190 93 trigger();
dzoni 2:aba8d0d53190 94
dzoni 2:aba8d0d53190 95 while (_state == STARTED)
dzoni 2:aba8d0d53190 96 ;
dzoni 2:aba8d0d53190 97
dzoni 3:cb5931861f4e 98 _echo.rise(NULL);
dzoni 3:cb5931861f4e 99 _echo.fall(NULL);
dzoni 3:cb5931861f4e 100 _timeout.detach();
dzoni 3:cb5931861f4e 101
dzoni 2:aba8d0d53190 102 switch (_state) {
dzoni 2:aba8d0d53190 103 case COMPLETED:
dzoni 2:aba8d0d53190 104 break;
dzoni 2:aba8d0d53190 105 default:
dzoni 3:cb5931861f4e 106 _ticks_us = 0;
dzoni 2:aba8d0d53190 107 break;
dzoni 2:aba8d0d53190 108 }
dzoni 2:aba8d0d53190 109
dzoni 2:aba8d0d53190 110 return _ticks_us;
dzoni 2:aba8d0d53190 111 }
dzoni 2:aba8d0d53190 112
dzoni 2:aba8d0d53190 113
dzoni 2:aba8d0d53190 114
dzoni 2:aba8d0d53190 115 void _tout(void) {
dzoni 2:aba8d0d53190 116 if (_state == STARTED)
dzoni 2:aba8d0d53190 117 _state = TIMEOUT;
dzoni 2:aba8d0d53190 118 }
dzoni 2:aba8d0d53190 119
dzoni 2:aba8d0d53190 120 void _rising(void) {
dzoni 2:aba8d0d53190 121 if (_state == STARTED) {
dzoni 2:aba8d0d53190 122 _timer.start();
dzoni 2:aba8d0d53190 123 }
dzoni 2:aba8d0d53190 124 }
dzoni 2:aba8d0d53190 125
dzoni 2:aba8d0d53190 126 void _falling(void) {
dzoni 2:aba8d0d53190 127 if (_state == STARTED) {
dzoni 2:aba8d0d53190 128 _timer.stop();
dzoni 2:aba8d0d53190 129 _ticks_us = _timer.read_us();
dzoni 4:bb5819be6ac3 130
dzoni 4:bb5819be6ac3 131 if (_ticks_us < _tmin_us) {
dzoni 4:bb5819be6ac3 132 _ticks_us = 0;
dzoni 4:bb5819be6ac3 133 _state = OUT_OF_RANGE_MIN;
dzoni 4:bb5819be6ac3 134 } else if (_ticks_us > _tmax_us) {
dzoni 4:bb5819be6ac3 135 _ticks_us = 0;
dzoni 4:bb5819be6ac3 136 _state = OUT_OF_RANGE_MAX;
dzoni 4:bb5819be6ac3 137 } else {
dzoni 4:bb5819be6ac3 138 _state = COMPLETED;
dzoni 4:bb5819be6ac3 139 }
dzoni 2:aba8d0d53190 140 }
dzoni 2:aba8d0d53190 141 }
dzoni 2:aba8d0d53190 142
dzoni 2:aba8d0d53190 143 private:
dzoni 2:aba8d0d53190 144 DigitalOut _trig;
dzoni 2:aba8d0d53190 145 InterruptIn _echo;
dzoni 2:aba8d0d53190 146 uint32_t _tout_us;
dzoni 4:bb5819be6ac3 147 uint32_t _tmin_us;
dzoni 4:bb5819be6ac3 148 uint32_t _tmax_us;
dzoni 2:aba8d0d53190 149 float _coeff;
dzoni 2:aba8d0d53190 150
dzoni 2:aba8d0d53190 151 Timer _timer;
dzoni 2:aba8d0d53190 152 Timeout _timeout;
dzoni 2:aba8d0d53190 153
dzoni 2:aba8d0d53190 154 volatile Distance_HC_SR04_state _state;
dzoni 4:bb5819be6ac3 155 uint32_t _ticks_us;
dzoni 2:aba8d0d53190 156 };
dzoni 2:aba8d0d53190 157
dzoni 2:aba8d0d53190 158
dzoni 2:aba8d0d53190 159
dzoni 0:6fd0fbcfc7e1 160 int main() {
dzoni 0:6fd0fbcfc7e1 161
dzoni 0:6fd0fbcfc7e1 162 wait_ms(250);
dzoni 0:6fd0fbcfc7e1 163 lcd.cls();
dzoni 0:6fd0fbcfc7e1 164
dzoni 0:6fd0fbcfc7e1 165 lcd.cls();
dzoni 0:6fd0fbcfc7e1 166 lcd.printf("Row 1");
dzoni 0:6fd0fbcfc7e1 167 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 168 lcd.printf("Row 2");
dzoni 0:6fd0fbcfc7e1 169
dzoni 4:bb5819be6ac3 170 Distance_HC_SR04 distFront(PB_9, PA_6);
dzoni 4:bb5819be6ac3 171 uint32_t ticks_us;
dzoni 4:bb5819be6ac3 172 float distance;
dzoni 0:6fd0fbcfc7e1 173
dzoni 4:bb5819be6ac3 174 while (true) {
dzoni 4:bb5819be6ac3 175 ticks_us = distFront.measureTicks();
dzoni 4:bb5819be6ac3 176 distance = distFront.getDistance();
dzoni 4:bb5819be6ac3 177
dzoni 4:bb5819be6ac3 178 lcd.cls();
dzoni 0:6fd0fbcfc7e1 179
dzoni 4:bb5819be6ac3 180 switch (distFront.getState()) {
dzoni 4:bb5819be6ac3 181 case COMPLETED:
dzoni 4:bb5819be6ac3 182 lcd.printf("Dist.: %u", ticks_us);
dzoni 4:bb5819be6ac3 183 lcd.locate(0, 1);
dzoni 4:bb5819be6ac3 184 lcd.printf("Dist.: %.3f", distance);
dzoni 0:6fd0fbcfc7e1 185
dzoni 4:bb5819be6ac3 186 break;
dzoni 4:bb5819be6ac3 187
dzoni 4:bb5819be6ac3 188 case TIMEOUT:
dzoni 4:bb5819be6ac3 189 lcd.printf("Dist.: ---");
dzoni 0:6fd0fbcfc7e1 190 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 191 lcd.printf("TIMEOUT");
dzoni 4:bb5819be6ac3 192
dzoni 4:bb5819be6ac3 193 break;
dzoni 4:bb5819be6ac3 194
dzoni 4:bb5819be6ac3 195 case ERROR_SIG:
dzoni 4:bb5819be6ac3 196 lcd.printf("Dist.: ---");
dzoni 4:bb5819be6ac3 197 lcd.locate(0, 1);
dzoni 4:bb5819be6ac3 198 lcd.printf("ERROR_SIG");
dzoni 4:bb5819be6ac3 199
dzoni 4:bb5819be6ac3 200 break;
dzoni 4:bb5819be6ac3 201
dzoni 4:bb5819be6ac3 202 case OUT_OF_RANGE_MIN:
dzoni 4:bb5819be6ac3 203 lcd.printf("Dist.: ---");
dzoni 4:bb5819be6ac3 204 lcd.locate(0, 1);
dzoni 4:bb5819be6ac3 205 lcd.printf("OUT_OF_RANGE_MIN");
dzoni 4:bb5819be6ac3 206
dzoni 4:bb5819be6ac3 207 break;
dzoni 4:bb5819be6ac3 208
dzoni 4:bb5819be6ac3 209 case OUT_OF_RANGE_MAX:
dzoni 4:bb5819be6ac3 210 lcd.printf("Dist.: ---");
dzoni 4:bb5819be6ac3 211 lcd.locate(0, 1);
dzoni 4:bb5819be6ac3 212 lcd.printf("OUT_OF_RANGE_MAX");
dzoni 4:bb5819be6ac3 213
dzoni 4:bb5819be6ac3 214 break;
dzoni 4:bb5819be6ac3 215
dzoni 4:bb5819be6ac3 216 default:
dzoni 4:bb5819be6ac3 217 lcd.printf("Dist.: ---");
dzoni 4:bb5819be6ac3 218 lcd.locate(0, 1);
dzoni 4:bb5819be6ac3 219 lcd.printf("OTHER");
dzoni 4:bb5819be6ac3 220
dzoni 4:bb5819be6ac3 221 break;
dzoni 0:6fd0fbcfc7e1 222 }
dzoni 0:6fd0fbcfc7e1 223
dzoni 0:6fd0fbcfc7e1 224 wait_ms(100);
dzoni 0:6fd0fbcfc7e1 225 }
dzoni 0:6fd0fbcfc7e1 226 }