ported to CircuitPython
This commit is contained in:
parent
4f0276012c
commit
a4e4f5592e
6 changed files with 783 additions and 0 deletions
Binary file not shown.
|
|
@ -0,0 +1,320 @@
|
|||
|
||||
/******************************************************************************
|
||||
*
|
||||
* this file is part of the gemma hoop animator example sketch
|
||||
*
|
||||
* it is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* it is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. see the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* you should have received a copy of the GNU Lesser General Public
|
||||
* License along with NeoPixel. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* this is the general implementation of the gemma hoop animator - unless you
|
||||
* don't like the preset animations or find a major bug, you don't need to
|
||||
* change anything here
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* this sketch simply cycles through the action list defined in
|
||||
* GemmaHoopActiuonList.h. it should run on any arduino compatible µC
|
||||
* and with all available NeoPixel products - you just have to adjust
|
||||
* the general settings in GemmaHoopActionList.h.
|
||||
*
|
||||
* it hereby loads the individually defined actions one after the other
|
||||
* and continously steps through these actions according to the action
|
||||
* speed specified for the respective action.
|
||||
*
|
||||
* independently from stepping through the current action, it also changes
|
||||
* the current color according to the color change interval and the
|
||||
* respective color selection method (random or spectrum)
|
||||
* definied for the current action.
|
||||
*
|
||||
* each action will continue according to the current action duration
|
||||
* as defined in the action list. then the next action will be loaded. when
|
||||
* the last action in the list is reached, it will continue with the first
|
||||
* action.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* the number of actions possible is limited by the RAM of the used µC. shall
|
||||
* the list be too long, the µC will crash and nothing will go on.
|
||||
*
|
||||
* i'd rather like to put the action definitions on a SD card or any external
|
||||
* storage to get more space for as well more different action implementations
|
||||
* as an unlimited number of actions per animation including more control
|
||||
* parameters as for example:
|
||||
*
|
||||
* - brightnes control per action
|
||||
* - speed wipes per action, which would reduce the number
|
||||
* of actions to be defined for seamless speed changes
|
||||
*
|
||||
* as i designed this for the gemma hoops as suggested on adafruit's web page
|
||||
* there seems to be no suitable way of connecting an external storage device
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* where the action list is to be declared and all animation actions
|
||||
* are to be defined:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "GemmaHoopActionList.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* general global variables
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t color = 0,
|
||||
color_timer = 0,
|
||||
action_timer = 0,
|
||||
action_step_timer = 0;
|
||||
uint16_t color_idx = 0,
|
||||
curr_color_interval = 0,
|
||||
curr_action_step_duration = 0,
|
||||
curr_action_duration = 0;
|
||||
uint8_t spectrum_part = 0,
|
||||
curr_action = 0,
|
||||
curr_color_gen = COL_RANDOM,
|
||||
idx = 0,
|
||||
offset = 0,
|
||||
number_of_actions = 0,
|
||||
curr_action_idx = 0,
|
||||
curr_color_granularity = 1;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* general global variables
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIXEL_OUTPUT);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* initializing - note that the action list is declared and initialized
|
||||
* in GemmaHoopActionList.h!
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void setup()
|
||||
{
|
||||
// fingers corssed, the seeding makes sense to really get random colors...
|
||||
randomSeed(analogRead(ANALOG_INPUT));
|
||||
|
||||
// we need to know, how many actions are defined - shall the there be too
|
||||
// many actions defined, the RAM will overflow and he µC won't do anything
|
||||
// --> rather easy diagnosis ;-)
|
||||
number_of_actions = sizeof (theActionList) / sizeof (actiondesc);
|
||||
|
||||
// let's go!
|
||||
pixels.begin();
|
||||
pixels.setBrightness(BRIGHTNESS);
|
||||
nextColor();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* where all the magic happens - note that the action list is declared and
|
||||
* initialized in GemmaHoopActionList.h!
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void loop()
|
||||
{
|
||||
// do we need to load the next action?
|
||||
if ((millis() - action_timer) > curr_action_duration)
|
||||
{
|
||||
curr_action_duration = theActionList[curr_action_idx].action_duration;
|
||||
curr_action = theActionList[curr_action_idx].action_and_color_gen & 0b00111111;
|
||||
curr_action_step_duration = theActionList[curr_action_idx].action_step_duration;
|
||||
curr_color_gen = theActionList[curr_action_idx].action_and_color_gen & 0b11000000;
|
||||
curr_color_granularity = theActionList[curr_action_idx].color_granularity;
|
||||
curr_color_interval = theActionList[curr_action_idx].color_interval;
|
||||
|
||||
curr_action_idx++;
|
||||
// take care to rotate the action list!
|
||||
curr_action_idx %= number_of_actions;
|
||||
|
||||
action_timer = millis();
|
||||
}
|
||||
|
||||
// do we need to change to the next color?
|
||||
if ((millis() - color_timer) > curr_color_interval)
|
||||
{
|
||||
nextColor();
|
||||
color_timer = millis();
|
||||
}
|
||||
|
||||
// do we need to step up the current action?
|
||||
if ((millis() - action_step_timer) > curr_action_step_duration)
|
||||
{
|
||||
switch (curr_action)
|
||||
{
|
||||
case ACT_NOP :
|
||||
{
|
||||
// rather trivial even tho this will be repeated as long as the
|
||||
// NOP continues - i could have prevented it from repeating
|
||||
// unnecessarily, but that would mean more code and less
|
||||
// space for more actions within the animation
|
||||
for (int i = 0; i < NUM_PIXELS; i++) pixels.setPixelColor(i,0);
|
||||
break;
|
||||
}
|
||||
case ACT_SIMPLE_RING :
|
||||
{
|
||||
// even more trivial - just set the new color, if there is one
|
||||
for (int i = 0; i < NUM_PIXELS; i++) pixels.setPixelColor(i,color);
|
||||
break;
|
||||
}
|
||||
case ACT_CYCLING_RING_ACLK :
|
||||
case ACT_CYCLING_RING_CLKW :
|
||||
{
|
||||
// spin the ring clockwise or anti clockwise
|
||||
(curr_action == ACT_CYCLING_RING_ACLK) ? idx++ : idx--;
|
||||
// prevent overflows or underflows
|
||||
idx %= NUM_PIXELS;
|
||||
// set the new color, if there is one
|
||||
pixels.setPixelColor(idx,color);
|
||||
break;
|
||||
}
|
||||
case ACT_WHEEL_ACLK :
|
||||
case ACT_WHEEL_CLKW :
|
||||
{
|
||||
// switch on / off the appropriate pixels according to
|
||||
// the current offset
|
||||
for(idx=0; idx < NUM_PIXELS; idx++)
|
||||
{
|
||||
pixels.setPixelColor(idx, ((offset + idx) & 7) < 2 ? color : 0);
|
||||
}
|
||||
// advance the offset and thus, spin the wheel
|
||||
// clockwise or anti clockwise
|
||||
(curr_action == ACT_WHEEL_CLKW) ? offset++ : offset--;
|
||||
// prevent overflows or underflows
|
||||
offset %= NUM_PIXELS;
|
||||
break;
|
||||
}
|
||||
case ACT_SPARKLING_RING :
|
||||
{
|
||||
// switch current pixel off
|
||||
pixels.setPixelColor(idx,0);
|
||||
// pick a new pixel
|
||||
idx = random (NUM_PIXELS);
|
||||
// set new pixel to the current color
|
||||
pixels.setPixelColor(idx,color);
|
||||
break;
|
||||
}
|
||||
/* for the sake of free RAM we disobey the rules
|
||||
of consistent coding and leave the following
|
||||
|
||||
default :
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
||||
pixels.show();
|
||||
action_step_timer = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void nextColor ()
|
||||
{
|
||||
/*
|
||||
* detailed color generation method selection is obsolete
|
||||
* as long as there are just two methods
|
||||
|
||||
switch (curr_color_gen)
|
||||
{
|
||||
case COL_RANDOM :
|
||||
{
|
||||
nextRandomColor();
|
||||
break;
|
||||
}
|
||||
case COL_SPECTRUM :
|
||||
{
|
||||
nextSpectrumColor();
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// save some RAM for more animation actions
|
||||
(curr_color_gen & COL_RANDOM) ? nextRandomColor() : nextSpectrumColor();
|
||||
}
|
||||
|
||||
void nextSpectrumColor ()
|
||||
{
|
||||
switch (spectrum_part)
|
||||
{
|
||||
case 0 : // spectral wipe from red to blue
|
||||
{
|
||||
color = Adafruit_NeoPixel::Color(255-color_idx,color_idx,0);
|
||||
color_idx += curr_color_granularity;
|
||||
if (color_idx > 255)
|
||||
{
|
||||
spectrum_part = 1;
|
||||
color_idx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1 : // spectral wipe from blue to green
|
||||
{
|
||||
color = Adafruit_NeoPixel::Color(0,255-color_idx,color_idx);
|
||||
color_idx += curr_color_granularity;
|
||||
if (color_idx > 255)
|
||||
{
|
||||
spectrum_part = 2;
|
||||
color_idx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2 : // spectral wipe from green to red
|
||||
{
|
||||
color = Adafruit_NeoPixel::Color(color_idx,0,255-color_idx);
|
||||
color_idx += curr_color_granularity;
|
||||
if (color_idx > 255)
|
||||
{
|
||||
spectrum_part = 0;
|
||||
color_idx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* for the sake of free RAM we disobey the rules
|
||||
of consistent coding and leave the following
|
||||
|
||||
default :
|
||||
{
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void nextRandomColor ()
|
||||
{
|
||||
color = Adafruit_NeoPixel::Color(random(256/curr_color_granularity) * curr_color_granularity,
|
||||
// granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
|
||||
random(256/curr_color_granularity) * curr_color_granularity,
|
||||
// granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
|
||||
random(256/curr_color_granularity) * curr_color_granularity);
|
||||
// granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
#
|
||||
# 3D_Printed_NeoPixel_Ring_Hair_Dress.py
|
||||
#
|
||||
# this is was ported from the 'gemma hoop animator' - unless you
|
||||
# don't like the preset animations or find a major bug, you don't need to
|
||||
# change anything here
|
||||
#
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
try:
|
||||
import urandom as random # for v1.0 API support
|
||||
except ImportError:
|
||||
import random
|
||||
from analogio import AnalogIn
|
||||
|
||||
# available actions
|
||||
ACT_NOP = 0x00 # all leds off, do nothing
|
||||
ACT_SIMPLE_RING = 0x01 # all leds on
|
||||
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
|
||||
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
|
||||
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
|
||||
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
|
||||
ACT_SPARKLING_RING = 0x20 # sparkling effect
|
||||
|
||||
numpix = 16 # total number of NeoPixels
|
||||
pixel_output = board.D0 # pin where NeoPixels are connected
|
||||
analog_input = board.A0 # needed to seed the random generator
|
||||
strip = neopixel.NeoPixel(pixel_output, numpix, brightness=.3, auto_write=False)
|
||||
|
||||
# available color generation methods
|
||||
COL_RANDOM = 0x40 # colors will be generated randomly
|
||||
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
|
||||
|
||||
# specifiyng the action list
|
||||
action_duration = 0 # the action's overall duration in milliseconds (be careful not
|
||||
# to use values > 2^16-1 - roughly one minute :-)
|
||||
|
||||
action_and_color_gen = 1 # the color generation method
|
||||
|
||||
action_step_duration = 2 # the duration of each action step rsp. the delay of the main
|
||||
# loop in milliseconds - thus, controls the action speed (be
|
||||
# careful not to use values > 2^16-1 - roughly one minute :-)
|
||||
|
||||
color_granularity = 3 # controls the increment of the R, G, and B portions of the
|
||||
# rsp. color. 1 means the increment is 0,1,2,3,..., 10 means
|
||||
# the increment is 0,10,20,... don't use values > 255, and note
|
||||
# that even values > 127 wouldn't make much sense...
|
||||
|
||||
color_interval = 4 # controls the speed of color changing independently from action
|
||||
|
||||
# general global variables
|
||||
color = 0
|
||||
color_timer = 0
|
||||
action_timer = 0
|
||||
action_step_timer = 0
|
||||
color_idx = 0
|
||||
curr_color_interval = 0
|
||||
curr_action_step_duration = 0
|
||||
curr_action_duration = 0
|
||||
curr_action = 0
|
||||
curr_color_gen = COL_RANDOM
|
||||
idx = 0
|
||||
offset = 0
|
||||
number_of_actions = 31
|
||||
curr_action_idx = 0
|
||||
curr_color_granularity = 1
|
||||
spectrum_part = 0
|
||||
|
||||
# defining the animation actions by simply initializing the array of actions
|
||||
# this array variable must be called theactionlist !!!
|
||||
#
|
||||
# valid actions are:
|
||||
# ACT_NOP simply do nothing and switch everything off
|
||||
# ACT_SIMPLE_RING all leds on
|
||||
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
||||
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
||||
# ACT_WHEEL_ACLK anti clockwise spinning wheel
|
||||
# ACT_WHEEL_CLKW clockwise spinning wheel
|
||||
# ACT_SPARKLING_RING sparkling effect
|
||||
#
|
||||
# valid color options are:
|
||||
# COL_RANDOM colors will be selected randomly, which might
|
||||
# be not very sufficient due to well known
|
||||
# limitations of the random generation algorithm
|
||||
# COL_SPECTRUM colors will be set as cyclic spectral wipe
|
||||
# R -> G -> B -> R -> G -> B -> R -> ...
|
||||
|
||||
# action action name & action step color color change
|
||||
# duration color generation method duration granularity interval
|
||||
theactionlist = [
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2, ACT_CYCLING_RING_CLKW | COL_RANDOM, 0.02, 1, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2, ACT_CYCLING_RING_ACLK | COL_RANDOM, 0.02, 1, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.25, 20, 0.020 ],
|
||||
[ 1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.50, 1, 0.020 ],
|
||||
[ .750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.075, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.100, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.125, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.150, 1, 0.050 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.175, 1, 0.100 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.200, 1, 0.200 ],
|
||||
[ .750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.225, 1, 0.250 ],
|
||||
[ 1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.250, 1, 0.350 ],
|
||||
[ 30, ACT_SIMPLE_RING | COL_SPECTRUM, 0.050, 1, 0.010 ],
|
||||
[ 2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.010, 1, 0.010 ],
|
||||
[ 2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.015, 1, 0.020 ],
|
||||
[ 2, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.025, 1, 0.030 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.050, 1, 0.040 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.075, 1, 0.040 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.100, 1, 0.050 ],
|
||||
[ .500, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.125, 1, 0.060 ],
|
||||
[ .500, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.125, 5, 0.050 ],
|
||||
[ 1, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.100, 10, 0.040 ],
|
||||
[ 1.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.075, 15, 0.030 ],
|
||||
[ 2, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.050, 20, 0.020 ],
|
||||
[ 2.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.025, 25, 0.010 ],
|
||||
[ 3, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.010, 30, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1 ],
|
||||
[ 5, ACT_NOP, 0, 0, 0 ]
|
||||
]
|
||||
|
||||
|
||||
def nextspectrumcolor():
|
||||
global spectrum_part, color_idx, curr_color_granularity, color
|
||||
|
||||
# spectral wipe from green to red
|
||||
if (spectrum_part == 2):
|
||||
color = (color_idx, 0, 255-color_idx)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
spectrum_part = 0
|
||||
color_idx = 0
|
||||
|
||||
# spectral wipe from blue to green
|
||||
elif (spectrum_part == 1):
|
||||
color = (0, 255 - color_idx, color_idx)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
spectrum_part = 2
|
||||
color_idx = 0
|
||||
|
||||
# spectral wipe from red to blue
|
||||
elif (spectrum_part == 0 ):
|
||||
color = (255 - color_idx, color_idx, 0)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
spectrum_part = 1
|
||||
color_idx = 0
|
||||
|
||||
def nextrandomcolor():
|
||||
global color
|
||||
|
||||
# granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
|
||||
# granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
|
||||
# granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
|
||||
random_red = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_red *= curr_color_granularity
|
||||
|
||||
random_green = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_green *= curr_color_granularity
|
||||
|
||||
random_blue = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_blue *= curr_color_granularity
|
||||
|
||||
color = (random_red, random_green, random_blue)
|
||||
|
||||
def nextcolor():
|
||||
# save some RAM for more animation actions
|
||||
if (curr_color_gen & COL_RANDOM):
|
||||
nextrandomcolor()
|
||||
else:
|
||||
nextspectrumcolor()
|
||||
|
||||
def setup():
|
||||
|
||||
# fingers corssed, the seeding makes sense to really get random colors...
|
||||
apin = AnalogIn(analog_input)
|
||||
random.seed(apin.value)
|
||||
apin.deinit()
|
||||
|
||||
# let's go!
|
||||
nextcolor()
|
||||
strip.write()
|
||||
|
||||
setup()
|
||||
|
||||
while True: # Loop forever...
|
||||
|
||||
# do we need to load the next action?
|
||||
if ( (time.monotonic() - action_timer) > curr_action_duration ):
|
||||
curr_action_duration = theactionlist[curr_action_idx][action_duration]
|
||||
curr_action = theactionlist[curr_action_idx][action_and_color_gen] & 0x3F
|
||||
curr_action_step_duration = theactionlist[curr_action_idx][action_step_duration]
|
||||
curr_color_gen = theactionlist[curr_action_idx][action_and_color_gen] & 0xC0
|
||||
curr_color_granularity = theactionlist[curr_action_idx][color_granularity]
|
||||
curr_color_interval = theactionlist[curr_action_idx][color_interval]
|
||||
curr_action_idx += 1
|
||||
|
||||
# take care to rotate the action list!
|
||||
curr_action_idx %= number_of_actions
|
||||
action_timer = time.monotonic()
|
||||
|
||||
# do we need to change to the next color?
|
||||
if ((time.monotonic() - color_timer) > curr_color_interval):
|
||||
nextcolor()
|
||||
color_timer = time.monotonic()
|
||||
|
||||
# do we need to step up the current action?
|
||||
if ((time.monotonic() - action_step_timer) > curr_action_step_duration):
|
||||
|
||||
if (curr_action):
|
||||
|
||||
if (curr_action == ACT_NOP):
|
||||
# rather trivial even tho this will be repeated as long as the
|
||||
# NOP continues - i could have prevented it from repeating
|
||||
# unnecessarily, but that would mean more code and less
|
||||
# space for more actions within the animation
|
||||
for i in range(0, numpix):
|
||||
strip[i] = (0,0,0)
|
||||
|
||||
elif (curr_action == ACT_SIMPLE_RING):
|
||||
# even more trivial - just set the new color, if there is one
|
||||
for i in range(0, numpix):
|
||||
strip[i] = color
|
||||
|
||||
elif ( curr_action == (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW)):
|
||||
# spin the ring clockwise or anti clockwise
|
||||
if (curr_action == ACT_CYCLING_RING_ACLK):
|
||||
idx += 1
|
||||
else:
|
||||
idx -= 1
|
||||
|
||||
# prevent overflows or underflows
|
||||
idx %= numpix
|
||||
|
||||
# set the new color, if there is one
|
||||
strip[idx] = color
|
||||
|
||||
elif (curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW):
|
||||
# switch on / off the appropriate pixels according to
|
||||
# the current offset
|
||||
for idx in range(0, numpix):
|
||||
if ( ((offset + idx) & 7 ) < 2 ):
|
||||
strip[idx] = color
|
||||
else:
|
||||
strip[idx] = (0,0,0)
|
||||
|
||||
# advance the offset and thus, spin the wheel
|
||||
if (curr_action == ACT_WHEEL_CLKW):
|
||||
offset += 1
|
||||
else:
|
||||
offset -= 1
|
||||
|
||||
# prevent overflows or underflows
|
||||
offset %= numpix
|
||||
|
||||
elif (curr_action == ACT_SPARKLING_RING):
|
||||
# switch current pixel off
|
||||
strip[idx] = (0,0,0)
|
||||
# pick a new pixel
|
||||
idx = random.randint(0, numpix)
|
||||
# set new pixel to the current color
|
||||
strip[idx] = color
|
||||
|
||||
strip.write()
|
||||
action_step_timer = time.monotonic()
|
||||
109
3D_Printed_NeoPixel_Ring_Hair_Dress/GemmaHoopActionList.h
Normal file
109
3D_Printed_NeoPixel_Ring_Hair_Dress/GemmaHoopActionList.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* this file is part of the gemma hoop animator example sketch
|
||||
*
|
||||
* it is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* it is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. see the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* you should have received a copy of the GNU Lesser General Public
|
||||
* License along with NeoPixel. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* use this file to set up your individual animation actions and
|
||||
* general settings and then simply recompile the sketch
|
||||
*
|
||||
* the number of actions possible is limited by the RAM of the used µC. shall
|
||||
* the list be too long, the µC will crash and nothing will go on.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* AND NOW HAVE FUN! :-)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _GEMMA_HOOP_ACTIONLIST_H_
|
||||
#define _GEMMA_HOOP_ACTIONLIST_H_
|
||||
|
||||
#include "GemmaHoopDefs.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* general settings
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define PIXEL_OUTPUT 0 // output pin the NeoPixels are connected to
|
||||
#define ANALOG_INPUT 0 // needed to seed the random generator
|
||||
#define NUM_PIXELS 16 // total number of NeoPixels
|
||||
#define BRIGHTNESS 30 // overall brightness of NeoPixels
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* defining the animation actions by simply initializing the array of actions
|
||||
* this array variable must be called theActionList !!!
|
||||
*
|
||||
* valid actions are:
|
||||
* ACT_NOP simply do nothing and switch everything off
|
||||
* ACT_SIMPLE_RING all leds on
|
||||
* ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
||||
* ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
||||
* ACT_WHEEL_ACLK anti clockwise spinning wheel
|
||||
* ACT_WHEEL_CLKW clockwise spinning wheel
|
||||
* ACT_SPARKLING_RING sparkling effect
|
||||
*
|
||||
* valid color options are:
|
||||
* COL_RANDOM colors will be selected randomly, which might
|
||||
* be not very sufficient due to well known
|
||||
* limitations of the random generation algorithm
|
||||
* COL_SPECTRUM colors will be set as cyclic spectral wipe
|
||||
* R -> G -> B -> R -> G -> B -> R -> ...
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
actionlist theActionList =
|
||||
{
|
||||
// action action name & action step color color change
|
||||
// duration color generation method duration granularity interval
|
||||
{ 5000, ACT_SPARKLING_RING | COL_RANDOM, 10, 25, 1000 },
|
||||
{ 2000, ACT_CYCLING_RING_CLKW | COL_RANDOM, 20, 1, 5 },
|
||||
{ 5000, ACT_SPARKLING_RING | COL_RANDOM, 10, 25, 1000 },
|
||||
{ 2000, ACT_CYCLING_RING_ACLK | COL_RANDOM, 20, 1, 5 },
|
||||
{ 5000, ACT_SPARKLING_RING | COL_RANDOM, 10, 25, 1000 },
|
||||
{ 2500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 25, 20, 20 },
|
||||
{ 1000, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 50, 1, 20 },
|
||||
{ 750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 75, 1, 20 },
|
||||
{ 500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 100, 1, 20 },
|
||||
{ 500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 125, 1, 20 },
|
||||
{ 500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 150, 1, 50 },
|
||||
{ 500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 175, 1, 100 },
|
||||
{ 500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 200, 1, 200 },
|
||||
{ 750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 225, 1, 250 },
|
||||
{ 1000, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 250, 1, 350 },
|
||||
{ 30000, ACT_SIMPLE_RING | COL_SPECTRUM, 50, 1, 10 },
|
||||
{ 2500, ACT_WHEEL_ACLK | COL_SPECTRUM, 10, 1, 10 },
|
||||
{ 2500, ACT_WHEEL_ACLK | COL_SPECTRUM, 15, 1, 20 },
|
||||
{ 2000, ACT_WHEEL_ACLK | COL_SPECTRUM, 25, 1, 30 },
|
||||
{ 1000, ACT_WHEEL_ACLK | COL_SPECTRUM, 50, 1, 40 },
|
||||
{ 1000, ACT_WHEEL_ACLK | COL_SPECTRUM, 75, 1, 40 },
|
||||
{ 1000, ACT_WHEEL_ACLK | COL_SPECTRUM, 100, 1, 50 },
|
||||
{ 500, ACT_WHEEL_ACLK | COL_SPECTRUM, 125, 1, 60 },
|
||||
{ 500, ACT_WHEEL_CLKW | COL_SPECTRUM, 125, 5, 50 },
|
||||
{ 1000, ACT_WHEEL_CLKW | COL_SPECTRUM, 100, 10, 40 },
|
||||
{ 1500, ACT_WHEEL_CLKW | COL_SPECTRUM, 75, 15, 30 },
|
||||
{ 2000, ACT_WHEEL_CLKW | COL_SPECTRUM, 50, 20, 20 },
|
||||
{ 2500, ACT_WHEEL_CLKW | COL_SPECTRUM, 25, 25, 10 },
|
||||
{ 3000, ACT_WHEEL_CLKW | COL_SPECTRUM, 10, 30, 5 },
|
||||
{ 5000, ACT_SPARKLING_RING | COL_RANDOM, 10, 25, 1000 },
|
||||
{ 5000, ACT_NOP, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#endif
|
||||
80
3D_Printed_NeoPixel_Ring_Hair_Dress/GemmaHoopDefs.h
Normal file
80
3D_Printed_NeoPixel_Ring_Hair_Dress/GemmaHoopDefs.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* this file is part of the gemma hoop animator example sketch
|
||||
*
|
||||
* it is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* it is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. see the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* you should have received a copy of the GNU Lesser General Public
|
||||
* License along with NeoPixel. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* these are the general definitions and declarations for the
|
||||
* gemma hoop animator - unless you don't like the preset animations or
|
||||
* find a major bug, you don't need to change anything here
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _GEMMA_HOOP_DEFS_H_
|
||||
#define _GEMMA_HOOP_DEFS_H_
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* available actions
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define ACT_NOP 0b00000000 // all leds off, do nothing
|
||||
#define ACT_SIMPLE_RING 0b00000001 // all leds on
|
||||
#define ACT_CYCLING_RING_ACLK 0b00000010 // anti clockwise cycling colors
|
||||
#define ACT_CYCLING_RING_CLKW 0b00000100 // clockwise cycling colors
|
||||
#define ACT_WHEEL_ACLK 0b00001000 // anti clockwise spinning wheel
|
||||
#define ACT_WHEEL_CLKW 0b00010000 // clockwise spinning wheel
|
||||
#define ACT_SPARKLING_RING 0b00100000 // sparkling effect
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* available color generation methods
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define COL_RANDOM 0b01000000 // colors will be generated randomly
|
||||
#define COL_SPECTRUM 0b10000000 // colors will be set as cyclic spectral wipe
|
||||
// R -> G -> B -> R -> ...
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* specifiyng the action list
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t action_duration; // the action's overall duration in milliseconds (be careful not
|
||||
// to use values > 2^16-1 - roughly one minute :-)
|
||||
uint8_t action_and_color_gen; // the color generation method
|
||||
uint16_t action_step_duration; // the duration of each action step rsp. the delay of the main
|
||||
// loop in milliseconds - thus, controls the action speed (be
|
||||
// careful not to use values > 2^16-1 - roughly one minute :-)
|
||||
uint8_t color_granularity; // controls the increment of the R, G, and B portions of the
|
||||
// rsp. color. 1 means the increment is 0,1,2,3,..., 10 means
|
||||
// the increment is 0,10,20,... don't use values > 255, and note
|
||||
// that even values > 127 wouldn't make much sense...
|
||||
uint16_t color_interval; // controls the speed of color changing independently from action
|
||||
// speed (be careful not to use values > 2^16-1 - roughly one minute :-)
|
||||
} actiondesc;
|
||||
|
||||
typedef actiondesc actionlist[]; // a simple array of actions that will be continously cycled through
|
||||
// by the sketch's main loop. the number of elemnts is limitted by
|
||||
// the size of RAM available on the rsp. µC
|
||||
#endif
|
||||
|
||||
5
3D_Printed_NeoPixel_Ring_Hair_Dress/README.md
Normal file
5
3D_Printed_NeoPixel_Ring_Hair_Dress/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# 3D_Printed_NeoPixel_Ring_Hair_Dress
|
||||
|
||||
Code to accompany this tutorial:
|
||||
|
||||
https://learn.adafruit.com/neopixel-ring-hair-dress
|
||||
Loading…
Reference in a new issue