Skip to content

Commit 06dc3dd

Browse files
committed
add processing samples for sensors
1 parent a98ab09 commit 06dc3dd

34 files changed

Lines changed: 5707 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# APDS9960 Ambient Light Theater
2+
3+
Turns APDS9960 ambient light readings into a window-lit room. Covering or exposing the sensor dims or brightens the scene, opens the blinds visually, and changes the dust motion.
4+
5+
## Requirements
6+
7+
- OSC destination configured to the computer running Processing.
8+
- APDS9960 **Ambient light** enabled.
9+
- Processing `oscP5` library installed.
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
OpenDeck APDS9960 Ambient Light Theater
3+
4+
Receives OpenDeck OSC ambient light data:
5+
/opendeck/sensors/apds9960/ambient_light f
6+
*/
7+
8+
import oscP5.*;
9+
import netP5.*;
10+
11+
OscP5 oscP5;
12+
13+
int oscListenPort = 9000;
14+
String ambientPath = "/opendeck/sensors/apds9960/ambient_light";
15+
16+
float ambient = 0.0;
17+
float visualAmbient = 0.0;
18+
int lastPacketMs = 0;
19+
int packetCount = 0;
20+
boolean receivedData = false;
21+
22+
ArrayList<Dust> dust = new ArrayList<Dust>();
23+
24+
void setup() {
25+
size(1200, 900, P2D);
26+
surface.setTitle("OpenDeck APDS9960 Ambient Light Theater");
27+
28+
oscP5 = new OscP5(this, oscListenPort);
29+
textFont(createFont("SansSerif", 18));
30+
31+
for (int i = 0; i < 220; i++) {
32+
dust.add(new Dust());
33+
}
34+
}
35+
36+
void draw() {
37+
visualAmbient += (ambient - visualAmbient) * 0.08;
38+
39+
drawRoom();
40+
drawWindowLight();
41+
drawBlinds();
42+
drawDust();
43+
drawMeter();
44+
drawHud();
45+
}
46+
47+
void drawRoom() {
48+
int topColor = lerpColor(color(4, 6, 12), color(24, 30, 42), visualAmbient);
49+
int bottomColor = lerpColor(color(10, 8, 13), color(70, 56, 40), visualAmbient);
50+
51+
noStroke();
52+
for (int y = 0; y < height; y++) {
53+
float t = y / float(height - 1);
54+
stroke(lerpColor(topColor, bottomColor, t));
55+
line(0, y, width, y);
56+
}
57+
58+
noStroke();
59+
fill(0, 80 - visualAmbient * 48);
60+
rect(0, height * 0.72, width, height * 0.28);
61+
}
62+
63+
void drawWindowLight() {
64+
float cx = width / 2.0;
65+
float cy = height / 2.0 - 30;
66+
float glow = 260 + visualAmbient * 520;
67+
float beamAlpha = 18 + visualAmbient * 96;
68+
69+
noStroke();
70+
for (int i = 9; i >= 1; i--) {
71+
float t = i / 9.0;
72+
fill(255, 220, 130, beamAlpha * 0.18 * t);
73+
ellipse(cx, cy, glow * t, glow * 0.72 * t);
74+
}
75+
76+
fill(255, 220, 120, 20 + visualAmbient * 85);
77+
quad(cx - 142, cy - 144, cx + 142, cy - 144, width - 70, height, 70, height);
78+
79+
fill(255, 235, 180, 30 + visualAmbient * 150);
80+
rect(cx - 150, cy - 150, 300, 300, 8);
81+
82+
stroke(255, 245, 210, 80 + visualAmbient * 120);
83+
strokeWeight(4);
84+
noFill();
85+
rect(cx - 150, cy - 150, 300, 300, 8);
86+
87+
stroke(255, 245, 210, 70 + visualAmbient * 100);
88+
line(cx, cy - 150, cx, cy + 150);
89+
line(cx - 150, cy, cx + 150, cy);
90+
}
91+
92+
void drawBlinds() {
93+
float cx = width / 2.0;
94+
float cy = height / 2.0 - 30;
95+
float open = visualAmbient;
96+
float slatHeight = 16;
97+
98+
noStroke();
99+
100+
for (int i = 0; i < 12; i++) {
101+
float y = cy - 142 + i * 25;
102+
float tilt = map(open, 0.0, 1.0, 0, 18);
103+
104+
fill(18, 22, 30, 210 - visualAmbient * 90);
105+
quad(cx - 156, y,
106+
cx + 156, y,
107+
cx + 150 - tilt, y + slatHeight,
108+
cx - 150 + tilt, y + slatHeight);
109+
}
110+
}
111+
112+
void drawDust() {
113+
for (Dust particle : dust) {
114+
particle.update(visualAmbient);
115+
particle.draw(visualAmbient);
116+
}
117+
}
118+
119+
void drawMeter() {
120+
float x = 54;
121+
float y = height - 90;
122+
float w = width - 108;
123+
float h = 24;
124+
125+
noStroke();
126+
fill(28, 30, 36);
127+
rect(x, y, w, h, 6);
128+
129+
fill(255, 214, 96);
130+
rect(x, y, w * visualAmbient, h, 6);
131+
132+
noFill();
133+
stroke(255, 180);
134+
strokeWeight(2);
135+
rect(x, y, w, h, 6);
136+
137+
fill(245);
138+
textAlign(LEFT, BOTTOM);
139+
textSize(18);
140+
text("ambient light " + nf(ambient, 1, 3), x, y - 10);
141+
}
142+
143+
void drawHud() {
144+
fill(245);
145+
textAlign(LEFT, TOP);
146+
textSize(22);
147+
text("APDS9960 ambient light theater", 40, 36);
148+
149+
textSize(18);
150+
text("Status: " + statusText(), 40, 72);
151+
text("Packets: " + packetCount, 40, 102);
152+
text("OSC: " + ambientPath, 40, 132);
153+
}
154+
155+
String statusText() {
156+
if (!receivedData) {
157+
return "waiting for OSC";
158+
}
159+
160+
if (millis() - lastPacketMs > 1600) {
161+
return "stale";
162+
}
163+
164+
return "receiving OSC";
165+
}
166+
167+
void oscEvent(OscMessage message) {
168+
if (!message.checkAddrPattern(ambientPath)) {
169+
return;
170+
}
171+
172+
if (message.typetag().length() < 1) {
173+
return;
174+
}
175+
176+
if (message.typetag().charAt(0) == 'f') {
177+
ambient = constrain(message.get(0).floatValue(), 0.0, 1.0);
178+
} else if (message.typetag().charAt(0) == 'i') {
179+
ambient = constrain(message.get(0).intValue() / 255.0, 0.0, 1.0);
180+
} else {
181+
return;
182+
}
183+
184+
receivedData = true;
185+
lastPacketMs = millis();
186+
packetCount++;
187+
}
188+
189+
class Dust {
190+
float x;
191+
float y;
192+
float size;
193+
float speed;
194+
float phase;
195+
196+
Dust() {
197+
reset();
198+
y = random(height);
199+
}
200+
201+
void reset() {
202+
x = random(width);
203+
y = random(-80, height + 80);
204+
size = random(2, 8);
205+
speed = random(0.18, 0.85);
206+
phase = random(TWO_PI);
207+
}
208+
209+
void update(float light) {
210+
y -= speed * (0.25 + light * 1.7);
211+
x += sin(frameCount * 0.018 + phase) * (0.1 + light * 0.42);
212+
213+
if (y < -80 || x < -80 || x > width + 80) {
214+
reset();
215+
y = height + random(20, 120);
216+
}
217+
}
218+
219+
void draw(float light) {
220+
float alpha = (18 + light * 130) * map(y, height, 0, 0.35, 1.0);
221+
222+
noStroke();
223+
fill(255, 235, 170, alpha);
224+
ellipse(x, y, size + light * 4, size + light * 4);
225+
}
226+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# APDS9960 Color Studio
2+
3+
Displays APDS9960 RGB readings as a large live color swatch. Recent detected colors are kept as chips along the bottom so it is easy to compare objects or lighting changes.
4+
5+
## Requirements
6+
7+
- OSC destination configured to the computer running Processing.
8+
- APDS9960 **RGB** enabled.
9+
- Processing `oscP5` library installed.

0 commit comments

Comments
 (0)