Palettes and Util Classes - AlbertGBarber/PixelSpork GitHub Wiki

Overview:

In this example, we'll go over Pixel Spork's Palettes and utility classes. This page is intended to be paired with the "Palettes_and_Utility_Classes" library example code. Note that this example builds on the previous examples in the "Starter Guide" in the right-hand wiki sidebar, so I won't be going over anything that's already been covered in a previous example.

In the example, we'll create two palettes, a Palette Blender utility, and a Twinkle effect. Palette Blenders blend from one palette to another over time, with additional options for looping the blend and randomize the palettes. We'll combine the Palette Blender with our two palettes to create a blended palette with ever changing colors.

The Twinkle effect fades random LEDs in and out using a palette for colors. We'll combine our blended palette with the effect to create a set of fading and color shifting LEDs.

We'll re-use the same Segment Set as in the "Basic Setup" example, replicating the strip as a 1D line, like how it is physically connected.

Example Output Using a 1D Segment Set with 60 LEDs

Note: when compiling using the Arduino IDE, if you have your "compiler warnings" (found in "preferences") set to "More" or "All" you may get a few warnings when you first compile a sketch. These should mainly concern the possible non-usage of various static variables, and are expected. They will not prevent the code from running!

Palettes:

In Pixel Spork, a palette is a set of FastLED CRGB colors. Typically, an effect will use a palette as the source of its colors. For example, if we had a palette containing red, green, and blue, any effects using the palette would use red, green, and blue for their colors.

Defining a palette is simple, requiring only an array of CRGB colors. In this example, we create two palettes with three random colors each:

The first palette:

//Create an array of random CRGB colors
CRGB palette0_arr[] = { colorUtilsPS::randColor(), colorUtilsPS::randColor(), colorUtilsPS::randColor() };

//Create the palette, "palette0" using the color array, and the array's length
palettePS palette0 = { palette0_arr, SIZE(palette0_arr) };

In the first line in the code above, we create an array (palette0_arr) of three randomly generated CRGB colors, using the [colorUtilsPS](https://github.com/AlbertGBarber/PixelSpork/wiki/Color-Utils) namespace randColor() function to pick each color. In this example, we're using random colors, but if we wanted specific colors, we could add them like: { CRGB::Red, CRGB::Green, CRGB::Blue } (using FastLED's pre-defined colors). You can read more about FastLED's colors here.

In the second line, we create the palette itself, named "palette0", using the color array above and the array's length (automatically set using SIZE()). We can now pass palette0 to any effect that uses a palette. Note that usually effects will use all the colors in a palette, so it's important to limit how long the palette is. I find that for most effects, between 2 and 5 colors works best. Also note that while you can change a palette's colors and length during runtime, it's usually easier to just define multiple palettes and swap between them.

You can read more about Palettes here, and by reading all the pages under "Palettes" in the right-hand wiki sidebar.

Pixel Spork also has a set of predefined Palettes listed here.

Finally, the second palette is defined in much the same way as the first:

//Create a second palette, "palette1"
CRGB palette1_arr[] = { colorUtilsPS::randColor(), colorUtilsPS::randColor(), colorUtilsPS::randColor() };
palettePS palette1 = { palette1_arr, SIZE(palette1_arr) };

Utility Classes and Palette Blender:

Utility classes are helpers for your effects. The behave almost exactly like effects, but instead of drawing (usually), they produce or change something over time such as a palette or other variable. Think of them as an enhancer for your effects. In this example, we'll use the Palette Blender utility class, but there are lots of other utility classes. You can read more about them here.

We'll setup our Palette Blender just like we would an effect:

//Create a Palette Blender named PB using the two random palettes from above
PaletteBlenderPS PB(palette0, palette1, true, 30, 100);

The code above creates a Palette Blender, named "PB". Palette Blenders take two input palettes and produce an output palette, "blendPalette", that transitions over time between first to second input palette. While not important for our example, the number of colors in the blendPalette will be equal to the longer of the two palettes. Using the other arguments for our Palette Blender, we have configured PB to loop (looped is set true), use 30 steps for each transition, and update at a rate of 100ms. So, a full transition from one palette to another takes 3000ms (30 steps * 100ms), and once a transition is finished, the blender will reset and transition back to the original palette, repeating the cycle endlessly.

You may remember that in the intro I said we were going to set the Palette Blender to randomize our palettes when looping. This option is not included in the Palette Blender constructor we used, so we'll set it during runtime in the Arduino setup() function. This kind of additional setting setup is fairly common because when creating constructors, I try to restrict them to the most important settings for each effect, which helps them stay "readable". Effects and utilities often have multiple constructors with different sets of options, so it's worth checking if there's one that fits your situation.

The Twinkle Effect:

With the Palette Blender created, we can create our Twinkle effect using the Palette Blender's blend palette:

//Create a TwinkleSL effect named "twinkle"
TwinkleSL twinkle(mainSegments, PB.blendPalette, 0, 1, 6, 6, 70);

The line above creates a Twinkle (Seg Line) effect named "twinkle". Note that we use the Palette Blender's output blend palette, PB.blendPalette, as the effect's palette. Also note that internally, effects almost always use a pointer to bind to external objects such as palettes. This means that changes to the blend palette's colors will carry over to the Twinkle effect automatically.

The other inputs to the effect make the background black (0), set one LED to turn on each cycle, set the LEDs to fade in and out in 6 blend steps, and that the effect will update at a rate of 70ms.

Set the Palette Blender to "Randomize":

As mentioned above, we want our Palette Blender to randomize our palettes when it loops, so that we have a constantly shifting set of colors. However, the "randomize" setting is not included in the Palette Blender constructor we used, so we need to set it during runtime. We only intend to set it once, so the easiest way is to set it during the Arduino setup() function:

void setup(){

    //<Some other, unrelated code>

    //Set the Palette Blender to randomize the palettes when it loops
    //This gives us an every changing set of colors
    PB.randomize = true;
}

Our Loop() Code:

With everything setup, we can create our runtime code. To run our Twinkle effect and Palette Blender, we simply need to update them. Note that we update the Palette Blender ("PB") just as we would an effect. Utility classes are coded to behave almost exactly like effects, so controlling them is basically the same as controlling an effect.

The overall result should be twinkling LED whose colors change as they fade in and out. At any time, the Twinkles will be one of three colors, corresponding to the three colors of the blended palette.

void loop() {

    //Update both the Palette Blender and Twinkle
    //The result should be twinkles that change colors over time (but always use 3 colors total)
    PB.update();
    twinkle.update();
}

Outro:

In this example, we went over Pixel Spork's palettes and utility classes. We used the Palette Blender utility class to enhance a Twinkle effect, giving the effect a set of ever changing colors.

In the next example, we'll delve into another effect enhancer (but not a class): Color Modes.

⚠️ **GitHub.com Fallback** ⚠️