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:
- 4:bb5819be6ac3
- Parent:
- 3:cb5931861f4e
- Child:
- 5:1a69f40177b0
File content as of revision 4:bb5819be6ac3:
/* * MAIN.CPP */ #include "mbed.h" #include "TextLCD.h" #define TIMEOUT_DELAY_US (25000) #define CALC_COEFF (340.0f/(2.0f*1000.0f)) #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); class Distance_HC_SR04 { public: 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) { _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(); if (_ticks_us < _tmin_us) { _ticks_us = 0; _state = OUT_OF_RANGE_MIN; } else if (_ticks_us > _tmax_us) { _ticks_us = 0; _state = OUT_OF_RANGE_MAX; } else { _state = COMPLETED; } } } private: DigitalOut _trig; InterruptIn _echo; uint32_t _tout_us; uint32_t _tmin_us; uint32_t _tmax_us; float _coeff; Timer _timer; Timeout _timeout; volatile Distance_HC_SR04_state _state; uint32_t _ticks_us; }; int main() { wait_ms(250); lcd.cls(); lcd.cls(); lcd.printf("Row 1"); lcd.locate(0, 1); lcd.printf("Row 2"); Distance_HC_SR04 distFront(PB_9, PA_6); uint32_t ticks_us; float distance; while (true) { ticks_us = distFront.measureTicks(); distance = distFront.getDistance(); lcd.cls(); switch (distFront.getState()) { case COMPLETED: lcd.printf("Dist.: %u", ticks_us); lcd.locate(0, 1); lcd.printf("Dist.: %.3f", distance); break; case TIMEOUT: lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("TIMEOUT"); break; case ERROR_SIG: lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("ERROR_SIG"); break; case OUT_OF_RANGE_MIN: lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("OUT_OF_RANGE_MIN"); break; case OUT_OF_RANGE_MAX: lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("OUT_OF_RANGE_MAX"); break; default: lcd.printf("Dist.: ---"); lcd.locate(0, 1); lcd.printf("OTHER"); break; } wait_ms(100); } }