Explorar o código

Initial draft

Fred Damstra (Macbook 2015) hai 5 meses
achega
d06e76e6fd
Modificáronse 6 ficheiros con 579 adicións e 0 borrados
  1. 3 0
      .gitignore
  2. 194 0
      BackgroundRingClass.cpp
  3. 93 0
      BackgroundRingClass.h
  4. 2 0
      README.md
  5. 154 0
      WS2812_Definitions.h
  6. 133 0
      background_rings_demo.ino

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+tmp*
+*.swp
+*.bak

+ 194 - 0
BackgroundRingClass.cpp

@@ -0,0 +1,194 @@
+#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
+}
+
+
+
+///////////////////////// 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);
+  }
+}

+ 93 - 0
BackgroundRingClass.h

@@ -0,0 +1,93 @@
+#ifndef BackGroundRingClass_h
+#define BackGroundRingClass_h
+
+#include <SoftwareSerial.h>
+#include "Arduino.h"
+#include "Adafruit_NeoPixel.h"
+#include "WS2812_Definitions.h"
+
+typedef enum Action {
+  Idle,
+  Solid,
+  Pulse,
+  Spin,
+  Flip,
+  Slowroll
+};
+
+class BackgroundRingClass : public Adafruit_NeoPixel {
+  public:
+    int led_count;
+    Action action;
+    BackgroundRingClass(int ledcount, int pin);
+    void tick();
+
+    // Helper Functions
+    void setColor(unsigned long color, uint8_t brightness=255, bool show=false);
+    void setRepeating(unsigned long* colors, int elements, int rotation);
+
+    // Idle
+    void init_idle();
+    void tick_idle();
+
+    // Solid
+    void init_solid(unsigned long int color, uint8_t brightness);
+    void tick_solid();
+
+    // Pulse
+    struct {
+      bool increasing;
+      unsigned long color;
+      unsigned long starttime;
+      unsigned long steptime;
+      uint8_t maxbrightness;
+      uint8_t curbrightness;
+    } pulseinfo;
+
+    void init_pulse(unsigned long color, uint8_t maxbrightness, unsigned long ms);
+    void tick_pulse();
+
+    // Spin
+    struct {
+      unsigned long color1;
+      unsigned long color2;
+      unsigned long ms;
+      unsigned long tickdelay;
+      unsigned long starttime;
+      unsigned long lasttick;
+      int rotation;
+    } spininfo;
+
+    void init_spin(unsigned long color1, unsigned long color2, unsigned long ms=2000, unsigned long tickdelay=125);
+    void tick_spin();
+
+    // Flip
+    struct {
+      unsigned long color1;
+      unsigned long color2;
+      unsigned long ms;
+      unsigned long tickdelay;
+      unsigned long starttime;
+      unsigned long lasttick;
+      bool flipper;
+    } flipinfo;
+
+    void init_flip(unsigned long color1, unsigned long color2, unsigned long ms=5000, unsigned long tickdelay=500);
+    void tick_flip();
+
+    // Slowroll
+    struct {
+      unsigned long color1;
+      unsigned long color2;
+      unsigned long ms;
+      unsigned long tickdelay;
+      unsigned long starttime;
+      unsigned long lasttick;
+      bool flipper;
+    } slowrollinfo;
+
+    void init_slowroll(unsigned long color1, unsigned long color2, unsigned long ms=5000, unsigned long tickdelay=500);
+    void tick_slowroll();
+};
+
+#endif

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+A set of routines to do pretty things with a ring of lights, in a class.
+

+ 154 - 0
WS2812_Definitions.h

