-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCosmic_Kali_Rainbow_Serpent_2018.ino
More file actions
255 lines (190 loc) · 6.9 KB
/
Cosmic_Kali_Rainbow_Serpent_2018.ino
File metadata and controls
255 lines (190 loc) · 6.9 KB
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
#include <SimpleTimer.h>
/*written by Alessandro Cesana for Rainbow Serpent 2018, Cosmic Kali interactive installation.
A few videos of the installation: https://www.instagram.com/p/BepblSAF94v/
Inspired by Color Palette and other examples in the FastLed Library*/
#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h>
#include <SerialCommands.h>
#define LED_PIN 3
#define NUM_LEDS 1000
#define BRIGHTNESS 100
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 30 /*change updates per second to adjust speed of color change in a smooth way,
or make it an adjustable parameter to interact with*/
CRGBPalette16 targetPalette( PartyColors_p );
CRGBPalette16 currentPalette( CRGB::Black);
TBlendType currentBlending;
////color palettes declarations
extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;
extern CRGBPalette16 GoldenColors;
extern const TProgmemPalette16 GoldenColors_p PROGMEM;
extern CRGBPalette16 OrangeColors;
extern const TProgmemPalette16 OrangeColors_p PROGMEM;
extern CRGBPalette16 FunkyRedColors;
extern const TProgmemPalette16 FunkyRedColors_p PROGMEM;
String a = "0";
//bool to switch between a non interactive mode(automode = true) and an interactive mode(automode = false)
bool automode = true;
///serial commands to switch automode on or off, not always working when tested with Openframeworks , maybe due to interrupts?
char serial_command_buffer_[32];
SerialCommands serial_commands_(&Serial, serial_command_buffer_, sizeof(serial_command_buffer_), "\r\n", " ");
//default handler, gets called when no other command matches.
void cmd_unrecognized(SerialCommands* sender, const char* cmd)
{
sender->GetSerial()->print("Unrecognized command [");
sender->GetSerial()->print(cmd);
sender->GetSerial()->println("]");
}
void cmd_AUTOMODE_ON_(SerialCommands* sender)
{
{
automode = true; }
}
void cmd_AUTOMODE_OFF_(SerialCommands* sender)
{
{ automode = false;
}
}
SerialCommand cmd_AUTOMODE_OFF("0", cmd_AUTOMODE_OFF_);
SerialCommand cmd_AUTOMODE_ON("1", cmd_AUTOMODE_ON_);
void ChangePalettePeriodically()
{
static uint8_t lastSecond = 0;
uint8_t secondHand = (millis() / 1000) % 8; // loop that rotates between color palettes (example when millis() = 1000 -> 1000/1000 % 8 = 0 -, millis() = 10000 --> 10000/1000 % 8 = 2-> change of color palette happens at 0 seconds, 10 seconds, 20 seconds, 30, 4
// would be way nicer to use variables rather than hard coded but will do it for the moment
if( lastSecond != secondHand) {
lastSecond = secondHand;
if( secondHand == 0) { targetPalette = OrangeColors_p; }
if( secondHand == 2) { targetPalette = FunkyRedColors_p; }
if( secondHand == 4) { targetPalette = OceanColors_p; }
if( secondHand == 6) { targetPalette = ForestColors_p; }
}
}
void ChangeColorModePeriodically() /*timer inserted to rotate between a fixed color mode and a rotating color mode
(or, more generally, different color modes)*/
{
uint8_t secondHand = (millis() / 1000) % 30;
static uint8_t lastSecond = 99;
Serial.println(secondHand);
Serial.println(lastSecond);
if( lastSecond != secondHand) {
lastSecond = secondHand;
if( secondHand == 0) { targetPalette = GoldenColors_p; }
if( secondHand == 10) { ChangePalettePeriodically(); }
//if(secondHand == 40) {s
}
}
void setup() {
delay( 3000 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
Serial.begin(9600);
currentPalette = GoldenColors_p;
currentBlending = LINEARBLEND;
serial_commands_.SetDefaultHandler(cmd_unrecognized);
serial_commands_.AddCommand(&cmd_AUTOMODE_OFF);
serial_commands_.AddCommand(&cmd_AUTOMODE_ON);
}
void loop()
{
serial_commands_.ReadSerial();
///Serial.println(modetimer);
//ChangeColorModePeriodically();
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* change the point on the strip at which leds start changing color adding to startindex to adjust
speed in a quite glitchy way, 1 gives a smooth transition */
FillLEDsFromPaletteColors( startIndex);
FastLED.show();
FastLED.delay(1000 / UPDATES_PER_SECOND);
uint8_t maxChanges = 24;
nblendPaletteTowardPalette( currentPalette, targetPalette, maxChanges);
}
void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = 255;
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 3;
}
}
///programmable palettes
const TProgmemRGBPalette16 GoldenColors_p PROGMEM =
{
CRGB::DarkGoldenrod,
CRGB::Goldenrod,
CRGB::Gold,
CRGB::Goldenrod,
CRGB::Gold,
CRGB::Gold,
CRGB::Gold,
CRGB::Gold,
CRGB::DarkGoldenrod,
CRGB::Yellow,
CRGB::Gold,
CRGB::Goldenrod,
CRGB::Goldenrod,
CRGB::Gold,
CRGB::DarkGoldenrod,
CRGB::Orange
};
const TProgmemRGBPalette16 OrangeColors_p PROGMEM =
{
CRGB::Orange,
CRGB::White,
CRGB::Orange,
CRGB::Orange,
CRGB::DarkOrange,
CRGB::DarkOrange,
CRGB::DarkOrange,
CRGB::DarkOrange,
CRGB::Black,
CRGB::Orange,
CRGB::Orange,
CRGB::Orange,
CRGB::DarkOrange,
CRGB::White,
CRGB::DarkOrange,
CRGB::DarkOrange,
};
const TProgmemRGBPalette16 FunkyRedColors_p PROGMEM =
{
CRGB::Black,
CRGB::Maroon,
CRGB::Black,
CRGB::Orange,
CRGB::DarkRed,
CRGB::Maroon,
CRGB::DarkRed,
CRGB::DarkRed,
CRGB::DarkRed,
CRGB::Red,
CRGB::Orange,
CRGB::Black,
CRGB::Orange,
CRGB::Red,
CRGB::DarkRed,
};
// Additionl notes on FastLED compact palettes:
//
// Normally, in computer graphics, the palette (or "color lookup table")
// has 256 entries, each containing a specific 24-bit RGB color. You can then
// index into the color palette using a simple 8-bit (one byte) value.
// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino
// is quite possibly "too many" bytes.
//
// FastLED does offer traditional 256-element palettes, for setups that
// can afford the 768-byte cost in RAM.
//
// However, FastLED also offers a compact alternative. FastLED offers
// palettes that store 16 distinct entries, but can be accessed AS IF
// they actually have 256 entries; this is accomplished by interpolating
// between the 16 explicit entries to create fifteen intermediate palette
// entries between each pair.
//
// So for example, if you set the first two explicit entries of a compact
// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved
// the first sixteen entries from the virtual palette (of 256), you'd get
// Green, followed by a smooth gradient from green-to-blue, and then Blue.