Hi All,
Just wanted to share a sketch I made that incorporates a button with Color Palettes (modified from Amelia Tetterton's FastLED Palette Button) and in this case the Fire sketch by Hans Luijten. The code might have some redundancies from a lot of experimentation, but it does work. Essentially, you need to call the
FillLEDsFromPaletteColors( startIndex);
For every case that involves palettes, rather than calling it globally in the void loop function. So to have another pattern like Fire work properly, you simply omit this code in the cases. Example of the loop:
//------------------MAIN LOOP------------------
void loop() {
byte currKeyState = digitalRead(BUTTON_PIN);
if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
shortKeyPress();
}
prevKeyState = currKeyState;
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* motion speed */
switch (ledMode) {
//The group of colors in a palette are sent through a strip of LEDS in speed and step increments youve chosen
//You can change the SPEED and STEPS to make things look exactly how you want
//SPEED refers to how fast the colors move. Higher numbers = faster motion
//STEPS refers to how wide the bands of color are. Based on the palette & number of LEDs, some look better at different steps
case 0:
{FillLEDsFromPaletteColors( startIndex);currentPalette = bhw1_14_gp; SPEED = 75; STEPS = 1;}
break;
case 1: {FillLEDsFromPaletteColors( startIndex);currentPalette = Sunset_Real_gp; SPEED = 35; STEPS = 1;}
break;
case 2: {FillLEDsFromPaletteColors( startIndex);currentPalette = bhw2_21_gp; SPEED = 25; STEPS = 1;}
break;
case 3: Fire(20,200,1);
break;
}
random16_add_entropy( random());
FastLED.show();
FastLED.delay(1000 / SPEED);
}
This is the full sketch:
/* This sketch is a compilation of the FastLED ColorPalette and a button press.
There are a bunch of mode options to choose from within the sketch.
Note: Codebender might not support some parts required by this sketch
as the version of FastLED may be out of date.
Copy to & upload via Java IDE if you run into this issue.
Have fun!
*/
#include <FastLED.h>
#include "colorutils.h"
#include "colorpalettes.h"
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
//This is where we adjust things to match our unique project:
#define NUM_LEDS 170 // adjust this to the number of LEDs you have: 16 or more
#define LED_TYPE WS2812B // adjust this to the type of LEDS. This is for Neopixels
#define DATA_PIN 4 // adjust this to the pin you've connected your LEDs to
#define BRIGHTNESS 255 // 255 is full brightness, 128 is half
#define SATURATION 255 // 0-255, 0 is pure white, 255 is fully saturated color
#define BUTTON_PIN 2 // Connect the button to GND and one of the pins.
#define FRAMES_PER_SECOND 60
#define COLOR_ORDER GRB
#define NUM_MODES 4 //Update this number to the highest number of "cases"
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
uint16_t STEPS = 30;// STEPS set dynamically once we've started up
uint16_t SPEED = 30;// SPEED set dynamically once we've started up
CRGB leds[NUM_LEDS];
CRGBPalette16 currentPalette;
CRGBPalette16 gPal;
TBlendType currentBlending;
bool gReverseDirection = false;
int ledMode = 0;
uint8_t colorLoop = 1;
const TProgmemPalette16 MyColors_p PROGMEM =
{
CRGB:: DarkBlue,
CRGB:: HotPink,
CRGB:: Teal,
CRGB:: BlueViolet,
CRGB:: DodgerBlue,
CRGB:: DeepPink,
CRGB:: Turquoise,
CRGB:: Indigo,
CRGB:: DarkBlue,
CRGB:: HotPink,
CRGB:: Teal,
CRGB:: BlueViolet,
CRGB:: DodgerBlue,
CRGB:: DeepPink,
CRGB:: Turquoise,
CRGB:: Indigo,
};
byte prevKeyState = HIGH; // button is active low
// Gradient palette "Sunset_Real_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png .index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) {
0,0, 0, 0,
1, 120, 0, 0,
22, 179, 22, 0,
51, 255,104, 0,
85, 167, 22, 18,
135, 100, 0,103,
198, 16, 0,130,
255, 0, 0,0};
// Gradient palette "bhw2_21_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_21.png .index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.
// Gradient palette "bhw2_21_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_21.png .index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.
DEFINE_GRADIENT_PALETTE( bhw2_21_gp ) {
0, 0, 0, 0,
22, 0, 0, 0,
51, 7,255, 8,
85, 0, 0, 0,
135, 0, 153, 76,
175, 0, 0, 0,
255, 153, 0, 153,
0, 0, 0, 0,};
// Gradient palette "bhw1_14_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_14.png .index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 36 bytes of program space.
DEFINE_GRADIENT_PALETTE( bhw1_14_gp ) {
0, 0, 0, 0,
12, 1, 1, 3,
53, 8, 1, 22,
80, 4, 6, 89,
119, 2, 25,216,
145, 7, 10, 99,
186, 15, 2, 31,
233, 2, 1, 5,
255, 0, 0, 0};
//------------------SETUP------------------
void setup() {
delay( 2000 ); // power-up safety delay
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness( BRIGHTNESS );
currentBlending = LINEARBLEND; //all of these will be blended unless I tell them not to be
gPal = HeatColors_p;
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
//------------------MAIN LOOP------------------
void loop() {
byte currKeyState = digitalRead(BUTTON_PIN);
if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
shortKeyPress();
}
prevKeyState = currKeyState;
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* motion speed */
switch (ledMode) {
//The group of colors in a palette are sent through a strip of LEDS in speed and step increments youve chosen
//You can change the SPEED and STEPS to make things look exactly how you want
//SPEED refers to how fast the colors move. Higher numbers = faster motion
//STEPS refers to how wide the bands of color are. Based on the palette & number of LEDs, some look better at different steps
case 0:
{FillLEDsFromPaletteColors( startIndex);currentPalette = bhw1_14_gp; SPEED = 75; STEPS = 1;}
break;
case 1: {FillLEDsFromPaletteColors( startIndex);currentPalette = Sunset_Real_gp; SPEED = 35; STEPS = 1;}
break;
case 2: {FillLEDsFromPaletteColors( startIndex);currentPalette = bhw2_21_gp; SPEED = 25; STEPS = 1;}
break;
case 3: Fire(20,200,1);
break;
}
random16_add_entropy( random());
FastLED.show();
FastLED.delay(1000 / SPEED);
}
void shortKeyPress() {
ledMode++;
if (ledMode > NUM_MODES) {
ledMode=0;
}
}
void FillLEDsFromPaletteColors( uint8_t colorIndex) {
for( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, BRIGHTNESS, currentBlending);
colorIndex += STEPS;
}
}
void SetupNewPalette()
{
fill_solid( currentPalette, 16, CRGB::Black);
// set half of the LEDs to the color selected here
// Play with the color, steps, and speed to get different results.
currentPalette[0] = CRGB::DodgerBlue;
currentPalette[1] = CRGB::DodgerBlue;
currentPalette[2] = CRGB::DodgerBlue;
currentPalette[3] = CRGB::DodgerBlue;
currentPalette[8] = CRGB::DodgerBlue;
currentPalette[9] = CRGB::DodgerBlue;
currentPalette[10] = CRGB::DodgerBlue;
currentPalette[11] = CRGB::DodgerBlue;
}
// This function sets up a palette of purple and green stripes.
// Play with the color, steps, and speed to get different results.
void SetupWatermelonPalette()
{
CRGB Pink = CHSV(HUE_PINK, 255, 255);
CRGB Green = CHSV( HUE_GREEN, 255, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
Green, Green, Green, Green,
Pink, Pink, Pink, Pink,
Green, Green, Green, Green,
Pink, Pink, Pink, Pink );
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
static byte heat[NUM_LEDS];
int cooldown;
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
if(cooldown>heat[i]) {
heat[i]=0;
} else {
heat[i]=heat[i]-cooldown;
}
}
// 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' near the bottom
if( random(255) < Sparking ) {
int y = random(7);
heat[y] = heat[y] + random(160,255);
//heat[y] = random(160,255);
}
// Step 4. Convert heat to LED colors
for( int j = 0; j < NUM_LEDS; j++) {
setPixelHeatColor(j, heat[j] );
}
showStrip();
delay(SpeedDelay);
}
void setPixelHeatColor (int Pixel, byte temperature) {
// Scale 'heat' down from 0-255 to 0-191
byte t192 = round((temperature/255.0)*191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if( t192 > 0x80) { // hottest
setPixel(Pixel, 255, 255, heatramp);
} else if( t192 > 0x40 ) { // middle
setPixel(Pixel, 255, heatramp, 0);
} else { // coolest
setPixel(Pixel, heatramp, 0, 0);
}
}
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}
For easy testing purposes by the way, you should totally use Wokwi Fastled Tester Site