-
Notifications
You must be signed in to change notification settings - Fork 0
/
sign.ino
280 lines (225 loc) · 6.53 KB
/
sign.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
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
Project: Astralis LED Sign
Created by: Jonas Ibsen
https://github.com/Uberibsen
This project is licensed under a Creative Commons Attribution 4.0 International License.
*/
// LED strip WS2812B
#include "FastLED.h"
#define NUM_LEDS 72
#define LED_DATA 12
const int brightnessPin = A1; // Brightness control
CRGB leds[NUM_LEDS];
#define MAX_BRIGHTNESS 255 // Maximum brightness
#define MIN_BRIGHTNESS 0 // Minimum brightness
// 7-segment display
#define LATCH 9
#define CLK 7
#define DATA 8
// Lightning sequence button
#define buttonPin 11
int sequenceNumber = -1;
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
// Microphone
const int microphonePin = A2;
// Declaring the bytes transferred to the 74HC595 making up the 7-segment display
const byte digit[]= {
B11111101, // 0
B01100000, // 1
B11011011, // 2
B11110011, // 3
B01100110, // 4
B10110111, // 5
B10111111, // 6
B11100000, // 7
B11111110, // 8
B11110111, // 9
B10011111, // E
};
void setup() {
// 74HC595 Bit Shift Register Pins
pinMode(LATCH, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(DATA, OUTPUT);
// WS2812B Pins
pinMode(LED_DATA, OUTPUT);
FastLED.addLeds<WS2812, LED_DATA, GRB>(leds, NUM_LEDS);
// Sequence Button Pin
pinMode(buttonPin, INPUT);
// Brightness Control Pin
pinMode(brightnessPin, INPUT);
// Microphone input pin
pinMode(microphonePin, INPUT);
}
// **************************
// ** LED Effect Functions **
// **************************
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifndef ADAFRUIT_NEOPIXEL_H
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
void showStrip() {
#ifndef ADAFRUIT_NEOPIXEL_H
FastLED.show();
#endif
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}
// Fade in and out effect
int iFadeInOut = 0;
bool bFadeInOut = true;
void FadeInOut(byte red, byte green, byte blue) {
float r, g, b;
if (bFadeInOut) {
r = (iFadeInOut/256.0)*red;
g = (iFadeInOut/256.0)*green;
b = (iFadeInOut/256.0)*blue;
setAll(r,g,b);
showStrip();
iFadeInOut++;
bFadeInOut = iFadeInOut <= 255;
} else {
r = (iFadeInOut/256.0)*red;
g = (iFadeInOut/256.0)*green;
b = (iFadeInOut/256.0)*blue;
setAll(r,g,b);
showStrip();
iFadeInOut -= 2;
bFadeInOut = iFadeInOut <= 0;
}
}
// Running lights effect
int iRunningLights = 1;
int RunningLightsDistance = 5;
int RunningLightsDelay = 4;
void RunningLights(byte red, byte green, byte blue) {
for(int i=0; i<NUM_LEDS; i++) {
setPixel(i,((sin(i+(iRunningLights / RunningLightsDelay)) * 127 + 128)/255)*red,
((sin(i+(iRunningLights / RunningLightsDelay)) * 127 + 128)/255)*green,
((sin(i+(iRunningLights / RunningLightsDelay)) * 127 + 128)/255)*blue);
}
showStrip();
iRunningLights = (iRunningLights + 1) % (RunningLightsDistance * RunningLightsDelay);
}
// Theater chase effect
int theaterDistance = 3;
int theaterDelay = 300;
int theaterJ = 0;
int theaterI = 0;
void theaterChase(byte red, byte green, byte blue) {
if (theaterI == 0) {
for (int i=0; i < NUM_LEDS; i++) {
setPixel(i, 0,0,0);
}
for (int i=0; i < NUM_LEDS; i+=theaterDistance) {
setPixel(i+theaterJ, red, green, blue); //turn every theaterDistance pixel on
}
showStrip();
theaterJ = (theaterJ + 1) % theaterDistance;
}
theaterI = (theaterI + 1) % theaterDelay;
}
// Meteor rain effect
int meteorRainI = 0;
int meteorRainDelay = 10;
int meteorTrailLength = 30;
void meteorRain(byte red, byte green, byte blue)
{
int i = meteorRainI / meteorRainDelay;
int positionMod = i + NUM_LEDS - meteorTrailLength;
for (int j = meteorTrailLength; j >= 0; j--)
{
int position = (j + positionMod) % NUM_LEDS;
int strength = ((j * 255) / meteorTrailLength);
setPixel(position, (red * strength) / 255, (green * strength) / 255, (blue * strength) / 255);
}
for (int j = 1; j < NUM_LEDS - meteorTrailLength; j++)
{
setPixel((i + j + NUM_LEDS) % NUM_LEDS, 0, 0, 0);
}
showStrip();
meteorRainI = (meteorRainI + 1) % (NUM_LEDS * meteorRainDelay);
}
// Sparkle effect
void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
int Pixel = random(NUM_LEDS);
setPixel(Pixel,red,green,blue);
showStrip();
delay(SpeedDelay);
setPixel(Pixel,0,0,0);
}
// Reactive lights from sound
void Microphone(byte red, byte green, byte blue, int micData){
FastLED.setBrightness(micData);
fill_solid(leds, NUM_LEDS, CRGB::Red); // Sets all LED's to red.
showStrip();
}
// Helper function for switch/case statements
// Controls the 7-segment display
void writeAndShift(int digitNumber) {
for (int i = 0; i <= 8; i++)
{
digitalWrite(LATCH, LOW);
digitalWrite(CLK, LOW);
shiftOut(DATA, CLK, MSBFIRST, digit[digitNumber] >> i);
digitalWrite(LATCH, HIGH);
delay(20);
}
}
// ***********************
// ** LED strip control **
// ***********************
void loop(){
// LED lightning sequence control
buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
sequenceNumber = (sequenceNumber+1) % 5;
writeAndShift(sequenceNumber + 1);
setAll(0, 0, 0);
}
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
// LED brightness control
int brightnessValue = map(analogRead(brightnessPin), 0, 1023, 0, 255);
// LED reactive brightness
int micData = map(analogRead(microphonePin), 0, 1023, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
while (sequenceNumber != 5){
FastLED.setBrightness(constrain(brightnessValue, MIN_BRIGHTNESS, MAX_BRIGHTNESS));
break;
}
switch(sequenceNumber){
case 0:
FadeInOut(0xff, 0x00, 0x00); // Only using red
break;
case 1:
RunningLights(0xff, 0x00, 0x00); // Only using red
break;
case 2:
theaterChase(0xff, 0x00, 0x00); // Only using red
break;
case 3:
meteorRain(0xff, 0x00, 0x00); // Only using red
break;
case 4:
Sparkle(0xff, 0x00, 0x00, 2); // Only using red
break;
case 5:
Microphone(0xff, 0x00, 0x00, micData); // Only using red
break;
default: // Failsafe if the sequence number cannot be read
fill_solid(leds, NUM_LEDS, CRGB::Red); // Sets all LED's to red.
FastLED.show();
writeAndShift(10); // Displays an 'E' on the 7-seg display to indicate an error
break;
}
}