-
Notifications
You must be signed in to change notification settings - Fork 0
/
InMySpace.pde
189 lines (147 loc) · 4.36 KB
/
InMySpace.pde
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import cc.arduino.*;
import org.firmata.*;
import processing.serial.*;
// The arduino
Arduino arduino;
// Connections for the RGB LED
final int redPin = 5;
final int greenPin = 6;
final int bluePin = 9;
// Connection for analog input from range finder
final int rangeFinderPin = 0; // (Analog input 0)
PFont f;
// System states
enum State {
COMFORTABLE,
TOO_CLOSE,
COOLING_OFF,
}
// Variable to keep track of the current state
State currentState = State.COMFORTABLE; // COMFORTABLE is the initial state
// Variable storing a moving average of the range finder reading
float dist = 80.0;
// Threshold distance
final float THRESHOLD = 40.0;
// Variable counting the number of times draw() has been executed.
// This is useful for generating time-based outputs.
int ticks = 0;
// Counter for how many ticks the system will be in the COOLING_OFF state
// once it is entered. 0 is appopriate if the system is not in the
// COOLING_OFF state.
int coolingOff = 0;
// How many ticks the system stays in the COOLING_OFF state before
// returning to the COMFORTABLE state.
final int COOLING_OFF_TIME = 180;
void setup() {
size(400, 400);
String[] ports = Arduino.list();
for (int i = 0; i < ports.length; i++) {
println("Port " + i + ":\t" + ports[i]);
}
arduino = new Arduino(this, Arduino.list()[32], 57600);
arduino.pinMode(redPin, Arduino.OUTPUT);
arduino.pinMode(greenPin, Arduino.OUTPUT);
arduino.pinMode(bluePin, Arduino.OUTPUT);
arduino.analogWrite(redPin, 0);
arduino.analogWrite(greenPin, 0);
arduino.analogWrite(bluePin, 0);
f = createFont("Helvetica", 16, true);
textFont(f, 36);
}
void draw() {
// Update ticks
ticks++;
// Update the range finder
updateRangeFinder();
// draw a circle based on the current range finder reading
background(211);
stroke(0);
fill((int)(255.0-dist), 50, 50);
ellipse(200, 200, (int)(255-dist), (int)(255-dist));
fill(0);
text("dist="+ String.format("%.2f", dist), 80, 350);
State nextState;
switch (currentState) {
case COMFORTABLE:
nextState = exec_COMFORTABLE();
break;
case TOO_CLOSE:
nextState = exec_TOO_CLOSE();
break;
case COOLING_OFF:
nextState = exec_COOLING_OFF();
break;
default:
throw new IllegalStateException("Unhandled state: " + currentState);
}
currentState = nextState;
}
void updateRangeFinder() {
// Here we are smoothing the output of the range finder.
dist = (0.9 * dist) + (0.1 * arduino.analogRead(rangeFinderPin));
}
float theta = 0;
State exec_COMFORTABLE() {
// Generate output(s)
// This makes the brightness of the green directly proportional
// to the distance
//arduino.analogWrite(greenPin, (int)(dist/4));
// This generates a pulsing effect that is inversely
// proportional to the distance
theta += Math.max(100 - dist, 0) / 200.0;
float g = ((sin(theta) + 1.0) / 2.0) * 255.0;
arduino.analogWrite(greenPin, (int)g);
// Determine next state
State nextState;
if (dist > THRESHOLD) {
// Stay in COMFORTABLE state
nextState = State.COMFORTABLE;
} else {
// Transition to TOO_CLOSE state
nextState = State.TOO_CLOSE;
// Turn off green
arduino.analogWrite(greenPin, 0);
}
return nextState;
}
State exec_TOO_CLOSE() {
// Generate outputs
float x = 2.0;
float theta = ticks / x;
float r = ((sin(theta) + 1.0) / 2.0) * 255.0;
arduino.analogWrite(redPin, (int)r);
// Determine next state
State nextState;
if (dist <= THRESHOLD) {
// Stay in TOO_CLOSE state
nextState = State.TOO_CLOSE;
} else {
// Transition to COOLING_OFF state
nextState = State.COOLING_OFF;
// Turn off red
arduino.analogWrite(redPin, 0);
// Set initial coolingOff counter value.
coolingOff = COOLING_OFF_TIME;
}
return nextState;
}
State exec_COOLING_OFF() {
// Generate outputs
// The intensity of the blue decays as we get closer
// to returning to the COMFORTABLE state
float b = (float)coolingOff / (float)COOLING_OFF_TIME;
arduino.analogWrite(bluePin, (int)(b * 255.0));
coolingOff--;
// Determine next state
State nextState;
if (coolingOff > 0) {
// Stay in COOLING_OFF state
nextState = State.COOLING_OFF;
} else {
// Transition to COMFORTABLE
nextState = State.COMFORTABLE;
// Turn off blue
arduino.analogWrite(bluePin, 0);
}
return nextState;
}