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 21:37:27 2015 +0000
Branch:
CLASS_IMPLEMENTATION
Revision:
3:cb5931861f4e
Parent:
2:aba8d0d53190
Child:
4:bb5819be6ac3
Still in progress...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dzoni 0:6fd0fbcfc7e1 1 /*
dzoni 0:6fd0fbcfc7e1 2 * TSK_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 0:6fd0fbcfc7e1 9 #define CALC_COEFF (1000.0f*340.0f/2)
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 0:6fd0fbcfc7e1 20 static DigitalOut trigDist(PB_9);
dzoni 0:6fd0fbcfc7e1 21 static DigitalIn echoDist(PA_6);
dzoni 0:6fd0fbcfc7e1 22
dzoni 0:6fd0fbcfc7e1 23 static uint32_t timer_ticks;
dzoni 0:6fd0fbcfc7e1 24 static float time_float;
dzoni 0:6fd0fbcfc7e1 25 static uint32_t timer_ticks_min;
dzoni 0:6fd0fbcfc7e1 26
dzoni 0:6fd0fbcfc7e1 27 static Timer timer;
dzoni 0:6fd0fbcfc7e1 28
dzoni 0:6fd0fbcfc7e1 29 static Timeout timeout;
dzoni 0:6fd0fbcfc7e1 30
dzoni 2:aba8d0d53190 31 static volatile Distance_HC_SR04_state state;
dzoni 0:6fd0fbcfc7e1 32
dzoni 0:6fd0fbcfc7e1 33 void tout(void) {
dzoni 0:6fd0fbcfc7e1 34 if (state == STARTED)
dzoni 0:6fd0fbcfc7e1 35 state = TIMEOUT;
dzoni 0:6fd0fbcfc7e1 36 }
dzoni 0:6fd0fbcfc7e1 37
dzoni 2:aba8d0d53190 38
dzoni 2:aba8d0d53190 39 class Distance_HC_SR04 {
dzoni 2:aba8d0d53190 40 public:
dzoni 2:aba8d0d53190 41 Distance_HC_SR04(PinName trig, PinName echo, uint32_t tout_us = TIMEOUT_DELAY_US, float coeff = CALC_COEFF) : _trig(trig), _echo(echo), _tout_us(tout_us), _coeff(coeff) {
dzoni 2:aba8d0d53190 42 _trig = 0;
dzoni 2:aba8d0d53190 43 _state = IDLE;
dzoni 2:aba8d0d53190 44 }
dzoni 2:aba8d0d53190 45
dzoni 2:aba8d0d53190 46 void trigger(void) {
dzoni 2:aba8d0d53190 47 if (_state == IDLE && _echo == 0) {
dzoni 2:aba8d0d53190 48 _timeout.detach();
dzoni 3:cb5931861f4e 49 _echo.rise(NULL);
dzoni 3:cb5931861f4e 50 _echo.fall(NULL);
dzoni 2:aba8d0d53190 51 _timer.stop();
dzoni 2:aba8d0d53190 52 _timer.reset();
dzoni 2:aba8d0d53190 53
dzoni 2:aba8d0d53190 54 _trig = 1;
dzoni 2:aba8d0d53190 55 wait_us(TRIG_PULSE_US);
dzoni 2:aba8d0d53190 56 _trig = 0;
dzoni 2:aba8d0d53190 57
dzoni 2:aba8d0d53190 58 if (_echo == 0) {
dzoni 2:aba8d0d53190 59 _state = STARTED;
dzoni 2:aba8d0d53190 60 timeout.attach_us(this, &Distance_HC_SR04::_tout, TIMEOUT_DELAY_US);
dzoni 2:aba8d0d53190 61
dzoni 2:aba8d0d53190 62 _echo.rise(this, &Distance_HC_SR04::_rising);
dzoni 2:aba8d0d53190 63 _echo.fall(this, &Distance_HC_SR04::_falling);
dzoni 2:aba8d0d53190 64
dzoni 2:aba8d0d53190 65 return;
dzoni 2:aba8d0d53190 66 }
dzoni 2:aba8d0d53190 67 }
dzoni 2:aba8d0d53190 68
dzoni 2:aba8d0d53190 69 if (_state == IDLE) {
dzoni 2:aba8d0d53190 70 _state = ERROR_SIG;
dzoni 2:aba8d0d53190 71 _ticks_us = 0;
dzoni 2:aba8d0d53190 72 }
dzoni 2:aba8d0d53190 73
dzoni 2:aba8d0d53190 74 return;
dzoni 2:aba8d0d53190 75 }
dzoni 2:aba8d0d53190 76
dzoni 2:aba8d0d53190 77 Distance_HC_SR04_state getState(void) {
dzoni 2:aba8d0d53190 78 return _state;
dzoni 2:aba8d0d53190 79 }
dzoni 2:aba8d0d53190 80
dzoni 2:aba8d0d53190 81 void reset(void) {
dzoni 2:aba8d0d53190 82 _state = IDLE;
dzoni 2:aba8d0d53190 83 _echo.rise(NULL);
dzoni 2:aba8d0d53190 84 _echo.fall(NULL);
dzoni 2:aba8d0d53190 85 _timeout.detach();
dzoni 2:aba8d0d53190 86 _timer.stop();
dzoni 2:aba8d0d53190 87 _timer.reset();
dzoni 2:aba8d0d53190 88 }
dzoni 2:aba8d0d53190 89
dzoni 2:aba8d0d53190 90 uint32_t getTicks(void) {
dzoni 2:aba8d0d53190 91 return _ticks_us;
dzoni 2:aba8d0d53190 92 }
dzoni 2:aba8d0d53190 93
dzoni 2:aba8d0d53190 94 float getDistance(void) {
dzoni 2:aba8d0d53190 95 return _ticks_us/_coeff;
dzoni 2:aba8d0d53190 96 }
dzoni 2:aba8d0d53190 97
dzoni 2:aba8d0d53190 98 float getCoeff(void) {
dzoni 2:aba8d0d53190 99 return _coeff;
dzoni 2:aba8d0d53190 100 }
dzoni 2:aba8d0d53190 101
dzoni 2:aba8d0d53190 102 void setCoeff(float coeff) {
dzoni 2:aba8d0d53190 103 _coeff = coeff;
dzoni 2:aba8d0d53190 104 }
dzoni 2:aba8d0d53190 105
dzoni 2:aba8d0d53190 106 float measureDistance(void) {
dzoni 2:aba8d0d53190 107 return measureTicks()/_coeff;
dzoni 2:aba8d0d53190 108 }
dzoni 2:aba8d0d53190 109
dzoni 2:aba8d0d53190 110 uint32_t measureTicks(void) {
dzoni 2:aba8d0d53190 111 reset();
dzoni 2:aba8d0d53190 112 trigger();
dzoni 2:aba8d0d53190 113
dzoni 2:aba8d0d53190 114 while (_state == STARTED)
dzoni 2:aba8d0d53190 115 ;
dzoni 2:aba8d0d53190 116
dzoni 3:cb5931861f4e 117 _echo.rise(NULL);
dzoni 3:cb5931861f4e 118 _echo.fall(NULL);
dzoni 3:cb5931861f4e 119 _timeout.detach();
dzoni 3:cb5931861f4e 120
dzoni 2:aba8d0d53190 121 switch (_state) {
dzoni 2:aba8d0d53190 122 case COMPLETED:
dzoni 2:aba8d0d53190 123 break;
dzoni 2:aba8d0d53190 124 default:
dzoni 3:cb5931861f4e 125 _ticks_us = 0;
dzoni 2:aba8d0d53190 126 break;
dzoni 2:aba8d0d53190 127 }
dzoni 2:aba8d0d53190 128
dzoni 2:aba8d0d53190 129 return _ticks_us;
dzoni 2:aba8d0d53190 130 }
dzoni 2:aba8d0d53190 131
dzoni 2:aba8d0d53190 132
dzoni 2:aba8d0d53190 133
dzoni 2:aba8d0d53190 134 void _tout(void) {
dzoni 2:aba8d0d53190 135 if (_state == STARTED)
dzoni 2:aba8d0d53190 136 _state = TIMEOUT;
dzoni 2:aba8d0d53190 137 }
dzoni 2:aba8d0d53190 138
dzoni 2:aba8d0d53190 139 void _rising(void) {
dzoni 2:aba8d0d53190 140 if (_state == STARTED) {
dzoni 2:aba8d0d53190 141 _timer.start();
dzoni 2:aba8d0d53190 142 }
dzoni 2:aba8d0d53190 143 }
dzoni 2:aba8d0d53190 144
dzoni 2:aba8d0d53190 145 void _falling(void) {
dzoni 2:aba8d0d53190 146 if (_state == STARTED) {
dzoni 2:aba8d0d53190 147 _timer.stop();
dzoni 2:aba8d0d53190 148 _ticks_us = _timer.read_us();
dzoni 2:aba8d0d53190 149 state = COMPLETED;
dzoni 2:aba8d0d53190 150 }
dzoni 2:aba8d0d53190 151 }
dzoni 2:aba8d0d53190 152
dzoni 2:aba8d0d53190 153 private:
dzoni 2:aba8d0d53190 154 DigitalOut _trig;
dzoni 2:aba8d0d53190 155 InterruptIn _echo;
dzoni 2:aba8d0d53190 156 uint32_t _tout_us;
dzoni 2:aba8d0d53190 157 float _coeff;
dzoni 2:aba8d0d53190 158
dzoni 2:aba8d0d53190 159 Timer _timer;
dzoni 2:aba8d0d53190 160 Timeout _timeout;
dzoni 2:aba8d0d53190 161
dzoni 2:aba8d0d53190 162 volatile Distance_HC_SR04_state _state;
dzoni 3:cb5931861f4e 163 uint32_t _ticks_us;
dzoni 2:aba8d0d53190 164 };
dzoni 2:aba8d0d53190 165
dzoni 2:aba8d0d53190 166
dzoni 2:aba8d0d53190 167
dzoni 0:6fd0fbcfc7e1 168 int main() {
dzoni 0:6fd0fbcfc7e1 169
dzoni 0:6fd0fbcfc7e1 170 trigDist = 0;
dzoni 0:6fd0fbcfc7e1 171 state = IDLE;
dzoni 0:6fd0fbcfc7e1 172 timer_ticks_min = 999999;
dzoni 0:6fd0fbcfc7e1 173
dzoni 0:6fd0fbcfc7e1 174 wait_ms(250);
dzoni 0:6fd0fbcfc7e1 175 lcd.cls();
dzoni 0:6fd0fbcfc7e1 176
dzoni 0:6fd0fbcfc7e1 177 lcd.cls();
dzoni 0:6fd0fbcfc7e1 178 lcd.printf("Row 1");
dzoni 0:6fd0fbcfc7e1 179 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 180 lcd.printf("Row 2");
dzoni 0:6fd0fbcfc7e1 181
dzoni 0:6fd0fbcfc7e1 182 while (true) {
dzoni 0:6fd0fbcfc7e1 183 // Priprava
dzoni 0:6fd0fbcfc7e1 184 state = STARTED;
dzoni 0:6fd0fbcfc7e1 185 timeout.attach_us(&tout, TIMEOUT_DELAY_US);
dzoni 0:6fd0fbcfc7e1 186
dzoni 0:6fd0fbcfc7e1 187 // Dej puls na trig
dzoni 0:6fd0fbcfc7e1 188 trigDist = 1;
dzoni 0:6fd0fbcfc7e1 189 wait_us(500);
dzoni 0:6fd0fbcfc7e1 190 trigDist = 0;
dzoni 0:6fd0fbcfc7e1 191
dzoni 0:6fd0fbcfc7e1 192 // Zkontroluj signal
dzoni 0:6fd0fbcfc7e1 193 if (echoDist != 0) {
dzoni 0:6fd0fbcfc7e1 194 state = ERROR_SIG;
dzoni 0:6fd0fbcfc7e1 195 timer_ticks = 0;
dzoni 0:6fd0fbcfc7e1 196 lcd.cls();
dzoni 0:6fd0fbcfc7e1 197 lcd.printf("Dist.: ---", timer_ticks);
dzoni 0:6fd0fbcfc7e1 198 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 199 lcd.printf("ERROR_SIG");
dzoni 0:6fd0fbcfc7e1 200 } else {
dzoni 0:6fd0fbcfc7e1 201 // Vynuluj timer
dzoni 0:6fd0fbcfc7e1 202 timer.stop();
dzoni 0:6fd0fbcfc7e1 203 timer.reset();
dzoni 0:6fd0fbcfc7e1 204
dzoni 0:6fd0fbcfc7e1 205 // Cekej na hrany na Echo
dzoni 0:6fd0fbcfc7e1 206 while (echoDist == 0 && state == STARTED)
dzoni 0:6fd0fbcfc7e1 207 ;
dzoni 0:6fd0fbcfc7e1 208
dzoni 0:6fd0fbcfc7e1 209 timer.start();
dzoni 0:6fd0fbcfc7e1 210
dzoni 0:6fd0fbcfc7e1 211 while (echoDist == 1 && state == STARTED)
dzoni 0:6fd0fbcfc7e1 212 ;
dzoni 0:6fd0fbcfc7e1 213
dzoni 0:6fd0fbcfc7e1 214 if (state == STARTED) {
dzoni 0:6fd0fbcfc7e1 215 state = COMPLETED;
dzoni 0:6fd0fbcfc7e1 216 timer.stop();
dzoni 0:6fd0fbcfc7e1 217
dzoni 0:6fd0fbcfc7e1 218 timer_ticks = timer.read_us();
dzoni 0:6fd0fbcfc7e1 219 time_float = timer.read()*CALC_COEFF;
dzoni 0:6fd0fbcfc7e1 220
dzoni 0:6fd0fbcfc7e1 221 timer_ticks_min = (timer_ticks_min < timer_ticks) ? timer_ticks_min : timer_ticks;
dzoni 0:6fd0fbcfc7e1 222
dzoni 0:6fd0fbcfc7e1 223 if (timer_ticks < TICKS_RANGE_MIN) {
dzoni 0:6fd0fbcfc7e1 224 timer_ticks = 0;
dzoni 0:6fd0fbcfc7e1 225 time_float = 0.0f;
dzoni 0:6fd0fbcfc7e1 226
dzoni 0:6fd0fbcfc7e1 227 state = OUT_OF_RANGE_MIN;
dzoni 0:6fd0fbcfc7e1 228
dzoni 0:6fd0fbcfc7e1 229 lcd.cls();
dzoni 0:6fd0fbcfc7e1 230 lcd.printf("Dist.: ---");
dzoni 0:6fd0fbcfc7e1 231 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 232 lcd.printf("OUT_OF_RANGE_MIN");
dzoni 0:6fd0fbcfc7e1 233 } else if (timer_ticks > TICKS_RANGE_MAX) {
dzoni 0:6fd0fbcfc7e1 234 timer_ticks = 0;
dzoni 0:6fd0fbcfc7e1 235 time_float = 0.0f;
dzoni 0:6fd0fbcfc7e1 236
dzoni 0:6fd0fbcfc7e1 237 state = OUT_OF_RANGE_MAX;
dzoni 0:6fd0fbcfc7e1 238
dzoni 0:6fd0fbcfc7e1 239 lcd.cls();
dzoni 0:6fd0fbcfc7e1 240 lcd.printf("Dist.: ---");
dzoni 0:6fd0fbcfc7e1 241 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 242 lcd.printf("OUT_OF_RANGE_MAX");
dzoni 0:6fd0fbcfc7e1 243 } else {
dzoni 0:6fd0fbcfc7e1 244 lcd.cls();
dzoni 0:6fd0fbcfc7e1 245 lcd.printf("Dist.: %u %u", timer_ticks, timer_ticks_min);
dzoni 0:6fd0fbcfc7e1 246 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 247 lcd.printf("Dist.: %.3f", time_float);
dzoni 0:6fd0fbcfc7e1 248 }
dzoni 0:6fd0fbcfc7e1 249 } else {
dzoni 0:6fd0fbcfc7e1 250 timer.stop();
dzoni 0:6fd0fbcfc7e1 251 timer_ticks = 0;
dzoni 0:6fd0fbcfc7e1 252 time_float = 0.0f;
dzoni 0:6fd0fbcfc7e1 253
dzoni 0:6fd0fbcfc7e1 254 lcd.cls();
dzoni 0:6fd0fbcfc7e1 255 lcd.printf("Dist.: ---", timer_ticks);
dzoni 0:6fd0fbcfc7e1 256 lcd.locate(0, 1);
dzoni 0:6fd0fbcfc7e1 257 lcd.printf("TIMEOUT");
dzoni 0:6fd0fbcfc7e1 258 }
dzoni 0:6fd0fbcfc7e1 259 }
dzoni 0:6fd0fbcfc7e1 260 timeout.detach();
dzoni 0:6fd0fbcfc7e1 261
dzoni 0:6fd0fbcfc7e1 262 wait_ms(100);
dzoni 0:6fd0fbcfc7e1 263
dzoni 0:6fd0fbcfc7e1 264 state = IDLE;
dzoni 0:6fd0fbcfc7e1 265 }
dzoni 0:6fd0fbcfc7e1 266 }
dzoni 0:6fd0fbcfc7e1 267
dzoni 0:6fd0fbcfc7e1 268
dzoni 0:6fd0fbcfc7e1 269 /*
dzoni 0:6fd0fbcfc7e1 270 // A class for flip()-ing a DigitalOut
dzoni 0:6fd0fbcfc7e1 271 class Flipper {
dzoni 0:6fd0fbcfc7e1 272 public:
dzoni 0:6fd0fbcfc7e1 273 Flipper(PinName pin) : _pin(pin) {
dzoni 0:6fd0fbcfc7e1 274 _pin = 0;
dzoni 0:6fd0fbcfc7e1 275 }
dzoni 0:6fd0fbcfc7e1 276 void flip() {
dzoni 0:6fd0fbcfc7e1 277 _pin = !_pin;
dzoni 0:6fd0fbcfc7e1 278 }
dzoni 0:6fd0fbcfc7e1 279 private:
dzoni 0:6fd0fbcfc7e1 280 DigitalOut _pin;
dzoni 0:6fd0fbcfc7e1 281 };
dzoni 0:6fd0fbcfc7e1 282
dzoni 0:6fd0fbcfc7e1 283 DigitalOut led1(LED1);
dzoni 0:6fd0fbcfc7e1 284 Flipper f(LED2);
dzoni 0:6fd0fbcfc7e1 285 Timeout t;
dzoni 0:6fd0fbcfc7e1 286
dzoni 0:6fd0fbcfc7e1 287 int main() {
dzoni 0:6fd0fbcfc7e1 288 t.attach(&f, &Flipper::flip, 2.0); // the address of the object, member function, and interval
dzoni 0:6fd0fbcfc7e1 289
dzoni 0:6fd0fbcfc7e1 290 // spin in a main loop. flipper will interrupt it to call flip
dzoni 0:6fd0fbcfc7e1 291 while(1) {
dzoni 0:6fd0fbcfc7e1 292 led1 = !led1;
dzoni 0:6fd0fbcfc7e1 293 wait(0.2);
dzoni 0:6fd0fbcfc7e1 294 }
dzoni 0:6fd0fbcfc7e1 295 }
dzoni 0:6fd0fbcfc7e1 296
dzoni 0:6fd0fbcfc7e1 297 */