|
@@ -0,0 +1,224 @@
|
|
|
+#include "Arduino.h"
|
|
|
+#include "Adafruit_NeoPixel.h"
|
|
|
+#include "BackgroundRingClass.h"
|
|
|
+#include "WS2812_Definitions.h"
|
|
|
+
|
|
|
+BackgroundRingClass::BackgroundRingClass(int led_count, int pin) : Adafruit_NeoPixel(led_count+1, pin, NEO_GRB + NEO_KHZ800) {
|
|
|
+ this->led_count = led_count;
|
|
|
+ this->action = Idle;
|
|
|
+ this->begin();
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick() {
|
|
|
+ switch(this->action) {
|
|
|
+ case Idle: this->tick_idle(); break;
|
|
|
+ case Solid: this->tick_solid(); break;
|
|
|
+ case Pulse: this->tick_pulse(); break;
|
|
|
+ case Spin: this->tick_spin(); break;
|
|
|
+ case Flip: this->tick_flip(); break;
|
|
|
+ case Slowroll: this->tick_slowroll(); break;
|
|
|
+ default: this->action = Idle;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Ring Functions */
|
|
|
+void BackgroundRingClass::setColor(unsigned long color, uint8_t brightness, bool show) {
|
|
|
+ this->setBrightness(brightness);
|
|
|
+ for(int i=0; i < this->led_count; i++) {
|
|
|
+ this->setPixelColor(i, color);
|
|
|
+ }
|
|
|
+ if(show) {
|
|
|
+ this->show();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::setRepeating(unsigned long* colors, int elements, int rotation) {
|
|
|
+ this->setBrightness(50);
|
|
|
+ int curcolor = 0;
|
|
|
+ for(int i = 0; i < this->led_count; i++) {
|
|
|
+ this->setPixelColor(i, colors[(i+rotation) % elements]);
|
|
|
+ }
|
|
|
+ this->show();
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////// Idle
|
|
|
+void BackgroundRingClass::init_idle() {
|
|
|
+ this->action = Idle;
|
|
|
+ this->setColor(BLACK, 255, true);
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_idle() {
|
|
|
+ // noop. Here for consistency
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+///////////////////////// Random
|
|
|
+int BackgroundRingClass::random_event(int copy) {
|
|
|
+ int draw = random(0, 480); // this lets us choose events with weighted probability
|
|
|
+ if(copy >= 0) { // we wish to copy the other one's action
|
|
|
+ draw = copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Christmas Colors
|
|
|
+ if(draw < 50) this->init_pulse(DARKRED, 80, 2000);
|
|
|
+ else if(draw < 100) this->init_pulse(DARKGREEN, 80, 2000);
|
|
|
+ else if(draw < 150) this->init_spin(DARKRED, DARKGREEN);
|
|
|
+ else if(draw < 200) this->init_spin(DARKGREEN, DARKRED);
|
|
|
+ else if(draw < 250) this->init_flip(DARKRED, DARKGREEN);
|
|
|
+ else if(draw < 300) this->init_flip(DARKGREEN, DARKRED);
|
|
|
+ else if(draw < 350) this->init_slowroll(DARKRED, DARKGREEN);
|
|
|
+ else if(draw < 400) this->init_slowroll(DARKGREEN, DARKRED);
|
|
|
+
|
|
|
+ // random colors
|
|
|
+ else if(draw < 410) this->init_pulse(random(0, 0xFFFFFF), 80, 2000);
|
|
|
+ else if(draw < 420) this->init_pulse(random(0, 0xFFFFFF), 80, 2000);
|
|
|
+ else if(draw < 430) this->init_spin(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+ else if(draw < 440) this->init_spin(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+ else if(draw < 450) this->init_flip(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+ else if(draw < 460) this->init_flip(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+ else if(draw < 470) this->init_slowroll(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+ else if(draw < 480) this->init_slowroll(random(0, 0xFFFFFF), random(0, 0xFFFFFF));
|
|
|
+
|
|
|
+ return draw;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+///////////////////////// Solid
|
|
|
+void BackgroundRingClass::init_solid(unsigned long color, uint8_t brightness) {
|
|
|
+ this->action = Solid;
|
|
|
+ this->setBrightness(brightness);
|
|
|
+ this->setColor(color);
|
|
|
+ this->show();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_solid() {
|
|
|
+ // noop. Here for consistency
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+///////////////////////// Pulse
|
|
|
+void BackgroundRingClass::init_pulse(unsigned long color, uint8_t maxbrightness, unsigned long ms) {
|
|
|
+ Serial.println("Initializing pulse");
|
|
|
+ this->action = Pulse;
|
|
|
+ this->pulseinfo.color = color;
|
|
|
+ this->pulseinfo.increasing = true;
|
|
|
+ this->pulseinfo.starttime = micros();
|
|
|
+ this->pulseinfo.steptime = (ms * 1000) / ((2 * (unsigned long)maxbrightness) - 1);
|
|
|
+ this->pulseinfo.maxbrightness = maxbrightness;;
|
|
|
+ this->pulseinfo.curbrightness = 1;
|
|
|
+
|
|
|
+ this->setColor(this->pulseinfo.color, brightness, true); // dimmest setting
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_pulse() {
|
|
|
+ if((micros() - this->pulseinfo.starttime) < this->pulseinfo.steptime) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this->pulseinfo.starttime = micros();
|
|
|
+ if(this->pulseinfo.increasing && this->pulseinfo.curbrightness == this->pulseinfo.maxbrightness) {
|
|
|
+ this->pulseinfo.increasing = false;
|
|
|
+ }
|
|
|
+ if(this->pulseinfo.increasing) {
|
|
|
+ this->pulseinfo.curbrightness++;
|
|
|
+ } else {
|
|
|
+ this->pulseinfo.curbrightness--;
|
|
|
+ }
|
|
|
+ if(this->pulseinfo.curbrightness == 0) {
|
|
|
+ // We are done
|
|
|
+ this->init_idle();
|
|
|
+ } else {
|
|
|
+ //Serial.print("Setting Brightness: "); Serial.println(this->pulseinfo.curbrightness);
|
|
|
+ this->setColor(this->pulseinfo.color, this->pulseinfo.curbrightness, true);
|
|
|
+ this->show();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////// Spin
|
|
|
+void BackgroundRingClass::init_spin(unsigned long color1, unsigned long color2, unsigned long ms, unsigned long tickdelay) {
|
|
|
+ this->action = Spin;
|
|
|
+ this->spininfo.color1 = color1;
|
|
|
+ this->spininfo.color2 = color2;
|
|
|
+ this->spininfo.ms = ms * 1000;
|
|
|
+ this->spininfo.tickdelay = tickdelay * 1000;
|
|
|
+ this->spininfo.starttime = micros();
|
|
|
+ this->spininfo.lasttick = micros() - this->spininfo.tickdelay;
|
|
|
+ this->spininfo.rotation = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_spin() {
|
|
|
+ if(micros() - this->spininfo.starttime > this->spininfo.ms) {
|
|
|
+ // we're done
|
|
|
+ Serial.println(micros() - this->spininfo.starttime);
|
|
|
+ this->init_idle();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(micros() - this->spininfo.lasttick > this->spininfo.tickdelay) {
|
|
|
+ // Time to spin
|
|
|
+ this->spininfo.lasttick = micros();
|
|
|
+ this->spininfo.rotation = (this->spininfo.rotation + 1) % 3;
|
|
|
+ //unsigned long tickcolors[] = { this->spininfo.color1, this->spininfo.color1, this->spininfo.color1, this->spininfo.color2 };
|
|
|
+ //unsigned long tickcolors[] = { BLACK, this->spininfo.color1, this->spininfo.color2 };
|
|
|
+ unsigned long tickcolors[] = { BLACK, this->spininfo.color1, this->spininfo.color1, this->spininfo.color2 };
|
|
|
+ this->setRepeating(tickcolors, 4, this->spininfo.rotation);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////// Flip
|
|
|
+void BackgroundRingClass::init_flip(unsigned long color1, unsigned long color2, unsigned long ms, unsigned long tickdelay) {
|
|
|
+ this->action = Flip;
|
|
|
+ this->flipinfo.color1 = color1;
|
|
|
+ this->flipinfo.color2 = color2;
|
|
|
+ this->flipinfo.ms = ms * 1000;
|
|
|
+ this->flipinfo.tickdelay = tickdelay * 1000;
|
|
|
+ this->flipinfo.starttime = micros();
|
|
|
+ this->flipinfo.lasttick = micros() - this->flipinfo.tickdelay;
|
|
|
+ this->flipinfo.flipper = false;
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_flip() {
|
|
|
+ if(micros() - this->flipinfo.starttime > this->flipinfo.ms) {
|
|
|
+ // we're done
|
|
|
+ Serial.println(micros() - this->flipinfo.starttime);
|
|
|
+ this->init_idle();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(micros() - this->flipinfo.lasttick > this->flipinfo.tickdelay) {
|
|
|
+ // Time to flip
|
|
|
+ this->flipinfo.lasttick = micros();
|
|
|
+ unsigned long tickcolors[] = { this->flipinfo.color1, this->flipinfo.color2 };
|
|
|
+ this->setRepeating(tickcolors, 2, (this->flipinfo.flipper ? 0 : 1));
|
|
|
+ this->flipinfo.flipper = not(this->flipinfo.flipper);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+///////////////////////// Slowroll
|
|
|
+void BackgroundRingClass::init_slowroll(unsigned long color1, unsigned long color2, unsigned long ms, unsigned long tickdelay) {
|
|
|
+ this->action = Slowroll;
|
|
|
+ this->slowrollinfo.color1 = color1;
|
|
|
+ this->slowrollinfo.color2 = color2;
|
|
|
+ this->slowrollinfo.ms = ms * 1000;
|
|
|
+ this->slowrollinfo.tickdelay = tickdelay * 1000;
|
|
|
+ this->slowrollinfo.starttime = micros();
|
|
|
+ this->slowrollinfo.lasttick = micros() - this->slowrollinfo.tickdelay;
|
|
|
+ this->slowrollinfo.flipper = false;
|
|
|
+}
|
|
|
+
|
|
|
+void BackgroundRingClass::tick_slowroll() {
|
|
|
+ if(micros() - this->slowrollinfo.starttime > this->slowrollinfo.ms) {
|
|
|
+ // we're done
|
|
|
+ Serial.println(micros() - this->slowrollinfo.starttime);
|
|
|
+ this->init_idle();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(micros() - this->slowrollinfo.lasttick > this->slowrollinfo.tickdelay) {
|
|
|
+ // Time to slowroll
|
|
|
+ this->slowrollinfo.lasttick = micros();
|
|
|
+ unsigned long tickcolors[] = { this->slowrollinfo.color1, this->slowrollinfo.color2, BLACK };
|
|
|
+ this->setRepeating(tickcolors, 3, (this->slowrollinfo.flipper ? 0 : 2));
|
|
|
+ this->slowrollinfo.flipper = not(this->slowrollinfo.flipper);
|
|
|
+ }
|
|
|
+}
|