Development and testing of ultrasonic distance measurement library for device HC-SR04.
Dependencies: TextLCD_improved mbed Distance_HC_SR04
main.cpp
- Committer:
- dzoni
- Date:
- 2015-12-20
- Branch:
- CLASS_IMPLEMENTATION
- Revision:
- 3:cb5931861f4e
- Parent:
- 2:aba8d0d53190
- Child:
- 4:bb5819be6ac3
File content as of revision 3:cb5931861f4e:
/* * TSK_MAIN.CPP */ #include "mbed.h" #include "TextLCD.h" #define TIMEOUT_DELAY_US (25000) #define CALC_COEFF (1000.0f*340.0f/2) #define TICKS_RANGE_MAX (15000) #define TICKS_RANGE_MIN (150) #define TRIG_PULSE_US (50) typedef enum { IDLE, STARTED, COMPLETED, TIMEOUT, OUT_OF_RANGE_MIN, OUT_OF_RANGE_MAX, ERROR_SIG } Distance_HC_SR04_state; TextLCD lcd(PA_8, PA_7, PA_9, PA_1, PB_5, PA_10, TextLCD::LCD16x2); static DigitalOut trigDist(PB_9); static DigitalIn echoDist(PA_6); static uint32_t timer_ticks; static float time_float; static uint32_t timer_ticks_min; static Timer timer; static Timeout timeout; static volatile Distance_HC_SR04_state state; void tout(void) { if (state == STARTED) state = TIMEOUT; } class Distance_HC_SR04 { public: 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) { _trig = 0; _state = IDLE; } void trigger(void) { if (_state == IDLE && _echo == 0) { _timeout.detach(); _echo.rise(NULL); _echo.fall(NULL); _timer.stop(); _timer.reset(); _trig = 1; wait_us(TRIG_PULSE_US); _trig = 0; if (_echo == 0) { _state = STARTED; timeout.attach_us(this, &Distance_HC_SR04::_tout, TIMEOUT_DELAY_US); _echo.rise(this, &Distance_HC_SR04::_rising); _echo.fall(this, &Distance_HC_SR04::_falling); return; } } if (_state == IDLE) { _state = ERROR_SIG; _ticks_us = 0; } return; } Distance_HC_SR04_state getState(void) { return _state; } void reset(void) { _state = IDLE; _echo.rise(NULL); _echo.fall(NULL); _timeout.detach(); _timer.stop(); _timer.reset(); } uint32_t getTicks(void) { return _ticks_us; } float getDistance(void) { return _ticks_us/_coeff; } float getCoeff(void) { return _coeff; } void setCoeff(float coeff) { _coeff = coeff; } float measureDistance(void) { return measureTicks()/_coeff; } uint32_t measureTicks(void) { reset(); trigger(); while (_state == STARTED) ; _echo.rise(NULL); _echo.fall(NULL); _timeout.detach(); switch (_state) { case COMPLETED: break; default: _ticks_us = 0; break; } return _ticks_us; } void _tout(void) { if (_state == STARTED) _state = TIMEOUT; } void _rising(void) { if (_state == STARTED) { _timer.start(); } } void _falling(void) { if (_state == STARTED) { _timer.stop(); _ticks_us = _timer.read_us(); state = COMPLETED; } } private: DigitalOut _trig; InterruptIn _echo; uint32_t _tout_us; float _coeff; Timer _timer; Timeout _timeout; volatile Distance_HC_SR04_state _state; uint32_t _ticks_us; }; int main() { trigDist = 0; state = IDLE; timer_ticks_min = 999999; wait_ms(250); lcd.cls(); lcd.cls(); lcd.printf("Row 1"); lcd.locate(0, 1); lcd.printf("Row 2"); while (true) { // Priprava state = STARTED; timeout.attach_us(&tout, TIMEOUT_DELAY_US); // Dej puls na trig trigDist = 1; wait_us(500); trigDist = 0; // Zkontroluj signal if (echoDist != 0) { state = ERROR_SIG; timer_ticks = 0; lcd.cls(); lcd.printf("Dist.: ---", timer_ticks); lcd.locate(0, 1); lcd.printf("ERROR_SIG"); } else { // Vynuluj timer timer.stop(); timer.reset(); // Cekej na hrany na Echo while (echoDist == 0 && state == STARTED) ; timer.start(); while (echoDist == 1 && state == STARTED) ; if (state == STARTED) { state = COMPLETED; timer.stop(); timer_ticks = timer.read_us(); time_float = timer.read()*CALC_COEFF; timer_ticks_min = (timer_ticks_min < timer_ticks) ? timer_ticks_min : timer_ticks; if (timer_ticks < TICKS_RANGE_MIN) { timer_ticks = 0; time_float = 0.0f; state = OUT_OF_RANGE_MIN; lcd.cls(); lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("OUT_OF_RANGE_MIN"); } else if (timer_ticks > TICKS_RANGE_MAX) { timer_ticks = 0; time_float = 0.0f; state = OUT_OF_RANGE_MAX; lcd.cls(); lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("OUT_OF_RANGE_MAX"); } else { lcd.cls(); lcd.printf("Dist.: %u %u", timer_ticks, timer_ticks_min); lcd.locate(0, 1); lcd.printf("Dist.: %.3f", time_float); } } else { timer.stop(); timer_ticks = 0; time_float = 0.0f; lcd.cls(); lcd.printf("Dist.: ---", timer_ticks); lcd.locate(0, 1); lcd.printf("TIMEOUT"); } } timeout.detach(); wait_ms(100); state = IDLE; } } /* // A class for flip()-ing a DigitalOut class Flipper { public: Flipper(PinName pin) : _pin(pin) { _pin = 0; } void flip() { _pin = !_pin; } private: DigitalOut _pin; }; DigitalOut led1(LED1); Flipper f(LED2); Timeout t; int main() { t.attach(&f, &Flipper::flip, 2.0); // the address of the object, member function, and interval // spin in a main loop. flipper will interrupt it to call flip while(1) { led1 = !led1; wait(0.2); } } */