@@ -0,0 +1,154 @@
+/* 
+  Bunches of definitions for the WS2812 Breakout Board example code
+  
+*/ 
+
+// These are for the cascade function
+#define TOP_DOWN 0
+#define DOWN_TOP 1
+
+/* A world of colors to set your LED to
+  Standard HTML Color Codes sorted by Hex Value
+    to see the colors in action, check out:
+   http://www.w3schools.com/html/html_colorvalues.asp */
+   
+#define BLACK			0x000000
+#define NAVY			0x000080
+#define DARKBLUE		0x00008B
+#define MEDIUMBLUE		0x0000CD
+#define BLUE			0x0000FF
+#define DARKGREEN		0x006400
+#define GREEN			0x008000
+#define TEAL			0x008080
+#define DARKCYAN		0x008B8B
+#define DEEPSKYBLUE		0x00BFFF
+#define DARKTURQUOISE		0x00CED1
+#define MEDIUMSPRINGGREEN	0x00FA9A
+#define LIME			0x00FF00
+#define SPRINGGREEN		0x00FF7F
+#define AQUA			0x00FFFF
+#define CYAN			0x00FFFF
+#define MIDNIGHTBLUE		0x191970
+#define DODGERBLUE		0x1E90FF
+#define LIGHTSEAGREEN		0x20B2AA
+#define FORESTGREEN		0x228B22
+#define SEAGREEN		0x2E8B57
+#define DARKSLATEGRAY		0x2F4F4F
+#define LIMEGREEN		0x32CD32
+#define MEDIUMSEAGREEN		0x3CB371
+#define TURQUOISE		0x40E0D0
+#define ROYALBLUE		0x4169E1
+#define STEELBLUE		0x4682B4
+#define DARKSLATEBLUE		0x483D8B
+#define MEDIUMTURQUOISE		0x48D1CC
+#define INDIGO 			0x4B0082
+#define DARKOLIVEGREEN		0x556B2F
+#define CADETBLUE		0x5F9EA0
+#define CORNFLOWERBLUE		0x6495ED
+#define MEDIUMAQUAMARINE	0x66CDAA
+#define DIMGRAY			0x696969
+#define SLATEBLUE		0x6A5ACD
+#define OLIVEDRAB		0x6B8E23
+#define SLATEGRAY		0x708090
+#define LIGHTSLATEGRAY		0x778899
+#define MEDIUMSLATEBLUE		0x7B68EE
+#define LAWNGREEN		0x7CFC00
+#define CHARTREUSE		0x7FFF00
+#define AQUAMARINE		0x7FFFD4
+#define MAROON			0x800000
+#define PURPLE			0x800080
+#define OLIVE			0x808000
+#define GRAY			0x808080
+#define SKYBLUE			0x87CEEB
+#define LIGHTSKYBLUE		0x87CEFA
+#define BLUEVIOLET		0x8A2BE2
+#define DARKRED			0x8B0000
+#define DARKMAGENTA		0x8B008B
+#define SADDLEBROWN		0x8B4513
+#define DARKSEAGREEN		0x8FBC8F
+#define LIGHTGREEN		0x90EE90
+#define MEDIUMPURPLE		0x9370DB
+#define DARKVIOLET		0x9400D3
+#define PALEGREEN		0x98FB98
+#define DARKORCHID		0x9932CC
+#define YELLOWGREEN		0x9ACD32
+#define SIENNA			0xA0522D
+#define BROWN			0xA52A2A
+#define DARKGRAY		0xA9A9A9
+#define LIGHTBLUE		0xADD8E6
+#define GREENYELLOW		0xADFF2F
+#define PALETURQUOISE	        0xAFEEEE
+#define LIGHTSTEELBLUE		0xB0C4DE
+#define POWDERBLUE		0xB0E0E6
+#define FIREBRICK		0xB22222
+#define DARKGOLDENROD		0xB8860B
+#define MEDIUMORCHID		0xBA55D3
+#define ROSYBROWN		0xBC8F8F
+#define DARKKHAKI		0xBDB76B
+#define SILVER			0xC0C0C0
+#define MEDIUMVIOLETRED	        0xC71585
+#define INDIANRED 		0xCD5C5C
+#define PERU			0xCD853F
+#define CHOCOLATE		0xD2691E
+#define TAN			0xD2B48C
+#define LIGHTGRAY		0xD3D3D3
+#define THISTLE			0xD8BFD8
+#define ORCHID			0xDA70D6
+#define GOLDENROD		0xDAA520
+#define PALEVIOLETRED		0xDB7093
+#define CRIMSON			0xDC143C
+#define GAINSBORO		0xDCDCDC
+#define PLUM			0xDDA0DD
+#define BURLYWOOD		0xDEB887
+#define LIGHTCYAN		0xE0FFFF
+#define LAVENDER		0xE6E6FA
+#define DARKSALMON		0xE9967A
+#define VIOLET			0xEE82EE
+#define PALEGOLDENROD		0xEEE8AA
+#define LIGHTCORAL		0xF08080
+#define KHAKI			0xF0E68C
+#define ALICEBLUE		0xF0F8FF
+#define HONEYDEW		0xF0FFF0
+#define AZURE			0xF0FFFF
+#define SANDYBROWN		0xF4A460
+#define WHEAT			0xF5DEB3
+#define BEIGE			0xF5F5DC
+#define WHITESMOKE		0xF5F5F5
+#define MINTCREAM		0xF5FFFA
+#define GHOSTWHITE		0xF8F8FF
+#define SALMON			0xFA8072
+#define ANTIQUEWHITE		0xFAEBD7
+#define LINEN			0xFAF0E6
+#define LIGHTGOLDENRODYELLOW	0xFAFAD2
+#define OLDLACE			0xFDF5E6
+#define RED			0xFF0000
+#define FUCHSIA			0xFF00FF
+#define MAGENTA			0xFF00FF
+#define DEEPPINK		0xFF1493
+#define ORANGERED		0xFF4500
+#define TOMATO			0xFF6347
+#define HOTPINK			0xFF69B4
+#define CORAL			0xFF7F50
+#define DARKORANGE		0xFF8C00
+#define LIGHTSALMON		0xFFA07A
+#define ORANGE			0xFFA500
+#define LIGHTPINK		0xFFB6C1
+#define REGPINK			0xFFC0CB // "PINK" conflicts with builtin
+#define GOLD			0xFFD700
+#define PEACHPUFF		0xFFDAB9
+#define NAVAJOWHITE		0xFFDEAD
+#define MOCCASIN		0xFFE4B5
+#define BISQUE			0xFFE4C4
+#define MISTYROSE		0xFFE4E1
+#define BLANCHEDALMOND		0xFFEBCD
+#define PAPAYAWHIP		0xFFEFD5
+#define LAVENDERBLUSH		0xFFF0F5
+#define SEASHELL		0xFFF5EE
+#define CORNSILK		0xFFF8DC
+#define LEMONCHIFFON		0xFFFACD
+#define FLORALWHITE		0xFFFAF0
+#define SNOW			0xFFFAFA
+#define YELLOW			0xFFFF00
+#define LIGHTYELLOW		0xFFFFE0
+#define IVORY			0xFFFFF0
+#define WHITE			0xFFFFFF

