Skip to content

Instantly share code, notes, and snippets.

@gdalgas
Created January 3, 2017 00:12
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 gdalgas/168f9e1fc1c966ddc4419da78694dba7 to your computer and use it in GitHub Desktop.
Save gdalgas/168f9e1fc1c966ddc4419da78694dba7 to your computer and use it in GitHub Desktop.
Christmas Tree Lights 2016
#include <IRremote.h>
#include "FastLED.h"
FASTLED_USING_NAMESPACE
// FastLED "100-lines-of-code" demo reel, showing just a few
// of the kinds of animation patterns you can quickly and easily
// compose using FastLED.
//
// This example also shows one easy way to define multiple
// animations patterns and have them automatically rotate.
//
// -Mark Kriegsman, December 2014a
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define DATA_PIN 10
//#define CLK_PIN 4
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 300
CRGB leds[NUM_LEDS];
int RECV_PIN = 11;
int RELAY = 4;
int LED_COUNT = 0;
bool LED_BLAST = false;
bool RELAY_STATE = false;
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 120
decode_results results;
IRrecv irrecv(RECV_PIN);
CRGBPalette16 currentPalette(CRGB::Black);
CRGBPalette16 targetPalette(OceanColors_p);
static uint16_t dist; // A random number for our noise generator.
uint16_t scale = 30; // Wouldn't recommend changing this on the fly, or the animation will be really blocky.
uint8_t maxChanges = 48; // Value for blending between palettes.
void setup() {
delay(3000); // 3 second delay for recovery
Serial.begin(9600);
Serial.println("setup");
// tell FastLED about the LED strip configuration
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
//FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
// set master brightness control
FastLED.setBrightness(0);
dist = random16(12345); // A semi-random number for our noise generator
irrecv.enableIRIn(); // Start the receiver
pinMode(RELAY, OUTPUT);
toggleRelay();
}
// List of patterns to cycle through. Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { prettysinewave, fillSolidPurpleWithGlitter, fillSolidGreenWithGlitter, fillSolidBlueWithGlitter, rainbowWithGlitter, confetti, sinelon, juggle, bpm };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
int incomingData = 0;
void loop()
{
if (Serial.available() > 0) {
if (!RELAY_STATE) {
toggleRelay();
}
incomingData = Serial.read();
Serial.print("I received: ");
Serial.println(incomingData, DEC);
if (incomingData > 48 && incomingData < 59) {
gCurrentPatternNumber = incomingData - 49;
}
}
if (irrecv.decode(&results)) {
dump(&results);
irrecv.resume(); // Receive the next value
}
// Call the current pattern function once, updating the 'leds' array
gPatterns[gCurrentPatternNumber]();
// send the 'leds' array out to the actual LED strip
FastLED.show();
// insert a delay to keep the framerate modest
FastLED.delay(1000/FRAMES_PER_SECOND);
// do some periodic updates
EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
// EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
EVERY_N_SECONDS(60 * 30) {
nextPattern();
toggleRelay();
}
}
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void dump(decode_results *results) {
//lightning();
if (!RELAY_STATE){
toggleRelay();
Serial.println("trigger");
}
nextPattern();
}
uint8_t flashes = 8; //the upper limit of flashes per strike
unsigned int dimmer = 1;
uint16_t ledstart; // Starting location of a flash
uint16_t ledlen; // Length of a flash
void toggleRelay() {
RELAY_STATE = !RELAY_STATE;
digitalWrite(RELAY, RELAY_STATE);
if (RELAY_STATE) {
FastLED.setBrightness(255);
} else {
FastLED.setBrightness(0);
}
}
void nextPattern()
{
FastLED.setBrightness(255);
// add one to the current pattern number, and wrap around at the end
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}
void fillSolidPurpleWithGlitter()
{
fill_solid(leds, NUM_LEDS, CRGB(0,102,204));
addGlitter(80);
}
void fillSolidGreenWithGlitter()
{
fill_solid(leds, NUM_LEDS, CRGB(255,0,0));
addGlitter(80);
}
void fillSolidBlueWithGlitter()
{
fill_solid(leds, NUM_LEDS, CRGB(0,0,255));
addGlitter(80);
}
void rainbow()
{
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, gHue, 7);
}
void rainbowWithGlitter()
{
// built-in FastLED rainbow, plus some random sparkly glitter
rainbow();
addGlitter(80);
}
void addGlitter( fract8 chanceOfGlitter)
{
if( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB::White;
}
}
void lightning() {
ledstart = 1; // Determine starting location of flash
ledlen = NUM_LEDS - 1; // Determine length of flash (not to go beyond NUM_LEDS-1)
for (int flashCounter = 0; flashCounter < random8(3,flashes); flashCounter++) {
if(flashCounter == 0) dimmer = 5; // the brightness of the leader is scaled down by a factor of 5
else dimmer = random8(1,3); // return strokes are brighter than the leader
fill_solid(leds+ledstart,ledlen,CHSV(255, 0, 255/dimmer));
FastLED.show(); // Show a section of LED's
delay(random8(4,10)); // each flash only lasts 4-10 milliseconds
fill_solid(leds+ledstart,ledlen,CHSV(255,0,0)); // Clear the section of LED's
FastLED.show();
if (flashCounter == 0) delay (150); // longer delay until next flash after the leader
delay(50+random8(100)); // shorter delay between strokes
}
}
void blast()
{
CRGB color = CRGB::Black;
if (!LED_BLAST) {
color = CRGB::White;
LED_BLAST != LED_BLAST;
}
leds[LED_COUNT] = color;
leds[LED_COUNT + 50] = color;
leds[LED_COUNT + 100] = color;
leds[LED_COUNT + 150] = color;
leds[LED_COUNT + 200] = color;
leds[LED_COUNT + 250] = color;
if (LED_COUNT < 10) {
LED_COUNT++;
} else {
LED_COUNT = 0;
}
}
void confetti()
{
// random colored speckles that blink in and fade smoothly
fadeToBlackBy( leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV( gHue + random8(64), 200, 255);
}
void sinelon()
{
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy( leds, NUM_LEDS, 20);
int pos = beatsin16(13,0,NUM_LEDS);
leds[pos] += CHSV( gHue, 255, 192);
}
void bpm()
{
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint8_t BeatsPerMinute = 70;
CRGBPalette16 palette = PartyColors_p;
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
for( int i = 0; i < NUM_LEDS; i++) { //9948
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
}
}
void juggle() {
// eight colored dots, weaving in and out of sync with each other
fadeToBlackBy( leds, NUM_LEDS, 20);
byte dothue = 0;
for( int i = 0; i < 8; i++) {
leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
void prettysinewave() {
EVERY_N_MILLISECONDS(10) {
nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); // Blend towards the target palette
fillnoise8(); // Update the LED array with noise at the new location
}
EVERY_N_SECONDS(5) { // Change the target palette to a random one every 5 seconds.
targetPalette = CRGBPalette16(CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 255, random8(128,255)), CHSV(random8(), 192, random8(128,255)), CHSV(random8(), 255, random8(128,255)));
}
}
void fillnoise8() {
for(int i = 0; i < NUM_LEDS; i++) { // Just ONE loop to fill up the LED array as all of the pixels change.
uint8_t index = inoise8(i*scale, dist+i*scale) % 255; // Get a value from the noise function. I'm using both x and y axis.
leds[i] = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
}
dist += beatsin8(10,1, 4); // Moving along the distance (that random number we started out with). Vary it a bit with a sine wave.
// In some sketches, I've used millis() instead of an incremented counter. Works a treat.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment