forked from mrRobot62/Arduino-ultrasonic-SR04-library
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SR04.cpp
124 lines (108 loc) · 2.68 KB
/
SR04.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
119
120
121
122
123
124
/**
* SR04.cpp
* Arduino\Energia library for SR04 ultrasonic distance sensor.
* Forked from mrRobot62/Arduino-ultrasonic-SR04-library
*
* modified-by: miller
* last-modified: 9/18/2022
*/
#include "SR04.h"
#define FETCH_TIMEOUT 5 // re-attempts allowed when averaging
#define TRIG_PULSE_WIDTH 20 // 20 us
#define SETTLE_TIME 4 // 4 us
#define FAILURE_DELAY 10000 // 10 ms
SR04::SR04(int echoPin, int triggerPin) {
_echoPin = echoPin;
_triggerPin = triggerPin;
_autoMode = false;
_distance = MAX_DISTANCE;
}
SR04::SR04(int echoTrigPin) {
_echoPin = echoTrigPin;
_triggerPin = echoTrigPin;
_autoMode = true;
_distance = MAX_DISTANCE;
}
void SR04::init() {
if (_autoMode) {
pinMode(_echoPin, INPUT);
} else {
pinMode(_echoPin, INPUT);
pinMode(_triggerPin, OUTPUT);
}
}
long SR04::Distance() {
long d = 0;
_duration = 0;
if (_autoMode) {
pinMode(_triggerPin, OUTPUT);
}
digitalWrite(_triggerPin, LOW);
delayMicroseconds(SETTLE_TIME);
// check if echo signal already high
if (digitalRead(_echoPin) == HIGH) {
// reduce frequency of failed attempts (for looping operations)
delayMicroseconds(FAILURE_DELAY);
return MAX_DISTANCE;
}
digitalWrite(_triggerPin, HIGH);
delayMicroseconds(TRIG_PULSE_WIDTH);
digitalWrite(_triggerPin, LOW);
delayMicroseconds(SETTLE_TIME);
if (_autoMode) {
pinMode(_echoPin, INPUT);
}
_duration = pulseIn(_echoPin, HIGH, PULSE_TIMEOUT);
d = MicrosecondsToCentimeter(_duration);
return d;
}
long SR04::DistanceAvg(int wait, int count) {
long min, max, avg, d;
int fetch;
min = 999;
max = 0;
avg = d = 0;
if (wait < 1) {
wait = 1;
}
if (count < 1) {
count = 1;
}
for (int x = 0; x < count + 2; x++) {
fetch = 0;
d = Distance();
while (d == MAX_DISTANCE) {
if ((++fetch) > FETCH_TIMEOUT) {
return MAX_DISTANCE;
}
delayMicroseconds(FAILURE_DELAY);
d = Distance();
}
if (d < min) {
min = d;
}
if (d > max) {
max = d;
}
avg += d;
delay(wait);
}
// substract highest and lowest value
avg -= (max + min);
// calculate average
avg /= count;
return avg;
}
void SR04::Ping() {
_distance = Distance();
}
long SR04::getDistance() {
return _distance;
}
long SR04::MicrosecondsToCentimeter(long duration) {
long d = (duration * 100) / 5882;
if ((d == 0) || (d > MAX_DISTANCE)) {
d = MAX_DISTANCE;
}
return d;
}