-
Notifications
You must be signed in to change notification settings - Fork 0
/
11_example_1.ino
117 lines (99 loc) · 3.12 KB
/
11_example_1.ino
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
#include <Servo.h>
// Arduino pin assignment
#define PIN_LED 9
#define PIN_SERVO 10
#define PIN_TRIG 12
#define PIN_ECHO 13
// configurable parameters
#define SND_VEL 346.0 // sound velocity at 24 celsius degree (unit: m/s)
#define INTERVAL 25 // sampling interval (unit: ms)
#define _DIST_MIN 100 // minimum distance to be measured (unit: mm)
#define _DIST_MAX 400 // maximum distance to be measured (unit: mm)
#define _DIST_ALPHA 0.5
// global variables
float timeout; // unit: us
float dist_min, dist_max, dist_raw, dist_prev, dist_ema, alpha; // unit: mm
unsigned long last_sampling_time; // unit: ms
int last_raw;
int i;
float scale; // used for pulse duration to distance conversion
Servo myservo;
void setup() {
// initialize GPIO pins
pinMode(PIN_LED,OUTPUT);
pinMode(PIN_TRIG,OUTPUT);
digitalWrite(PIN_TRIG, LOW);
pinMode(PIN_ECHO,INPUT);
myservo.attach(PIN_SERVO);
myservo.write(90);
// initialize USS related variables
dist_min = _DIST_MIN;
dist_max = _DIST_MAX;
alpha = _DIST_ALPHA;
timeout = (INTERVAL / 2) * 1000.0; // precalculate pulseIn() timeout value. (unit: us)
dist_raw = dist_prev = 0.0; // raw distance output from USS (unit: mm)
last_raw = 0.0;
i = 10;
scale = 0.001 * 0.5 * SND_VEL;
// initialize serial port
Serial.begin(57600);
// initialize last sampling time
last_sampling_time = 0;
}
void loop() {
// wait until next sampling time.
// millis() returns the number of milliseconds since the program started. Will overflow after 50 days.
if(millis() < last_sampling_time + INTERVAL) return;
// get a distance reading from the USS
dist_raw = USS_measure(PIN_TRIG,PIN_ECHO);
dist_ema = alpha * dist_raw +((1 - alpha) * dist_ema);
// output the read value to the serial port
Serial.print("Min:100,raw:");
Serial.print(dist_raw);
Serial.print(" ,ema:");
Serial.print(dist_ema);
Serial.print(",servo:");
Serial.print(myservo.read());
Serial.println("Max:400");
// adjust servo position according to the USS read value
if(dist_raw < 180){
analogWrite(PIN_LED, 255);
myservo.write(0);
i = 10;
}
else if(dist_raw > 180 && dist_raw < 360){
analogWrite(PIN_LED, 0);
if(int(dist_raw/10) > last_raw){
myservo.write(i);
i += 10;
}
else if(int(dist_raw/10) == last_raw){
myservo.write(i);
}
else if(last_raw > int(dist_raw/10)){
i -= 10;
myservo.write(i);
}
}
else if(dist_raw > 360){
analogWrite(PIN_LED, 255);
myservo.write(180);
i = 180;
}
last_raw = int(dist_raw/10);
// update last sampling time
last_sampling_time += INTERVAL;
}
// get a distance reading from USS. return value is in millimeter.
float USS_measure(int TRIG, int ECHO)
{
float reading;
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
reading = pulseIn(ECHO, HIGH, timeout) * scale; // unit: mm
if(reading < dist_min || reading > dist_max) reading = 0.0; // return 0 when out of range.
if(reading == 0.0) reading = dist_prev;
else dist_prev = reading;
return reading;
}