Source

Gameshow / jacket.ino

#include "Adafruit_FloraPixel.h"
#include "sprite.h"

/*****************************************************************************
Example sketch for driving Adafruit Flora pixels
Connect the pixel(s) to Digital 6 (low right hand) or D7 on a teensy
*****************************************************************************/

// Set the first variable to the NUMBER of pixels. 25 = 25 pixels in a row
#define NUM_PIXELS 16
Adafruit_FloraPixel strip = Adafruit_FloraPixel(NUM_PIXELS);
RGBPixel frame[NUM_PIXELS];

void setup() {
    
  strip.begin();

  // Update the strip, to start they are all 'off'
  strip.show();
}

static RGBPixel colors[] = {
	{ 0, 0, 255 }, // red
	{ 0, 255, 0 }, // blue
	{ 80, 0, 255 },  // orange
	{ 0, 255, 90 },  // teal
	{ 200, 90, 90 },  // aqua
};

#define NUM_COLORS (sizeof(colors)/sizeof(*colors))


static sprite_t sprites[] = {
  { 0, 1, { 80, 0, 255 } },
  //{ NUM_PIXELS, -1, { 0, 255, 0 } },
  //{ 0, 5, { 255, 0, 255 } },
  //{ 8, -3, { 128, 128, 128 } },
};

static void
avg_color(
	int x,
	int r,
	int g,
	int b
)
{
	if (x < 0 || x >= NUM_PIXELS)
		return;
	RGBPixel * const p = &frame[x];

	r = (p->red + r) / 2;
	g = (p->green + g) / 2;
	b = (p->blue + b) / 2;

	if (r < 0) r = 0; else if (r > 0xFF) r = 0xFF;
	if (g < 0) g = 0; else if (g > 0xFF) g = 0xFF;
	if (b < 0) b = 0; else if (b > 0xFF) b = 0xFF;

	p->red = r;
	p->green = g;
	p->blue = b;
}


void sparkle(int chance)
{
	if (random(chance) != 0)
		return;
	int x = random(NUM_PIXELS);
	avg_color(x, 255, 255, 255);
}


void draw_wave(sprite_t *s)
{
    const int num = NUM_PIXELS;

    uint8_t r = s->c.red;
    uint8_t g = s->c.blue;
    uint8_t b = s->c.green;

#if 0
    for (int i = 0 ; i < 8; i++)
    {
       int x = s->pos;
       if (s->vel > 0)
         x -= i;
       else
         x += i;
         
       avg_color(x, r, g, b);
       r = (r * (uint16_t) 3) / 4;
       g = (g * (uint16_t) 3) / 4;
       b = (b * (uint16_t) 3) / 4;
    }
#else
	avg_color(s->pos, r, g, b);
#endif

    s->pos += s->vel;
    
    if (s->pos > num + 1)
    {
        s->pos = num - 1;
        s->vel = -s->vel;
    } else
    if (s->pos < -1)
    {
        s->pos = 0;
        s->vel = -s->vel;
    } else
	return;

    // Change the colors infrequently when we are off screen
    if (random(20) == 0)
	s->c = colors[random(NUM_COLORS)];
}


static void pulse(void)
{
	static int pos;

	for (int i=0; i < NUM_PIXELS ; i++)
		avg_color(i, 0, 10, 0);

	// occasionally pulse everything red
	if (random(NUM_PIXELS) == 0)
		for (int i = 0 ; i < NUM_PIXELS ; i++)
			avg_color(i, 80, 100, 0);
	// chase a single pixel around
	avg_color(pos, 10, 1000, 0);
	pos++;
	if (pos >= NUM_PIXELS)
		pos = 0;
}


void loop() {
    if (0)
    {
	    for (int i=0; i < NUM_PIXELS ; i++)
		avg_color(i, 0, 0, 0);

	    for (int i=0 ; i < sizeof(sprites)/sizeof(*sprites) ; i++)
	      draw_wave(&sprites[i]);
    } else {
	pulse();
    }

    sparkle(NUM_PIXELS/2);

    for (int i=0; i < NUM_PIXELS; i++)
      strip.setPixelColor(i, frame[i]);

    strip.show();   // write all the pixels out
    delay(80);

}

void rainbow(uint8_t wait) {
  int i, j;
   
  for (j=0; j < 256; j++) {     // 3 cycles of all 256 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel( (i + j) % 255));
    }  
    strip.show();   // write all the pixels out
    delay(wait);
  }
}

// Slightly different, this one makes the rainbow wheel equally distributed 
// along the chain
void rainbowCycle(uint8_t wait) {
  int i, j;
  
  for (j=0; j < 256 * 5; j++) {     // 5 cycles of all 25 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      // tricky math! we use each pixel as a fraction of the full 96-color wheel
      // (thats the i / strip.numPixels() part)
      // Then add in j which makes the colors go around per pixel
      // the % 96 is to make the wheel cycle around
      strip.setPixelColor(i, Wheel( ((i * 256 / strip.numPixels()) + j) % 256) );
    }  
    strip.show();   // write all the pixels out
    delay(wait);
  }
}

// fill the dots one after the other with said color
// good for testing purposes
void colorWipe(RGBPixel c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

/* Helper functions */

// Create a 24 bit color value from R,G,B
RGBPixel Color(byte r, byte g, byte b)
{
  RGBPixel p;
  
  p.red = r;
  p.green = g;
  p.blue = b;
  
  return p;
}

//Input a value 0 to 255 to get a color value.
//The colours are a transition r - g -b - back to r
RGBPixel Wheel(byte WheelPos)
{
  if (WheelPos < 85) {
   return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
   WheelPos -= 85;
   return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170; 
   return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}