|
new file 100644
|
|
|
#include <Adafruit_NeoPixel.h>
|
|
|
#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
|
|
|
#include <avr/power.h>
|
|
|
#endif
|
|
|
|
|
|
#define PIN 0
|
|
|
|
|
|
enum pattern {
|
|
|
RAINBOW_CYCLE,
|
|
|
COLOR_WIPE,
|
|
|
DOUBLE_COLOR_WIPE,
|
|
|
SCANNER,
|
|
|
DOUBLE_SCANNER,
|
|
|
RANDOM,
|
|
|
DOUBLE_RANDOM,
|
|
|
BLINK,
|
|
|
DOT
|
|
|
};
|
|
|
|
|
|
class NeoPatterns : public Adafruit_NeoPixel {
|
|
|
public:
|
|
|
pattern ActivePattern;
|
|
|
|
|
|
uint16_t Interval;
|
|
|
unsigned long lastUpdate;
|
|
|
uint32_t Color1;
|
|
|
uint16_t TotalSteps;
|
|
|
uint16_t Index;
|
|
|
|
|
|
void (*OnComplete)();
|
|
|
|
|
|
NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)()) : Adafruit_NeoPixel(pixels, pin, type) {
|
|
|
OnComplete = callback;
|
|
|
}
|
|
|
|
|
|
void Update() {
|
|
|
if ((millis() - lastUpdate) > Interval) {
|
|
|
lastUpdate = millis();
|
|
|
switch (ActivePattern) {
|
|
|
case RAINBOW_CYCLE:
|
|
|
RainbowCycleUpdate();
|
|
|
break;
|
|
|
case COLOR_WIPE:
|
|
|
ColorWipeUpdate();
|
|
|
break;
|
|
|
case DOUBLE_COLOR_WIPE:
|
|
|
DoubleColorWipeUpdate();
|
|
|
break;
|
|
|
case SCANNER:
|
|
|
ScannerUpdate();
|
|
|
break;
|
|
|
case DOUBLE_SCANNER:
|
|
|
DoubleScannerUpdate();
|
|
|
break;
|
|
|
case RANDOM:
|
|
|
RandomUpdate();
|
|
|
break;
|
|
|
case DOUBLE_RANDOM:
|
|
|
DoubleRandomUpdate();
|
|
|
break;
|
|
|
case BLINK:
|
|
|
BlinkUpdate();
|
|
|
break;
|
|
|
case DOT:
|
|
|
DotUpdate();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Increment() {
|
|
|
show();
|
|
|
Index++;
|
|
|
if (Index >= TotalSteps) {
|
|
|
Index = 0;
|
|
|
OnComplete();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void RainbowCycle(uint16_t interval) {
|
|
|
ActivePattern = RAINBOW_CYCLE;
|
|
|
Interval = interval;
|
|
|
TotalSteps = 255;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void RainbowCycleUpdate() {
|
|
|
for (int i = 0; i < numPixels(); i++) {
|
|
|
setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
|
|
|
}
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void ColorWipe(uint32_t color, uint16_t interval) {
|
|
|
ActivePattern = COLOR_WIPE;
|
|
|
Interval = interval;
|
|
|
TotalSteps = numPixels();
|
|
|
Color1 = color;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void ColorWipeUpdate() {
|
|
|
setPixelColor(Index, Color1);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void DoubleColorWipe(uint32_t color, uint16_t interval) {
|
|
|
ActivePattern = DOUBLE_COLOR_WIPE;
|
|
|
Interval = interval;
|
|
|
TotalSteps = numPixels() / 2;
|
|
|
Color1 = color;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void DoubleColorWipeUpdate() {
|
|
|
setPixelColor(Index, Color1);
|
|
|
setPixelColor(numPixels() - 1 - Index, Color1);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void Scanner(uint32_t color1, uint16_t interval) {
|
|
|
ActivePattern = SCANNER;
|
|
|
Interval = interval;
|
|
|
TotalSteps = (numPixels() - 1) * 2;
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void ScannerUpdate() {
|
|
|
for (int i = 0; i < numPixels(); i++) {
|
|
|
if (i == Index) {
|
|
|
setPixelColor(i, Color1);
|
|
|
}
|
|
|
else if (i == TotalSteps - Index) {
|
|
|
setPixelColor(i, Color1);
|
|
|
}
|
|
|
else {
|
|
|
setPixelColor(i, DimColor(getPixelColor(i)));
|
|
|
}
|
|
|
}
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void DoubleScanner(uint32_t color1, uint16_t interval) {
|
|
|
ActivePattern = DOUBLE_SCANNER;
|
|
|
Interval = interval;
|
|
|
TotalSteps = (numPixels() / 2);
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void DoubleScannerUpdate() {
|
|
|
for (int i = 0; i < numPixels() / 2; i++) {
|
|
|
if (i == Index) {
|
|
|
setPixelColor(i, Color1); // First Eye
|
|
|
setPixelColor(numPixels() - 1 - i, Color1); // Second Eye
|
|
|
}
|
|
|
else {
|
|
|
setPixelColor(i, DimColor(getPixelColor(i)));
|
|
|
setPixelColor(numPixels() - 1 - i, DimColor(getPixelColor(i)));
|
|
|
|
|
|
}
|
|
|
}
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void Random(uint32_t color1, uint16_t steps, uint16_t interval) {
|
|
|
ActivePattern = RANDOM;
|
|
|
Interval = interval;
|
|
|
TotalSteps = steps;
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void RandomUpdate() {
|
|
|
setPixelColor(random(numPixels()), Color1);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void DoubleRandom(uint32_t color1, uint16_t steps, uint16_t interval) {
|
|
|
ActivePattern = DOUBLE_RANDOM;
|
|
|
Interval = interval;
|
|
|
TotalSteps = steps;
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void DoubleRandomUpdate() {
|
|
|
int i = random(numPixels() / 2);
|
|
|
setPixelColor(i, Color1);
|
|
|
setPixelColor(numPixels() - 1 - i, Color1);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void Blink(uint32_t color1, uint16_t steps, uint16_t interval) {
|
|
|
ActivePattern = BLINK;
|
|
|
Interval = interval;
|
|
|
if (steps % 2 != 0) {
|
|
|
steps++;
|
|
|
}
|
|
|
TotalSteps = steps;
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void BlinkUpdate() {
|
|
|
uint32_t c;
|
|
|
if (Index % 2 == 0) {
|
|
|
c = Color1;
|
|
|
} else {
|
|
|
c = Color(0, 0, 0);
|
|
|
}
|
|
|
ColorSet(c);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
void Dot(uint32_t color1, uint16_t steps, uint16_t interval) {
|
|
|
ActivePattern = DOT;
|
|
|
Interval = interval;
|
|
|
TotalSteps = steps;
|
|
|
Color1 = color1;
|
|
|
Index = 0;
|
|
|
}
|
|
|
|
|
|
void DotUpdate() {
|
|
|
ColorSet(Color(0, 0, 0));
|
|
|
show();
|
|
|
setPixelColor(random(numPixels()), Color1);
|
|
|
Increment();
|
|
|
}
|
|
|
|
|
|
uint32_t DimColor(uint32_t color) {
|
|
|
return Color(((color >> 16) & 0xFF) >> 1, ((color >> 8) & 0xFF) >> 1, (color & 0xFF) >> 1);
|
|
|
}
|
|
|
|
|
|
uint32_t Wheel(byte WheelPos) {
|
|
|
WheelPos = 255 - WheelPos;
|
|
|
if (WheelPos < 85) {
|
|
|
return Color(255 - WheelPos * 3, 0, WheelPos * 3);
|
|
|
}
|
|
|
else if (WheelPos < 170) {
|
|
|
WheelPos -= 85;
|
|
|
return Color(0, WheelPos * 3, 255 - WheelPos * 3);
|
|
|
}
|
|
|
else {
|
|
|
WheelPos -= 170;
|
|
|
return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ColorSet(uint32_t color) {
|
|
|
for (int i = 0; i < numPixels(); i++) {
|
|
|
setPixelColor(i, color);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
void RingsComplete();
|
|
|
|
|
|
NeoPatterns Rings(32, PIN, NEO_GRB + NEO_KHZ800, &RingsComplete);
|
|
|
uint8_t mode = 0;
|
|
|
uint32_t prev_time;
|
|
|
|
|
|
void setup() {
|
|
|
#ifdef __AVR_ATtiny85__ // Trinket, Gemma, etc.
|
|
|
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
|
|
|
#endif
|
|
|
Rings.begin();
|
|
|
Rings.setBrightness(64);
|
|
|
Rings.RainbowCycle(random(1, 11));
|
|
|
prev_time = millis();
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
Rings.Update();
|
|
|
uint32_t t = millis();
|
|
|
if ((t - prev_time) >= 10000) {
|
|
|
mode = random(0, 9);
|
|
|
prev_time = t;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void RingsComplete()
|
|
|
{
|
|
|
uint16_t slow_interval = random(25, 56);
|
|
|
//uint16_t fast_interval = random(1, 11);
|
|
|
uint32_t color = Rings.Wheel(random(1, 256));
|
|
|
uint16_t steps = random(5, 11);
|
|
|
switch (mode) {
|
|
|
case 0:
|
|
|
Rings.RainbowCycle(random(1, 11));
|
|
|
break;
|
|
|
case 1:
|
|
|
Rings.ColorWipe(color, slow_interval);
|
|
|
break;
|
|
|
case 2:
|
|
|
Rings.DoubleColorWipe(color, slow_interval);
|
|
|
break;
|
|
|
case 3:
|
|
|
Rings.Scanner(color, slow_interval);
|
|
|
break;
|
|
|
case 4:
|
|
|
Rings.DoubleScanner(color, slow_interval);
|
|
|
break;
|
|
|
case 5:
|
|
|
Rings.Random(color, steps, slow_interval);
|
|
|
break;
|
|
|
case 6:
|
|
|
Rings.DoubleRandom(color, steps, slow_interval);
|
|
|
break;
|
|
|
case 7:
|
|
|
Rings.Blink(color, steps, random(250, 501));
|
|
|
break;
|
|
|
case 8:
|
|
|
Rings.Dot(color, steps, slow_interval);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|