-
Notifications
You must be signed in to change notification settings - Fork 0
/
URMSensor.cpp
118 lines (96 loc) · 2.54 KB
/
URMSensor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "URMSensor.h"
void URMSensor::startMeasure()
{
// Ignoring the call if this instance already started measuring the distance.
if (_currentState == WaitingForPulse || _currentState == Measuring) return;
// Failing the measure if this instance is not attached to the sensor, or the ECHO pin
// is not in IDLE state.
if (!isAttached() ||
(fastDigitalReadEcho() == _echoActiveState))
{
_currentState = Idle;
return;
}
// Starting the measure.
_currentState = WaitingForPulse;
fastDigitalWriteTrig(_trigActiveState);
delayMicroseconds(_trigPulseWidth);
fastDigitalWriteTrig(getOppositeStateFor(_trigActiveState));
resetTime();
refreshState();
}
boolean URMSensor::isMeasuring()
{
return (_currentState == WaitingForPulse || _currentState == Measuring);
}
void URMSensor::interruptMeasure()
{
_currentState = Idle;
}
void URMSensor::refreshState()
{
byte echoState = fastDigitalReadEcho();
switch (_currentState)
{
case WaitingForPulse:
if ((getCurrentDuration() > _timeoutForPulseStart) &&
(echoState != _echoActiveState))
{
_currentState = Idle;
}
else if (echoState == _echoActiveState)
{
_currentState = Measuring;
resetTime();
}
break;
case Measuring:
if ((getCurrentDuration() > _maxPulseDuration) &&
(echoState == _echoActiveState))
{
_currentState = Idle;
}
else if (echoState != _echoActiveState)
{
_currentState = FinishedMeasure;
}
break;
case FinishedMeasure:
case Idle:
default:
break;
}
}
boolean URMSensor::finishedMeasure()
{
// If this instance haven't been attach()'d, reporting failure.
if (!_isAttached)
{
_currentState = Idle;
return true;
}
// Now we'll poll data and refresh state...
refreshState();
// ...and tell the user whether we are finished the work or not.
return (!isMeasuring());
}
unsigned long URMSensor::getMeasuredDistance()
{
if (_currentState != FinishedMeasure) return URM_INVALID_VALUE;
return convertCurrentDurationToDistance();
}
/**
* Synchronously gets the distance in front of the sensor. Maximal working time for
* this method is (timeoutForPulseStart + maxPulseDuration) us. This method is suitable
* for simple applications or for situations when you just need to get distance and
* don't mind if the board's core will be busy for 40-50 ms doing it.
*
* @return Distance in front of the sensor in centimeters, or URM_INVALID_VALUE
* in case of failure.
*/
unsigned long URMSensor::measureDistance()
{
startMeasure();
while (!finishedMeasure()) ;
return getMeasuredDistance();
}