SkillAgentSearch skills...

QuickPatterns

FastLED based pattern engine for addressable LEDs (NeoPixels, WS2811, WS2812) for layering animations on the same strand of lights.

Install / Use

/learn @brimshot/QuickPatterns
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

quickPatterns

A pattern and animation manager for individually addressable LEDs (WS2811, WS2812, NeoPixels, etc.) using FastLED.

The goal of quickPatterns is to provide makers a simple interface in code for building advanced light pattern configurations i.e. multiple patterns running simultaneously, configurable colors, timed and sequenced pattern activation.

Features

  • Easily layer multiple animations on top of each other, with multiple options for how overlapping pixels interact
  • Time patterns to activate and deactivate either at specific intervals or in relation to other patterns
  • Configure colors to change in relation to pattern activity including updates, frames, "cycles" or activations
  • Create multiple "scenes" of one or more patterns running simultaneously and quickly change between them
  • Easily write custom light patterns that are immediately usable with all configuration options

Documentation

Installation

Example sketch

Adding patterns

Layers

Layer brushes

Configuring pattern colors

Periodic color changes

Periodic pattern activation

Linked pattern activation

Layer effects

Scenes

Writing custom patterns

Sample pattern library

Installation

quickPatterns uses the FastLED library which must be installed on your system first, and this document assumes you are familiar with the basics of using FastLED

From the command line

Navigate to your Arduino/libraries directory and clone via the following command:

git clone https://github.com/brimshot/quickPatterns.git

ZIP archive

Choose "Download ZIP" from the Code menu when viewing the source on github and extract the archive inside your Arduino/libraries directory

Example sketch

A simple example that can be run right away

#include <quickPatterns.h>

#define CHIPSET     WS2812B
#define DATA_PIN    2
#define NUM_LEDS    100
#define BRIGHTNESS  64
#define COLOR_ORDER GRB         //GRB for WS2812, RGB for WS2811
#define TICKLENGTH  25

// declare array of CRGB objects, used by FastLED
CRGB leds[NUM_LEDS];

//declare quickPatterns controller and pass in main led array
quickPatterns quickPatterns(leds, NUM_LEDS);

void setup() {

  delay(3000); // Recovery delay

  random16_add_entropy(analogRead(0)); // seed random number generator

  // ~ Configure FastLED

  FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS)
    .setCorrection(TypicalLEDStrip)
    .setDither(BRIGHTNESS < 255);

  FastLED.setBrightness(BRIGHTNESS);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 450);

  FastLED.clear();


  // ~ Configure quickPatterns

  quickPatterns.setTickMillis(TICKLENGTH);

  // Cylon of 8 pixels that cycles through the rainbow (layer 0)
  quickPatterns.newScene().addPattern(new qpBouncingBars(8))
    .chooseColorFromPalette(RainbowColors_p, SEQUENTIAL)
    .changeColorEveryNTicks(2);

  // Periodically toss in some lightning flashes at random places along the strand, 10 pixels wide (layer 1)
  quickPatterns.sameScene().addPattern(new qpLightning(10))
      .singleColor(CRGB::White)
      .activatePeriodicallyEveryNTicks(100, 200) // activate at random intervals between 100 and 200 ticks
      .stayActiveForNCycles(2, 4); // each activation will trigger 2 to 4 lightning flashes
}

void loop()
{
  quickPatterns.show();
}

Adding patterns

Basic setup

At the top of your file declare an array of LEDs as you would in any FastLED based sketch

CRGB leds[NUM_LEDS];

Next, declare the quickPatterns controller, passing in your LEDs and length

quickPatterns quickPatterns(leds, NUM_LEDS);

In your setup() function, configure FastLED as normal, then add patterns to the quickPatterns controller as will be described below.

void setup() {

  FastLED.addLeds<...>

  ...  // configure FastLED


  // configure quickPatterns (see below)

  ...

}

Finally, in your loop() function, call the show() method of the quickPatterns controller (this will call FastLED.show() in turn).

void loop()
{
  quickPatterns.show();
}

Adding the patterns