+ 133 - 0
background_rings_demo.ino

@@ -0,0 +1,133 @@
+
+#include <SoftwareSerial.h>
+#include "WS2812_Definitions.h"
+#include <eRCaGuy_ButtonReader.h>
+#include "BackgroundRingClass.h"
+
+const int LED_COUNT = 24;
+const int MAXBRIGHTNESS = 80;
+
+const int leftFSRSimPin = A7;
+const int rightFSRSimPin = A0;
+
+/* Start Button */
+const int leftReadyButtonPin = 13;
+const int rightReadyButtonPin = 8;
+
+/* WS2812 Christmas Tree Setup:
+    Two strips of 6 LEDs connected to 5V and Ground, plus the signal pin
+*/
+const int ledPinRight = 12;
+const int ledPinLeft  = 11;
+
+const int randomPin = A5;
+
+BackgroundRingClass rightRing = BackgroundRingClass(LED_COUNT, ledPinRight);
+BackgroundRingClass leftRing  = BackgroundRingClass(LED_COUNT, ledPinLeft);
+
+eRCaGuy_ButtonReader leftReadyButton = eRCaGuy_ButtonReader(leftReadyButtonPin);
+eRCaGuy_ButtonReader rightReadyButton = eRCaGuy_ButtonReader(rightReadyButtonPin);
+eRCaGuy_ButtonReader leftFSRButton = eRCaGuy_ButtonReader(leftFSRSimPin);
+eRCaGuy_ButtonReader rightFSRButton = eRCaGuy_ButtonReader(rightFSRSimPin);
+
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200); // Serial used for logging
+
+  randomSeed(analogRead(randomPin));
+
+  /* WS2812 LED Setup */
+  //rightRing.begin();
+  //leftRing.begin();
+
+  pinMode(leftReadyButtonPin, INPUT_PULLUP);
+  pinMode(rightReadyButtonPin, INPUT_PULLUP);
+  pinMode(leftFSRSimPin, INPUT_PULLUP);
+  pinMode(rightFSRSimPin, INPUT_PULLUP);
+
+  Serial.println("Testing Solids");
+  rightRing.init_solid(DARKRED, MAXBRIGHTNESS);
+  leftRing.init_solid(DARKGREEN, MAXBRIGHTNESS);
+  delay(1000);
+  leftRing.init_idle();
+  rightRing.init_idle();
+  Serial.println("Begin.");
+}
+
+
+
+void loop() {
+  static bool button_released = true;
+
+  rightRing.tick();
+  leftRing.tick();
+  
+  if(button_pressed(rightFSRButton)) {
+    Serial.println("Right button pressed. Switching.");
+    //rightRing.init_pulse(random(0, 0xFFFFFF), 255, 2000);
+    //rightRing.init_pulse(DARKRED, MAXBRIGHTNESS, 2000);
+    //rightRing.init_spin(DARKRED, DARKGREEN);
+    rightRing.init_flip(DARKRED, DARKGREEN);
+    //rightRing.init_slowroll(DARKRED, DARKGREEN);
+  }
+
+  if(button_pressed(leftFSRButton)) {
+    Serial.println("Right button pressed. Switching.");
+    //leftRing.init_pulse(random(0, 0xFFFFFF), 255, 2000);
+    //leftRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
+    //leftRing.init_spin(DARKGREEN, DARKRED);
+    leftRing.init_flip(DARKGREEN, DARKRED);
+    //leftRing.init_slowroll(DARKGREEN, DARKRED);
+  }
+
+  //test_solids();
+  //test_pulses();
+  //test_random_pulses();
+}
+
+bool button_pressed(eRCaGuy_ButtonReader& button)
+{
+  int8_t buttonaction;
+  boolean buttonstate;
+
+  button.readButton(&buttonaction, &buttonstate);
+  return buttonaction == 1;
+}
+
+
+void test_pulses() {
+  if(rightRing.action == Idle) {
+    Serial.println("Changing right");
+    rightRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
+  }
+  if(leftRing.action == Idle) {
+    Serial.println("Changing left");
+    leftRing.init_pulse(DARKGREEN, MAXBRIGHTNESS, 2000);
+  }
+}
+
+void test_random_pulses() {
+  if(rightRing.action == Idle) {
+    Serial.println("Changing right");
+    rightRing.init_pulse(random(0, 0xFFFFFF), MAXBRIGHTNESS, 2000);
+  }
+  if(leftRing.action == Idle) {
+    Serial.println("Changing left");
+    leftRing.init_pulse(random(0, 0xFFFFFF), MAXBRIGHTNESS, 2000);
+  }
+}
+
+void test_random_solids() {
+  if(rightRing.action == Idle) {
+    Serial.println("Changing right");
+    rightRing.init_solid(random(0, 0xFFFFFF), MAXBRIGHTNESS);
+  }
+  if(leftRing.action == Idle) {
+    Serial.println("Changing left");
+    leftRing.init_solid(random(0, 0xFFFFFF), MAXBRIGHTNESS);
+  }
+  delay(500);
+  leftRing.init_idle();
+  rightRing.init_idle();
+}