Skip to content

Commit 9382827

Browse files
authored
Add files via upload
1 parent 9cc58c0 commit 9382827

File tree

4 files changed

+835
-0
lines changed

4 files changed

+835
-0
lines changed
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
// SPDX-FileCopyrightText: 2014 HerrRausB https://github.com/HerrRausB
2+
//
3+
// SPDX-License-Identifier: LGPL-3.0-or-later
4+
//
5+
/******************************************************************************
6+
*
7+
* this file is part of the gemma hoop animator example sketch
8+
*
9+
* it is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as
11+
* published by the Free Software Foundation, either version 3 of
12+
* the License, or (at your option) any later version.
13+
*
14+
* it is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. see the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* you should have received a copy of the GNU Lesser General Public
20+
* License along with NeoPixel. If not, see
21+
* <http://www.gnu.org/licenses/>.
22+
*
23+
* ----------------------------------------------------------------------------
24+
*
25+
* this is the general implementation of the gemma hoop animator - unless you
26+
* don't like the preset animations or find a major bug, you don't need to
27+
* change anything here
28+
*
29+
* ----------------------------------------------------------------------------
30+
*
31+
* this sketch simply cycles through the action list defined in
32+
* GemmaHoopActiuonList.h. it should run on any arduino compatible µC
33+
* and with all available NeoPixel products - you just have to adjust
34+
* the general settings in GemmaHoopActionList.h.
35+
*
36+
* it hereby loads the individually defined actions one after the other
37+
* and continously steps through these actions according to the action
38+
* speed specified for the respective action.
39+
*
40+
* independently from stepping through the current action, it also changes
41+
* the current color according to the color change interval and the
42+
* respective color selection method (random or spectrum)
43+
* definied for the current action.
44+
*
45+
* each action will continue according to the current action duration
46+
* as defined in the action list. then the next action will be loaded. when
47+
* the last action in the list is reached, it will continue with the first
48+
* action.
49+
*
50+
* ----------------------------------------------------------------------------
51+
*
52+
* the number of actions possible is limited by the RAM of the used µC. shall
53+
* the list be too long, the µC will crash and nothing will go on.
54+
*
55+
* i'd rather like to put the action definitions on a SD card or any external
56+
* storage to get more space for as well more different action implementations
57+
* as an unlimited number of actions per animation including more control
58+
* parameters as for example:
59+
*
60+
* - brightnes control per action
61+
* - speed wipes per action, which would reduce the number
62+
* of actions to be defined for seamless speed changes
63+
*
64+
* as i designed this for the gemma hoops as suggested on adafruit's web page
65+
* there seems to be no suitable way of connecting an external storage device
66+
*
67+
******************************************************************************/
68+
69+
#include <Adafruit_NeoPixel.h>
70+
71+
/******************************************************************************
72+
*
73+
* where the action list is to be declared and all animation actions
74+
* are to be defined:
75+
*
76+
******************************************************************************/
77+
78+
#include "GemmaHoopActionList.h"
79+
80+
/******************************************************************************
81+
*
82+
* general global variables
83+
*
84+
******************************************************************************/
85+
86+
uint32_t color = 0,
87+
color_timer = 0,
88+
action_timer = 0,
89+
action_step_timer = 0;
90+
uint16_t color_idx = 0,
91+
curr_color_interval = 0,
92+
curr_action_step_duration = 0,
93+
curr_action_duration = 0;
94+
uint8_t spectrum_part = 0,
95+
curr_action = 0,
96+
curr_color_gen = COL_RANDOM,
97+
idx = 0,
98+
offset = 0,
99+
number_of_actions = 0,
100+
curr_action_idx = 0,
101+
curr_color_granularity = 1;
102+
103+
/******************************************************************************
104+
*
105+
* general global variables
106+
*
107+
******************************************************************************/
108+
109+
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIXEL_OUTPUT);
110+
111+
/******************************************************************************
112+
*
113+
* initializing - note that the action list is declared and initialized
114+
* in GemmaHoopActionList.h!
115+
*
116+
******************************************************************************/
117+
118+
void setup()
119+
{
120+
// fingers corssed, the seeding makes sense to really get random colors...
121+
randomSeed(analogRead(ANALOG_INPUT));
122+
123+
// we need to know, how many actions are defined - shall the there be too
124+
// many actions defined, the RAM will overflow and he µC won't do anything
125+
// --> rather easy diagnosis ;-)
126+
number_of_actions = sizeof (theActionList) / sizeof (actiondesc);
127+
128+
// let's go!
129+
pixels.begin();
130+
pixels.setBrightness(BRIGHTNESS);
131+
nextColor();
132+
pixels.show();
133+
}
134+
135+
/******************************************************************************
136+
*
137+
* where all the magic happens - note that the action list is declared and
138+
* initialized in GemmaHoopActionList.h!
139+
*
140+
******************************************************************************/
141+
142+
void loop()
143+
{
144+
// do we need to load the next action?
145+
if ((millis() - action_timer) > curr_action_duration)
146+
{
147+
curr_action_duration = theActionList[curr_action_idx].action_duration;
148+
curr_action = theActionList[curr_action_idx].action_and_color_gen & 0b00111111;
149+
curr_action_step_duration = theActionList[curr_action_idx].action_step_duration;
150+
curr_color_gen = theActionList[curr_action_idx].action_and_color_gen & 0b11000000;
151+
curr_color_granularity = theActionList[curr_action_idx].color_granularity;
152+
curr_color_interval = theActionList[curr_action_idx].color_interval;
153+
154+
curr_action_idx++;
155+
// take care to rotate the action list!
156+
curr_action_idx %= number_of_actions;
157+
158+
action_timer = millis();
159+
}
160+
161+
// do we need to change to the next color?
162+
if ((millis() - color_timer) > curr_color_interval)
163+
{
164+
nextColor();
165+
color_timer = millis();
166+
}
167+
168+
// do we need to step up the current action?
169+
if ((millis() - action_step_timer) > curr_action_step_duration)
170+
{
171+
switch (curr_action)
172+
{
173+
case ACT_NOP :
174+
{
175+
// rather trivial even tho this will be repeated as long as the
176+
// NOP continues - i could have prevented it from repeating
177+
// unnecessarily, but that would mean more code and less
178+
// space for more actions within the animation
179+
for (int i = 0; i < NUM_PIXELS; i++) pixels.setPixelColor(i,0);
180+
break;
181+
}
182+
case ACT_SIMPLE_RING :
183+
{
184+
// even more trivial - just set the new color, if there is one
185+
for (int i = 0; i < NUM_PIXELS; i++) pixels.setPixelColor(i,color);
186+
break;
187+
}
188+
case ACT_CYCLING_RING_ACLK :
189+
case ACT_CYCLING_RING_CLKW :
190+
{
191+
// spin the ring clockwise or anti clockwise
192+
(curr_action == ACT_CYCLING_RING_ACLK) ? idx++ : idx--;
193+
// prevent overflows or underflows
194+
idx %= NUM_PIXELS;
195+
// set the new color, if there is one
196+
pixels.setPixelColor(idx,color);
197+
break;
198+
}
199+
case ACT_WHEEL_ACLK :
200+
case ACT_WHEEL_CLKW :
201+
{
202+
// switch on / off the appropriate pixels according to
203+
// the current offset
204+
for(idx=0; idx < NUM_PIXELS; idx++)
205+
{
206+
pixels.setPixelColor(idx, ((offset + idx) & 7) < 2 ? color : 0);
207+
}
208+
// advance the offset and thus, spin the wheel
209+
// clockwise or anti clockwise
210+
(curr_action == ACT_WHEEL_CLKW) ? offset++ : offset--;
211+
// prevent overflows or underflows
212+
offset %= NUM_PIXELS;
213+
break;
214+
}
215+
case ACT_SPARKLING_RING :
216+
{
217+
// switch current pixel off
218+
pixels.setPixelColor(idx,0);
219+
// pick a new pixel
220+
idx = random (NUM_PIXELS);
221+
// set new pixel to the current color
222+
pixels.setPixelColor(idx,color);
223+
break;
224+
}
225+
/* for the sake of free RAM we disobey the rules
226+
of consistent coding and leave the following
227+
228+
default :
229+
{
230+
}
231+
*/
232+
}
233+
pixels.show();
234+
action_step_timer = millis();
235+
}
236+
}
237+
238+
void nextColor ()
239+
{
240+
/*
241+
* detailed color generation method selection is obsolete
242+
* as long as there are just two methods
243+
244+
switch (curr_color_gen)
245+
{
246+
case COL_RANDOM :
247+
{
248+
nextRandomColor();
249+
break;
250+
}
251+
case COL_SPECTRUM :
252+
{
253+
nextSpectrumColor();
254+
break;
255+
}
256+
default :
257+
{
258+
}
259+
}
260+
261+
*/
262+
263+
// save some RAM for more animation actions
264+
(curr_color_gen & COL_RANDOM) ? nextRandomColor() : nextSpectrumColor();
265+
}
266+
267+
void nextSpectrumColor ()
268+
{
269+
switch (spectrum_part)
270+
{
271+
case 0 : // spectral wipe from red to blue
272+
{
273+
color = Adafruit_NeoPixel::Color(255-color_idx,color_idx,0);
274+
color_idx += curr_color_granularity;
275+
if (color_idx > 255)
276+
{
277+
spectrum_part = 1;
278+
color_idx = 0;
279+
}
280+
break;
281+
}
282+
case 1 : // spectral wipe from blue to green
283+
{
284+
color = Adafruit_NeoPixel::Color(0,255-color_idx,color_idx);
285+
color_idx += curr_color_granularity;
286+
if (color_idx > 255)
287+
{
288+
spectrum_part = 2;
289+
color_idx = 0;
290+
}
291+
break;
292+
}
293+
case 2 : // spectral wipe from green to red
294+
{
295+
color = Adafruit_NeoPixel::Color(color_idx,0,255-color_idx);
296+
color_idx += curr_color_granularity;
297+
if (color_idx > 255)
298+
{
299+
spectrum_part = 0;
300+
color_idx = 0;
301+
}
302+
break;
303+
}
304+
/* for the sake of free RAM we disobey the rules
305+
of consistent coding and leave the following
306+
307+
default :
308+
{
309+
}
310+
*/
311+
}
312+
}
313+
314+
void nextRandomColor ()
315+
{
316+
color = Adafruit_NeoPixel::Color(random(256/curr_color_granularity) * curr_color_granularity,
317+
// granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
318+
random(256/curr_color_granularity) * curr_color_granularity,
319+
// granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
320+
random(256/curr_color_granularity) * curr_color_granularity);
321+
// granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
322+
}
323+

0 commit comments

Comments
 (0)