4: Getting the sample code

The code uses the FastLED library, which can be added to the IDE through the Library Manager. Depending on the version of the IDE you use, it may look a little different, but on a Mac, it looks like this:

A search for FastLED should turn up the library we need, and clicking “Install” makes it ready to use. After this, we can create a new sketch (the Arduino IDE name for a program) with the original code and change it to what we want! The original code is at the bottom of this page.

Original code:

#include <FastLED.h>

// LCDS LED Widget starter code, June 2019
// 
// bdodds at gmail dot com
//
// Read through the comments below and play around and have fun!


// *********************************************************
// First we set up things for the FastLED library to work
// These shouldn't be messed with: 

FASTLED_USING_NAMESPACE

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    7
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    20
CRGB leds[NUM_LEDS];
// *********************************************************


// *********************************************************
// Now we can start playing
//
// Change the brightness of the LEDs here: 
// 
#define BRIGHTNESS         75
//
// The number is from 0 to 100 and it is the percentage duty cycle,
// or how long the lights are on in any given time so if the number 
// is 50, the LEDs will flash on as much as they are off.  LEDs are 
// different than normal bulbs in that they operate best at the full
// power they can take, so instead of using a dimming method that 
// lowers the voltage, it flashes the LEDs very quickly, quicker 
// than humans can see.  The more time the LEDs are on, the brighter
// they appear.  A brightness of 50 means they are on as much as they
// are off, and so on.  


// This controls the overall speed of the animations, and is set at 
// what I determined to be optimal, but feel free to play with it.  
// It's originally set to 120:
#define FRAMES_PER_SECOND  120


// Now we have functions.  Functions are groups of commands that are
// grouped together to do a more complex task. The first function is the 
// setup() function that runs once when the board is first powered on.
// It's unlikely you'll want to change anything in here:

void setup() {
  delay(300); // 300 millisecond delay for recovery  
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}

// Now we set some variables for our functions to use later.
// First up is a list of patterns to cycle through.  Each of the patterns
// is defined as a separate function below. Change the ordr of these
// patterns to change the order they run through on the board.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { LCDS, rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, cylon, fire };

// Index number of which pattern is current
uint8_t gCurrentPatternNumber = 0; 
// rotating "base color" used by many of the patterns
uint8_t gHue = 0; 
  

// This next function is the main function that runs on the board.  This will loop
// indefinitely until the board is powered off.  
void loop()
{

  // This calls the function that runs through all of the patterns defined
  // above.  Comment out this line (put a // in front) if you don't want
  // the patterns to cycle through:
  gPatterns[gCurrentPatternNumber]();

  // These are the individual patterns called by each function.  Uncomment 
  // them to display just that one pattern, assuming the above line is 
  // commented out.
  
  //LCDS();
  //rainbow();
  //rainbowWithGlitter();
  //confetti();
  //juggle();
  //sinelon();
  //bpm();
  //cylon();
  //fire();

  // 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); 

  // slowly cycle the "base color" through the rainbow
  EVERY_N_MILLISECONDS( 20 ) { gHue++; } 
  // change patterns periodically, change the number to make the patterns cycle
  // at a different rate
  EVERY_N_SECONDS( 10 ) { nextPattern(); } 
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

// This function shows the new LCDS logo colors on the letters:
void LCDS()
{
  static uint8_t hue = 0;
  int colors[] = {160,120,90,30};
  int index=0;
  int fade = 380;
  // Spell out LCDS, start with the L:
  for( int i = 0; i < 5; i++) { 
    leds[i] = CHSV(colors[index % 4], 255, 255);
  }
  index++;
  FastLED.show();
  delay(100);
  fadeToBlackBy(leds, NUM_LEDS, fade);
  // Spell the C:
  for( int i = 5; i < 10; i++) { 
    leds[i] = CHSV(colors[index % 4], 255, 255);
  }
  index++;
  FastLED.show();
  delay(100);
  fadeToBlackBy(leds, NUM_LEDS, fade);
  // Spell the D:
  for( int i = 10; i < 15; i++) { 
    leds[i] = CHSV(colors[index % 4], 255, 255);
  }
  index++;
  FastLED.show();
  delay(100);
  fadeToBlackBy(leds, NUM_LEDS, fade);
  // Spell the S:
  for( int i = 15; i < 20; i++) { 
    leds[i] = CHSV(colors[index % 4], 255, 255);
  }
  index++;
  FastLED.show();
  delay(100);
  fadeToBlackBy(leds, NUM_LEDS, fade);
  hue=hue+10;
}

// FastLED's built-in rainbow generator
void rainbow() 
{
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

// built-in FastLED rainbow, plus some random sparkly glitter
void rainbowWithGlitter() 
{
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

// random colored speckles that blink in and fade smoothly
void confetti() 
{
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
  addGlitter(80);
}

// a colored dot sweeping back and forth, with fading trails
void sinelon()
{
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}

// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
void bpm()
{
  uint8_t BeatsPerMinute = 62;
  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));
  }
}

// eight colored dots, weaving in and out of sync with each other
void juggle() {
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(200); } }

void cylon() { 
  static uint8_t hue = 0;
  // First slide the led in one direction
  for(int i = 0; i < NUM_LEDS; i++) {
    // Set the i'th led to red 
    leds[i] = CHSV(hue++, 255, 255);
    // Show the leds
    FastLED.show(); 
    // now that we've shown the leds, reset the i'th led to black
    // leds[i] = CRGB::Black;
    fadeall();
    // Wait a little bit before we loop around and do it again
    delay(50);
  }

  // Now go in the other direction.  
  for(int i = (NUM_LEDS)-1; i >= 0; i--) {
    // Set the i'th led to red 
    leds[i] = CHSV(hue++, 255, 255);
    // Show the leds
    FastLED.show();
    // now that we've shown the leds, reset the i'th led to black
    // leds[i] = CRGB::Black;
    fadeall();
    // Wait a little bit before we loop around and do it again
    delay(50);
  }
}

// The rest of the code is for the fire() pattern, which makes the board
// look like flickering flame, from left to right. 

#define COOLING  55

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120
bool gReverseDirection = false;

void fire()
{
// Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
    }
  
    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }
    
    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(7);
      heat[y] = qadd8( heat[y], random8(160,255) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS-1) - j;
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *