Releases: FastLED/FastLED
FastLED 3.10.2
Fastled.3.10.2-1.mp4
FastLED 3.10.2
- CORKSCREW MAPPING!
- Want to create a light saber or festival stick? Before your options were to have vertical strips.
- Now you can use a corkscrew mapping fl/corkscrew.h, see examples/FestivalStick
- You input the number of LEDS + number of turns.
- Corkscrew will provide a surface XY grid that you draw too.
- then call Corkscrew::draw(), and the current surface will be mapped to the corkscrew.
- Rendering is done via 2x2 bilinear sampling. Looks great!
- Animartrix - 30% faster due to forced
-O3
andfastmath
compiler settings for this one file. - Ease Functions - lots and lots of ease functions! Great for animations!
- see fl/ease.h and the demo examples/Ease/Ease.ino
- Fast! Everything is done in integer space.
- 3D Perlin noise (
inoise8(x, y, z)
) range utilization improved from 72.9% to 88.6%- Significantly better quality for volumetric LED effects (3D fire, clouds, particles)
- Uses industry-standard 12 edge vectors of a cube for optimal gradient coverage
- Adafruit NeoPixel Bridge: Optional Adafruit_NeoPixel clockless controller support
- For some platforms Adafruits NeoPixel just works better.
- Enable with
#define FASTLED_USE_ADAFRUIT_NEOPIXEL
before including FastLED - Now your WS2812 chipset will use the AdafruitNeopixel library (if installed)
- New LED chipset: SM16824E
- 3-Wire
- See also: #1941 (comment)
- apollo3_red (stm variant): beta support.
- HSV16 support
- CRGB -> HSV -> CRGB is highly lossy
- CRGB -> HSV16 -> CRGB is almost perfect.
- Integer based so it's fast.
- ColorBoost
- CRGB::colorBoost()
- Are you doing video on WS2812? Well then you probably are using gamma correction
- Color Boost is an alternative for gamma correction for the WS2812 and other RGB8 chipsets.
- It preserves luminosity but allows you to increase saturation.
- HSV16 is used to preserve color resolution.
- HSV -> CRGB default conversion function can now be overriden.
- Thanks to https://github.com/ssilverman or this full spectrum HSV implementation.
- If you just want to change it for your sketch you can use this:
#define FASTLED_HSV_CONVERSION_RAINBOW
(default)#define FASTLED_HSV_CONVERSION_SPECTRUM
#define FASTLED_HSV_CONVERSION_FULL_SPECTRUM
- To change for the entire engine (recommended) then set these as build flags:
-DFASTLED_HSV_CONVERSION_RAINBOW
-DFASTLED_HSV_CONVERSION_SPECTRUM
-FASTLED_HSV_CONVERSION_FULL_SPECTRUM
- fl/fetch.h
- A non blocking http fetch library returning an fl/promise.h
- You can then await the promise with
fl::await
or install a callback to be invoked. The latter is recommended.
- fl/json.h rewrite
- Much more ergonic library. Fast parsing for packed arrays of number
- The underlying ArduinoJson library is only ergonomic if you allow
std:string
andstd::sstream
, which is missing on platforms like avr. So we had to write our own api to handle this.
- Platforms
- ESP32-C5 is now supported.
- ESP32 WS2812 SPI driver has a fix for it's async draw routine.
- Blend2d will now replace a subfx XYMap (when necessary) to prevent double mapping. A warning will be issued.
- Seeed XIAO nRF52840 Sense: Fixed incorrect pin mappings that were copied from Adafruit Feather board
- APA102HD Gamma Correction Algorithm: Completely rewritten with closed-form mathematical solution
- Thanks https://github.com/gwgill!
- Graph of the old algorithms quantization issues can be see here:
- STM32F1 pin mapping fixes (blue pill)
- #1973
- Thanks https://github.com/vishwamartur!
- Internal stuff
- FastLED is now way more strict in it's compiler settings. Warnings are treated as errors
- Lots of fixes, some code required amnesty.
- The examples now compile under clang and run for
./test
- All examples now compile for ALL platforms.
- this was a major undertaking.
- required a rewrite of the testing infrastructure.
- Teensy41 took ~ 1 hours to compile 40 examples, now it can do 80 examples in ~8 mins
- FastLED is now way more strict in it's compiler settings. Warnings are treated as errors
3.10.1 - Bug Fix for 3.10.0
- Fix for Esp32s3 - Improvement to code caused DMA mode was set to true, breaking RMT5
- Examples fix
- Some problematic headers were pulled in that conflicts with Arduino.h, these have been fixed
- SKETCH_HAS_LOTS_OF_MEMORY was being tested before
#include "FastLED.h"
fixed
FastLED 3.10.0 Released - Animartrix, ESP32-P4, ESP32-S3 I2S improvements
fastled_3_10_animartrix_small.mp4
- Animartrix now out of beta.
- examples/Animartrix/Animartrix.ino
- ESP32
- Esp32P4 now officially supported.
- ESP32-S3 I2S driver is improved
- It will now auto error on known bad Esp32-Arduino Core versions.
- Arudino core 3.2.0 is now know to work.
- Documentation has been greatly simplified and unnecessary steps have been removed.
- It will now auto error on known bad Esp32-Arduino Core versions.
Full Changelog: 3.9.20...3.10.0
3.9.20: Misc Fixes
Optional upgrade. Fixes fadeByLight not being in the global namespace. This fixes a regression that happened in 3.9.17.
Full Changelog: 3.9.19...3.9.20
Hot Fix #2 for 3.9.17
For more information see this bug fix thread.
It turns out the older AVR gcc compilers will not eliminate complex static objects that are not referenced. However it seems it will eliminate them if they are in statics inside static functions, like this:
This will unconditionally initialize in avr-gcc at startup, but be removed in more modern toolchains.
typedef fl::hash_map<Key, Value> HashMap;
static HashMap gStatic;
This however, will be removed in avr-gcc and others
static HashMap& get_static() {
static HashMap s_static;
return s_static;
}
Here is a Chat GPT Summary:
🔍 Summary:
-
AVR-GCC does not aggressively eliminate unused static non-POD objects — even if they appear to be unused — because:
- It lacks certain modern optimizations (especially LTO-level optimizations).
- It typically relies on the
.ctors
section to ensure initialization of static objects with constructors. - By default, objects with static storage duration and non-trivial constructors get registered for initialization via
.ctors
and the linker keeps them.
-
Modern Clang and GCC (non-AVR) will remove these if they are not referenced and the constructors are not marked in a way that ensures their side effects are preserved.
🔧 Arduino Build Settings
In the Arduino build system (typically using avr-gcc
):
- Link-Time Optimization (LTO) is often disabled by default for compatibility. Without LTO, the compiler doesn't see across translation units and is less aggressive about removing "unused" symbols.
- Static initializers are kept because they're registered in the
.ctors
section which the startup code walks through during initialization. - If you're using Arduino CLI or PlatformIO with LTO enabled (
-flto
), you may start seeing more Clang/GCC-like elision behavior if you're not careful.
🔒 Why static constructors aren’t elided (AVR-specific reasons)
- AVR
libc
(avr-libc
) startup code explicitly calls global/static constructors via__do_global_ctors
. - The compiler places constructors into
.ctors
section using.section .ctors
+.initN
priorities. - These sections are preserved unless explicitly dropped or optimized out with aggressive LTO.
✅ To Preserve in Modern Toolchains
In more aggressive modern toolchains (Clang/GCC with LTO):
- Use
__attribute__((used))
orvolatile
globals if you want to force retention. - Or rely on
__attribute__((constructor))
for function-level hooks that are less likely to be optimized out.
👇 Example
struct AutoRun {
AutoRun() { Serial.println("I ran!"); }
};
static AutoRun my_auto_run; // Kept by AVR-GCC, likely dropped by Clang w/LTO
To preserve it in Clang:
__attribute__((used)) static AutoRun my_auto_run;
✅ Conclusion
This is an AVR-GCC behavior, not strictly Arduino's doing — but Arduino's default settings do reinforce this behavior by avoiding LTO and preserving .ctors
invocations. Modern toolchains need extra care to keep static initializers with side effects.
Bug fix - hot fix!
- Reverted AVR memory blow up
- Fix odd even bug on leds on avr
FastLED 3.9.17 - stdlib compatibility, audio preview, xypath
This release has a few bug fixes in it and some internal refactorings that has been on my to-do list for a while. The next release will have more features and less core changes.
FastLED now has a small subset of std:: data structures. This allows complex code ingest from open source which rely on things like std::vector<>, hashmaps and others. Unlike other micro stdlib attempts, this one actually compiles everywhere thanks to our ~50 testing configurations that we run on each change committed to the repo.
These std data structures were used to create complex rendering functions xypaths that look absolutely jaw dropping.
However in this release my attention got pulled into about four different directions. Audio and xypaths were added to the core, but the examples were prunned for this release, in order to get this release out in a timely manner.
What's all the noise about lines and rasterization in this release?
You ever try to draw a point or a line on a LED matrix? By default it looks awful. As the point particle moves it lights up one led index at a time. It's tricky to make this transition look smooth. Drawing beautiful lines on matrices requires pixel-neighboring calculations in order to correctly blend into a low resolution strip/matrix. And that's what most of the new math you see below is about.. Take a point in float(x,y) and then color a tile of 2x2 pixels, or 2x1 if you are in a strip.
Happy coding!
Change list
- esp
- esp-idf v5.4 fixes to include lcd_50
- #1924
- Thanks! https://github.com/rommo911
- RMT5 will now respect DMA_MODE=DMA_ENABLED
- Default is still off.
- #1927
s.
- datastructures
- FastLED now has it's own subset of std lib. fl::vector<>, fl::hash_map<> etc so you can bring in external code to your sketches easily and have it still be cross platform compatible. Our std lib subset is backed by a fleet of platform testers so it compiles and works everywhere. Will this increase the AVR and other small memory footprints? No, we have strict checks for these platforms and compile size remains the same.
- fl::hash_map
- open addressing but with inlined rehashing when "tombstones" fill up half the slots.
- fl::hash_map_inlined
- fl::hash_set
- fl::vector
- fl::vector_inlined
- fl::function<>
- fl::variant<T,...>
- fl::optional
- esp-idf v5.4 fixes to include lcd_50
- graphics
- CRGB::downscale(...) for downsizing led matrices / strips.
- Essentially pixel averaging.
- Uses a fastpath when downsizeing from M by N to M/2 by N/2.
- Uses fixed-integer fractional downsizing when the destination matrix/strip is any other ratio.
- CRGB::upscale(...) for expanding led matrices / strips, uses bilinear expansion.
- XYPath (Work in progress):
- Create paths that smoothly interpolate in response to animation values => [0, 1.0f]
- Still a work in progress.
- Subpixel calculations.
- Let's face it, low resolution matrices and strips produce bad results with simple pixel rendering in integer space. I've implemented the ability for using floating point x,y coordinates and then splatting that pixel to a 2x2 tile. If a point is dead center on a led then only that led in the tile will light up, but if that point moves then other neighboring leds will start to light up in proportion to the overlap. This gives 256 effective steps in the X and Y directions between neightbors. This greatly improves visual quality without having to super sample.
- Line Simplification
- Take a line with lots of points and selectively remove points that
have the least impact on the line, keeping the overall shape. We use an improved Douglas-Peucker algorithm that is memory efficient. We also have a version that is more cpu intensive which will will hit a target number of vertices.
- Take a line with lots of points and selectively remove points that
- RasterSparse: efficient rendering to an intermediate buffer that only allocates x,y points for values actually written, then flush to LED matrix/strip. See below for more information.
- traverseGridSegment
- Given a line A-B, find all the intersecting cells on a grid.
- Essentially 2D ray tracing.
- Great for optimization of particle trails and rastering an entire XYPath.
- Example:
- Full XYPath (e.g. Heart) renders 200 xy points
- Use line simplification to reduce this to 50 most significant points -> 49 line segments
- For each line segment
- traverseGridSegment computes all the intersecting grid points
- for each grid point find the closest point on the segment, call it closest-pt
- closet-pt generates a tile2x2 of itself plus it's 3 neighbors
- for each tile2x2 it will have a uint8_t value representing it's intensity / closeness to center.
- tile2x2 list/stream -> raster (RasterSparse)
- raster -> composite to LED matrix/strip using a gradient or draw functor.
- closet-pt generates a tile2x2 of itself plus it's 3 neighbors
- for each grid point find the closest point on the segment, call it closest-pt
- traverseGridSegment computes all the intersecting grid points
- Example:
- RasterSparse
- A memory efficient raster that elements like the XYPath can write to as an intermediate step to writing to the display LEDs. This allows layering: very important for creating things like "particle trails" which require multiple writing to similar pixels destructively and then flushed to the LED display. For example if a particle has a long fade trail with say 30 points of history, then this entire path can be destructively drawn to the raster then composited to the led display as an unified layer.
- "Sparse" in "RasterSparse" here means that the x,y values of the pixels being written to are stored in a hash table rather than a spanning grid. This greatly reduces memory usage and improves performance. To prevent excessive computation with hashing, a small 8-unit inlined hash_table with a FastHash function is carefully used to exploit the inherent locality of computing particle and paths.
- Right now, RasterSparse is only implemented for uint8_t values and not an entire CRGB pixel, as CRGB values are typically computed via an algorithm during the compositing process. For example a gradient function can take a rasterized particle trail and apply coloring.
- LineMath
- Take a line A-B and calculate the closest distance from the line to a point P. This is important to optimize rendering if oversampling takes too much CPU.
- CRGB::downscale(...) for downsizing led matrices / strips.
FastLED 3.9.16
FastLED 3.9.16 Changes
This release is for the artists and makers who want to make the light they want to see in the world.
fastled_3_16_small.mp4
FastLED 3.9.16 is now released. Arduino will approve it in the next few hours and should have it available through your IDE by Friday morning.
This release of FastLED is geared toward our programmer-artist community. If you love creating amazing visuals then this release will be one of the most significant releases yet for you. Read on:
Summary of Visual Enhancements in FastLED 3.9.16
-
FxWave: FastLED now features a 1D and 2D wave simulator. Special thanks to Shawn Silverman who provided the differential equations to make this work. This simulator runs in int16_t fixed integer space, allowing it to be fast on MCU's without a dedicated FP processor. We support super scaling the wave simulator which is then down scaled for rendering. The wave simulator will default to half-duplex which means negative values are discarded. This allows the simulator in it's default state to produce black, instead of some midpoint (127) color. The fixed 16 point integer calculation has enough bit depth to run easing functions mapping [0, 1] -> [0, 1] without loss of quality. Unlike particle based effects which slow down as the complexity increases, the WaveSimulator does not suffer from this. The same processing is needed whether the wave simulator is drawing all black or otherwise, so go wild.
-
Animations: TimeAlpha classes now offer smooth transitions based on the current time and begin & end times. You will trigger the TimeAlpha which will start the clock. After this, you can called the TimeAlpha's
update()
function to retrieve the current alpha value. You can use this alpha transition to do path tracing. For example in the video above I'm drawing a cross by running a pixel trace with a span of 6. Any intersection with the wave simulator is then incremented by the specified value. Example usages include: one TimeAlpha class can be used for brightness control while another can be used as input for a parametric path, taking in auint8_t
orfloat
and outputtingx
andy
. -
Alpha-less blending: CRGB::blendAlphaMaxChannel(...) allows per-pixel blending between most visualizers now in the wild. FastLED does not have a strong concept of alpha masks. This really bothered me as compositing is the key for great visualizers and this algorithm produces striking results and can essentially be bolted on without much changes: the brightness of a pixel is a strong signal for proper mixing. You will specify an upper and lower pixel. The upper pixel is queried for the max brightness of it's components. This max brightness then becomes the alpha mask and the two pixels are mixed to generate a new pixel.
-
fx/fx2d/blend.h
is a newFx2d
subclass that functions as a blend stack. combining severalFx2d
classes into one functionalFx2d
instance. EachFx2d
contained in the blending stack can have it's own blur settings specified. The layers are then composited from back to front. The bottom layer is drawn directly without blending. The rest of the channels are composited via CRGB::blendAlphaMaxChannel(...). The bluring parameters for the blend stack can be set for the whole stack, or per frame, allowing striking visual quality even at low resolution and eliminates a lot of aliasing effects common in FastLED visualizers. -
inoise(...) just went 4D. This is designed to support irregular shapes like led strip wrapped cylinders, which is the main use case. In this instance you could define a width and radius and then compute each pixel in 3D space. You can then run the x,y,z coordinates through inoise(...) plus a time factor to produce a noise pattern.
-
FireMatrix and FireCylinder. Fire2012 visualizer is becoming more dated by the day. There are lot of 2D fire simulators in the wild based on FastLED's perlin noise functions. The FireMatrix is a straight matrix for flat pannels, while FireCylinder wrapps around so that the first and last x value are seemless. FireCylinder is perfect for those flex led panels if you want to bend them on themselves - you will now get a full 360 fire effect.
How the featured examples/FxWave2d
demo was generated
- This examples is a 64x64 matrix grid. I used two FxWave2d visualizers: one for the blue gradient and other for the white->red gradient. The blue gradient wave simulator runs at a slightly faster speed factor to improve visual impact and make it look similar to a star going nova. Both wave simulators are super scaled at 2x in W and H and then downscaled for rendering (this is featured in the Wave simulator class and you don't need to worry about it - it's just an enum you pass). I then combined both FxWave2d instances into a Blend2d FX class with the blue gradient wave at the bottom of the stack which will unconditionally write it's pixel values to the render surface. The white->red gradient wave is then composited ontop. Again this is all automatic when you use the Blend2D fx class. The white->red wave produces lots of artifacts and therefore heavy bluring is used to improve visual quality. The blue wave does not need much bluring because of reasons. The cross that you see is drawn using 4 parameterized paths being applied to the white->red wave simulator. The speed of the path is controlled via a user setting and can be changed. To avoid pixel skipping as the path traverses across the screen, the paths are over drawn with a span of 6% of the width of the display.
That's it at a high level. If you aren't interested in the details of this release you can stop reading now.
Release Notes
- New inoise16 4D function taking in x,y,z,t
- This is good for 3D oriented noise functions + time factor.
- Wrap an led strip as a cylinder and use this function to map noise to it.
- New Wave Simulator in 1D and 2D
- Thanks /u/ssilverman
- Full and half duplex wave simulators (half duplix supports black)
- For improved rendering we allow 2x, 4x, 8x super sampling
- Speed control via multiplying the rendering iterations per frame.
EVERY_N_MILLISECONDS_RANDOM(MIN, MAX)
macro for sketches.CRGB CRGB::blendAlphaMaxChannel(const CRGB& upper, const CRGB& lower)
for fx blending withoutalpha
.- fl/2dfx/blend.h
- Visualizer blend stack.
- Multiple visualizers can be stacked and then composited via
blendAlphaMaxChannel(...)
- Blur2d can be applied per layer and globally.
fl/time_alpha.h
- New time based functions for controlling animations.
- Give it a beginning time, and end time and the current time
update(...)
will give you the current time progression.
- Trigger then called upated to get
uint8_t
from 0 -> 255 representing current animation progression.
fonts/
- We now are opening up a beta preview of FastLED fonts. These are lifted from the WLED project, who copied them from Microsoft. There is no mapping yet for turning a character like
a
into it's font representation and will need to be done ad-hoc style. The API on this is going to change a lot so it's recommended that if you use the fonts that you copy them directly into your sketch. Otherwise it's very likely the API will change in the near future when font mapping is added.
- We now are opening up a beta preview of FastLED fonts. These are lifted from the WLED project, who copied them from Microsoft. There is no mapping yet for turning a character like
- New Examples:
- FxWave2d
- Complex multi wave simulator visualizer.
- FireMatrix
- FireCylinder
- Same as FireMatrix, but the visualizer wraps around so it is seemless (y(0) ~= y(width -1))
- FxWave2d
Happy coding! ~Zach
New Contributors
- @imwhocodes made their first contribution in #1916
- @ssilverman
Full Changelog: 3.9.15...3.9.16
3.9.15
What's Changed
- Fix ATtiny4313/13 builds by @sutaburosu in #1874
- Enable test compiles for ESP32 with ESP-IDF 3.3 LTS by @Jueff in #1879
- fix: add the executable flag to
build_archive.sh
by @sutaburosu in #1883 - Initial support for Arduino GIGA R1 WiFi added by @zackees in #1892
- Fix issue with bad reference to non existing GPIO register for giga r1 by @RubiCubix in #1893
- made sin approximations faster and more accurate by @zackees in #1896
- Additional platform identifier define added for giga r1 by @RubiCubix in #1899
- Don't define MIN and MAX in platform headers by @hmaarrfk in #1901
- fixing ESP IDF V 5.4 compiler error [-Werror=mismatched-new-delete] by @rommo911 in #1906
- Fixes jumping red pixel - see #943 by @zackees in #1907
- 1909: Add preproccesor check to prevent redefinition of new() by @Dantali0n in #1910
- fixed cause the assertion in panel_io_i80_tx_color, assert(color_size <= bus->max_transfer_bytes && "color bytes too long, enlarge max_transfer_bytes"); by @ChinaBurn in #1913
New Contributors
- @RubiCubix made their first contribution in #1893
- @hmaarrfk made their first contribution in #1901
- @rommo911 made their first contribution in #1906
- @Dantali0n made their first contribution in #1910
- @ChinaBurn made their first contribution in #1913
Full Changelog: 3.9.13...3.9.15
FastLED 3.9.14
FastLED 3.9.14
- Attiny4313 now works
- #1874
- Thanks https://github.com/sutaburosu!
- Arduino GIGA Now working
- Thank you @RubixCubix!
- Fix for mqtt build modes: #1884