Adding a pattern always begins with the Scene[#scenes]

quickPatterns.newScene().addPattern()

Once the quickPatterns controller has been instantiated you can use the addPattern() method and pass in a new instance of any class that inherits from the qpPattern class (write your own or use one of the sample patterns)

For example, a simple pulse of eight pixels that moves back and forth a string of lights:

quickPatterns.newScene().addPattern(new qpComet(8))
  .singleColor(CRGB::Red);

addPattern() returns a pointer to the pattern object passed as a parameter which can be used to continue to chain configuration methods. In this case we are chaining the singleColor() method which sets our pulse pattern to a constant red.

Setting pattern speeds

Updates and changes in quickPatterns operate on a tick system. Each tick, active patterns are drawn and any pending changes processed.

The default tick length is 25 milliseconds, but the length of a tick is configurable on the controller. To change the master tick length, use the setTickMillis() method

quickPatterns.setTickMillis(50); //sets tick length to 50 milliseconds

By default each pattern will update once per tick. This can be changed with the pattern configuration method drawEveryNTicks(), which allows for lowering a patterns render frequency.

quickPatterns.addPattern(new qpComet(8))
  .singleColor(CRGB::Red);
  .drawEveryNTicks(2);

By adding drawEveryNTicks(2) to the configuration chain, our pulse pattern will now animate at half speed.

Ticks are also used to calculate pattern activation and duration timings (see periodic pattern activation).

Layers

Patterns are pre-rendered on separate arrays of leds in memory which are then combined to make the final image displayed i.e. 'layers'.

The default behavior is that filled pixels in upper layers cover those in lower layers, for example:

Layer one - red every 4th LED:

----------------------
- R - - - R - - - R -
----------------------

Layer two - green every 3rd LED:

----------------------
G - - G - - G - - G -
----------------------

Final result that gets displayed on the LED strand:

----------------------
G R - G - R G - - G -
----------------------

Layers are applied to the final output in ascending order. Since layer two (green pixels) is on 'top' of layer one, the value at any collision will be the value in the upper layer.

To configure how layers interact with each other when combined see layer brushes.

By default each call to addPattern() creates a new layer in memory for that pattern to run on. However, multiple patterns can be added on to a single layer (pixel data will be written in the order patterns are rendered).

To add a pattern to a specific layer, insert the layer() method into the access chain

quickPatterns.layer(0).addPattern(new qpComet(8)); //add a pattern directly to layer 0
quickPatterns.layer(1).addPattern(new qpConfetti(60)); //add a pattern directly to layer 1

If the layer() method is called for an index that does yet exist, a new layer will be created automatically and a reference to the new layer returned.

Once created, patterns can be re-accessed directly via layer().pattern() i.e.

quickPatterns.layer(0).pattern(0) //provides access to pattern 0 on layer 0
quickPatterns.layer(0).pattern(1) //provides access to pattern 1 on layer 0

Layer brushes

Layer brushes give control over how each layer interacts with those below it and whether pixels in the same location on two separate layers overwrite, combine or blend.

Setting a layer brush is via the setLayerBrush() method which accepts one of the enumerated brush types

quickPatterns.layer(1).setLayerBrush(ADD); //layer 1 will now add it's light to below layers instead of replacing underlying pixels

There are 6 different brush types which affect the application of each layer to those below:

OVERLAY

This is the default brush if none set - any pixels in this layer that are set to black (CRGB::Black) are not written, allowing whatever is below to show through, while any pixels that have a color value replace those from layers below

ADD

The light value of pixels in this layer will be added to the light values of pixels below

SUBTRACT

The light value of pixels in this layer are subtracted from those below. Using this brush, we can turn 'off' pixels on underlying layers and render patterns using negative space. For example: set a pattern color to full white (CRGB::White) and set the layer brush to SUBTRACT and any pixels the pattern fills in will be removed from below layers.

OVERWRITE

Completely overwrite below layers with this layers pixels, including pixels that are 'off' (CRGB::Black).

COMBINE

Combine the values of this layers pixels with those below.

MASK

The mask brush subtracts the inverse of the light values in the current layer from those below. When a pattern with black and white pixels used is as a mask, any white pixels in the mask will allow those from below to show through, while any black pixels will eliminate what's underneath. Use this brush to leave 'windows' of visible space from patterns that are being rendered on the below layers.

Configuring pattern colors

Patterns are drawn using either a palette of colors or a single color per frame.

Palettes

For patterns that use a complete palette to render frames, the usePalette() method sets the palette to be used. Pass in any FastLED CRGBPalette16 object.

quickPatterns

Related Skills

View on GitHub
GitHub Stars48
CategoryDevelopment
Updated1mo ago
Forks5

Languages

C++

Security Score

95/100

Audited on Feb 12, 2026

No findings