Skip to content

Instantly share code, notes, and snippets.

@RichardBronosky
Created May 15, 2015 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RichardBronosky/d50609fa4764460ba57b to your computer and use it in GitHub Desktop.
Save RichardBronosky/d50609fa4764460ba57b to your computer and use it in GitHub Desktop.
Decatur Makers Lanterns - designed for Decatur Arts Festival Lantern Parade
/*
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