Created
May 15, 2015 01:29
-
-
Save RichardBronosky/d50609fa4764460ba57b to your computer and use it in GitHub Desktop.
Decatur Makers Lanterns - designed for Decatur Arts Festival Lantern Parade
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Decatur Makers Lanterns | |
designed for Decatur Arts Festival Lantern Parade | |
May 16, 2015 Decatur, GA | |
Lantern Code beta | |
v 100 added eeprom address storage / retrieval | |
added paparozzi, firefly patterns | |
*/ | |
#include <SPI.h> | |
#include "nRF24L01.h" | |
#include "RF24.h" | |
#include <Adafruit_NeoPixel.h> | |
#include <avr/power.h> | |
#include <EEPROM.h> | |
//#include "printf.h" | |
#define PIN 6 | |
#define MSG_ADDR msg[0] | |
#define MSG_UNUSED01 msg[1] | |
#define MSG_CMD msg[2] | |
#define MSG_MOD1 msg[3] | |
#define MSG_MOD2 msg[4] | |
#define MSG_MOD3 msg[5] | |
#define MSG_MOD4 msg[6] | |
#define MSG_MOD5 msg[7] | |
#define MSG_MOD6 msg[8] | |
#define MSG_MOD7 msg[9] | |
#define MSG_MOD8 msg[10] | |
#define MSG_UNUSED06 msg[11] | |
#define MSG_UNUSED07 msg[12] | |
#define MSG_UNUSED08 msg[13] | |
#define MSG_LED1R msg[14] | |
#define MSG_LED1G msg[15] | |
#define MSG_LED1B msg[16] | |
#define MSG_UNUSED12 msg[17] | |
#define MSG_UNUSED13 msg[18] | |
#define MSG_LED2R msg[19] | |
#define MSG_LED2G msg[20] | |
#define MSG_LED2B msg[21] | |
#define MSG_UNUSED17 msg[22] | |
#define MSG_UNUSED18 msg[23] | |
#define MSG_LED3R msg[24] | |
#define MSG_LED3G msg[25] | |
#define MSG_LED3B msg[26] | |
#define MSG_UNUSED22 msg[27] | |
#define MSG_UNUSED23 msg[28] | |
#define MSG_LED4R msg[29] | |
#define MSG_LED4G msg[30] | |
#define MSG_LED4B msg[31] | |
#define DEFAULT_MODE 9 | |
#define BLACK 0 | |
#define RED 0xFF0000 | |
#define GREEN 0x00FF00 | |
#define BLUE 0x0000FF | |
#define YELLOW 0xFFF000 | |
#define PURPLE 0xFF00F0 | |
#define WHITE 0xFFFFFF | |
uint32_t colors[8]; | |
// Parameter 1 = number of pixels in strip | |
// Parameter 2 = Arduino pin number (most are valid) | |
// Parameter 3 = pixel type flags, add together as needed: | |
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) | |
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) | |
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) | |
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, PIN, NEO_GRB + NEO_KHZ800); | |
byte msg[32]; | |
//byte pattern = 1; | |
byte mode = DEFAULT_MODE; | |
byte rate = 10; | |
const byte EEPROM_ADDR = 4; | |
byte addr = 0; | |
unsigned int red; | |
unsigned int green; | |
unsigned int blue; | |
unsigned long timeout; | |
const uint64_t pipe = 0xE8E8F0F0E1LL; | |
RF24 radio(9,10); | |
void setup(void){ | |
Serial.begin(9600); | |
while (!Serial) { | |
; // wait for serial port to connect. Needed for Leonardo only | |
} | |
radio.begin(); | |
radio.setAutoAck(0); | |
radio.openReadingPipe(1,pipe); | |
radio.startListening(); | |
strip.begin(); | |
// strip.setPixelColor(0, strip.Color(255,0,0)); | |
// strip.setPixelColor(1, strip.Color(0,255,0)); | |
// strip.setPixelColor(2, strip.Color(0,0,255)); | |
// strip.setPixelColor(3, strip.Color(0,255,255)); | |
// strip.show(); | |
colors[0] = BLACK; | |
colors[1] = WHITE; | |
colors[2] = RED; | |
colors[3] = GREEN; | |
colors[4] = BLUE; | |
colors[5] = YELLOW; | |
colors[6] = PURPLE; | |
timeout = millis() + 10000; | |
set_addr(); | |
} | |
void loop(void){ | |
bool done; | |
byte n; // mount loop counter | |
byte i; // internal counter 1 (usually pixel number 0-3) | |
byte j; // internal counter 2 (usually for color, logic, etc.) | |
bool b[64]; // bitmap for all pixels in all lanterns | |
while(1){ | |
done = false; | |
switch (mode){ | |
case 0: // display r, g and b from master | |
while(!done){ | |
red = msg[14]; | |
green = msg[15]; | |
blue = msg[16]; | |
for(i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(rate); | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
} | |
break; | |
case 1: // colored ball rotating around circle | |
n = (addr-1) * 16; | |
while (!done){ | |
if (n<16){ | |
strip.setPixelColor(0, strip.Color(255,0,0)); | |
strip.setPixelColor(1, strip.Color(255,0,0)); | |
strip.setPixelColor(2, strip.Color(255,0,0)); | |
strip.setPixelColor(3, strip.Color(255,0,0)); | |
strip.show(); | |
} | |
else | |
{ | |
strip.setPixelColor(0, strip.Color(0,0,255)); | |
strip.setPixelColor(1, strip.Color(0,0,255)); | |
strip.setPixelColor(2, strip.Color(0,0,255)); | |
strip.setPixelColor(3, strip.Color(0,0,255)); | |
strip.show(); | |
} | |
n++; | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
delay(rate); | |
} | |
break; | |
case 2: // rainbow of colors rotating around circle | |
n = (addr-1) * 16; | |
while (!done){ | |
for(i=0; i< strip.numPixels(); i++) { | |
strip.setPixelColor(i, Wheel((64 + n) & 255)); | |
} | |
strip.show(); | |
delay(rate); | |
n++; | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
delay(rate); | |
} | |
break; | |
case 3: // paparozzi | |
randomSeed(addr); //every lantern gets the same random number | |
while(!done){ | |
if(random(1,17) == addr){ //the random number matches exactly 1 lantern each time | |
for(i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(255, 255, 255)); } | |
strip.show(); | |
} | |
delay(50); // short wait independant of rate because it is a strobe | |
for(i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(0, 0, 0)); } | |
strip.show(); | |
delay(rate*5); | |
if(check_radio()){done = process_msg();} | |
if(millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
delay(rate); | |
} | |
break; | |
case 4: // fire flies | |
randomSeed(addr); //every lantern gets the same random number | |
n = (addr-1) * 4; | |
while(!done){ | |
if(random(1,17) == addr){ //the random number matches exactly 1 lantern each time | |
if(n<128){ | |
red = 0; | |
green = 255 * n/128; | |
blue = 32 * n/128; | |
}else{ | |
red = 0; | |
green = 255 * (256-n)/128; | |
blue = 32 * (256-n)/128; | |
} | |
}else{ | |
red = 0; | |
green = 0; | |
blue = 0; | |
} | |
for(i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(rate); // wait longer so they don't all blend together | |
if(check_radio()){done = process_msg();} | |
if(millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
n++; | |
if(n == 0){ | |
i = random(1,17); | |
} | |
} | |
break; | |
case 5: // in - out travelling color | |
i = 1; | |
n = addr-1; | |
strip.setPixelColor(0, strip.Color(0, 0, 255)); | |
strip.setPixelColor(2, strip.Color(0, 0, 255)); | |
while(!done){ | |
if (i == 1){ | |
if ((n%3) == 0){ | |
strip.setPixelColor(1, strip.Color(0,0,0)); | |
} | |
else | |
{ | |
strip.setPixelColor(1, strip.Color(255, 0, 0)); | |
} | |
i=3; | |
} | |
if (i == 3){ | |
if (((15-n)%3) == 0){ | |
strip.setPixelColor(3, strip.Color(0,0,0)); | |
} | |
else | |
{ | |
strip.setPixelColor(3, strip.Color(0, 255, 0)); | |
} | |
i=1; | |
} | |
strip.show(); | |
delay(rate); | |
if(check_radio()){done = process_msg();} | |
if(millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
n++; | |
if (n>15) n=0; | |
} | |
break; | |
case 6: // each led random color | |
n = (addr-1) * 16; | |
randomSeed(addr); | |
while (!done){ | |
for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(random(1,255))); } | |
strip.show(); | |
delay(rate); | |
n++; | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
delay(rate); | |
} | |
break; | |
case 7: // each lantern random color | |
n = (addr-1) * 16; | |
randomSeed(addr); | |
while (!done){ | |
uint32_t c = Wheel(random(1,255)); | |
for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, c); } | |
strip.show(); | |
delay(rate); | |
n++; | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
delay(rate); | |
} | |
break; | |
case 8: // wipe colors around the loop | |
n=0; | |
j=0; | |
while (!done){ | |
uint32_t c = colors[j]; | |
for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, c); } | |
strip.show(); | |
delay(rate); | |
if (n == addr) j++; | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
if (j>6) j=0; | |
n++; | |
if (n>16) n=1; | |
} | |
break; | |
case 9: // pixel disolve | |
n=0; | |
j=0; | |
randomSeed(0); | |
i = random(0,64); | |
while (!done){ | |
if(n==0){ | |
for(int k=0; k<64; k++){ | |
b[k] = 0; | |
} | |
} | |
uint32_t c = colors[j]; | |
while(b[i] == 1){ | |
i = random(0,64); | |
} | |
b[i] = 1; | |
Serial.print("i: "); | |
Serial.println(i); | |
if(i >= (addr-1)*4 && i < addr*4){ // i is in this LED | |
Serial.print("p: "); | |
Serial.println(i-(addr-1)*4); | |
strip.setPixelColor(i-(addr-1)*4, c); | |
strip.show(); | |
n++; | |
} | |
delay(rate); | |
if(check_radio()){done = process_msg();} | |
if (millis() > timeout){ | |
timeout = millis()+60000; | |
mode = DEFAULT_MODE; | |
done = true; | |
} | |
n++; | |
if (n>=64){ | |
n=0; | |
j++; | |
if (j>6) j=0; | |
} | |
} | |
break; | |
default: | |
mode = DEFAULT_MODE; | |
} | |
} | |
} | |
// Fill the dots one after the other with a color | |
void colorWipe(uint32_t c, uint8_t wait) { | |
for(uint16_t i=0; i<strip.numPixels(); i++) { | |
strip.setPixelColor(i, c); | |
strip.show(); | |
delay(wait); | |
} | |
} | |
void rainbow(uint8_t wait) { | |
uint16_t i, j; | |
for(j=0; j<256; j++) { | |
for(i=0; i<strip.numPixels(); i++) { | |
strip.setPixelColor(i, Wheel((i+j) & 255)); | |
} | |
strip.show(); | |
delay(wait); | |
} | |
} | |
// Slightly different, this makes the rainbow equally distributed throughout | |
void rainbowCycle(uint8_t wait) { | |
uint16_t i, j; | |
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel | |
for(i=0; i< strip.numPixels(); i++) { | |
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); | |
} | |
strip.show(); | |
delay(wait); | |
} | |
} | |
//Theatre-style crawling lights. | |
void theaterChase(uint32_t c, uint8_t wait) { | |
for (int j=0; j<10; j++) { //do 10 cycles of chasing | |
for (int q=0; q < 3; q++) { | |
for (int i=0; i < strip.numPixels(); i=i+3) { | |
strip.setPixelColor(i+q, c); //turn every third pixel on | |
} | |
strip.show(); | |
delay(wait); | |
for (int i=0; i < strip.numPixels(); i=i+3) { | |
strip.setPixelColor(i+q, 0); //turn every third pixel off | |
} | |
} | |
} | |
} | |
//Theatre-style crawling lights with rainbow effect | |
void theaterChaseRainbow(uint8_t wait) { | |
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel | |
for (int q=0; q < 3; q++) { | |
for (int i=0; i < strip.numPixels(); i=i+3) { | |
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on | |
} | |
strip.show(); | |
delay(wait); | |
for (int i=0; i < strip.numPixels(); i=i+3) { | |
strip.setPixelColor(i+q, 0); //turn every third pixel off | |
} | |
} | |
} | |
} | |
// Input a value 0 to 255 to get a color value. | |
// The colours are a transition r - g - b - back to r. | |
uint32_t Wheel(byte WheelPos) { | |
WheelPos = 255 - WheelPos; | |
if(WheelPos < 85) { | |
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); | |
} else if(WheelPos < 170) { | |
WheelPos -= 85; | |
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); | |
} else { | |
WheelPos -= 170; | |
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); | |
} | |
} | |
bool check_radio(void){ | |
if (radio.available()){ | |
timeout = millis() + 10000; | |
if (MSG_ADDR == 0){ | |
return true; | |
} | |
else if (MSG_ADDR == addr){ | |
return true; | |
} else { return false; } | |
} | |
else { return false; } | |
} | |
bool process_msg(void){ | |
radio.read(msg, 32); | |
// mode = MSG_MOD1; | |
rate = MSG_MOD2; | |
red = MSG_MOD3; | |
green= MSG_MOD4; | |
blue = MSG_MOD5; | |
switch (MSG_CMD){ | |
case 'P': // set mode number to new pattern number | |
if (MSG_MOD1 != mode){ // new pattern | |
mode = MSG_MOD1; | |
return true; | |
}else{ return false; } | |
break; | |
case 'D': // enter demo mode | |
if (MSG_MOD1 != mode){ // new pattern | |
mode = MSG_MOD1; | |
return true; | |
} else{ return false; } | |
break; | |
default: | |
return false; | |
} | |
} | |
void set_addr(void){ | |
addr = EEPROM.read(0); | |
if (addr == EEPROM_ADDR){ | |
red=0; | |
blue=0; | |
for(int n=0; n<addr; n++){ // blink green addr times to confirm address | |
green=255; | |
for(int i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(250); | |
green=0; | |
for(int i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(400); | |
} | |
} else { | |
EEPROM.write(0, EEPROM_ADDR); | |
red=255; | |
green=0; | |
// blue=0; | |
for(int n=0; n<addr; n++){ // blink red addr times to confirm address | |
red = 255; | |
for(int i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(250); | |
red=0; | |
for(int i=0; i<4; i++){ strip.setPixelColor(i, strip.Color(red, green, blue)); } | |
strip.show(); | |
delay(400); | |
} | |
} | |
} | |
void setLantern(uint32_t c){ | |
for(uint16_t n=0; n < strip.numPixels(); n++){ | |
setLED(n, c); | |
} | |
} | |
void setLantern(uint8_t r, uint8_t g, uint8_t b){ | |
setLantern(strip.Color(r, g, b)); | |
} | |
void setLED(uint16_t n, uint32_t c){ | |
strip.setPixelColor(n, c); | |
if(n == strip.numPixels()-1){ | |
strip.show(); | |
} | |
} | |
void setLED(uint16_t n, uint8_t r, uint8_t g, uint8_t b){ | |
setLED(n, strip.Color(r, g, b)); | |
} | |
// eof |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment