Visitar URL original
Releases · FastLED/FastLED · GitHub
Skip to content

Releases: FastLED/FastLED

FastLED 3.10.6

Choose a tag to compare

@github-actions github-actions released this 04 Oct 23:07
ebf8c28
  • MP3 decoder: minimp3 is now the only backend, and it decodes in fixed point
    • The RPSL/RCSL-licensed src/third_party/libhelix_mp3/ tree has been removed. FastLED's MP3 support is now entirely CC0 (minimp3), which is what makes the library redistributable without the Helix licence obligations.
    • The decoder defaults to an integer (Q26 fixed-point) DSP path, so MP3 decoding no longer needs an FPU. Float remains available for reference and comparison via MINIMP3_FLOAT_POINT.
    • Integer SIMD kernels (SSE4.1 with runtime dispatch, NEON unconditionally on ARM64) accelerate the polyphase filter and DCT-32, and are gated on producing bit-identical PCM to the scalar path.
    • Mp3HelixDecoder is gone. It was an internal fl::third_party type exposed only for backend-parity testing; the public fl::Mp3Decoder / fl::Mp3 API is unchanged. Code that named Mp3HelixDecoder or MP3_HELIX_STREAM_BUFFER_SIZE directly should use Mp3Minimp3Decoder / MP3_MINIMP3_STREAM_BUFFER_SIZE.
    • Working RAM for the shipping fixed-point build is 23,308 bytes against Helix's 27,952 (the float reference build measures 23,180), and the budget is enforced in CI by codec_memory_ledger.md.
  • NEW: TrueType Font Rendering Support: Full TrueType font (.ttf/.ttc) rendering API with embedded default font
    • High-quality text rendering: Render scalable TrueType fonts to LED matrices with antialiasing support
    • stb_truetype integration: Built on industry-standard stb_truetype library (5108 lines, compact and efficient)
    • Embedded default font: Includes Covenant5x5 pixel font (9.9KB) with 5x5 pixel cell size, perfect for LED displays
    • Custom font support: Load any TrueType font from memory (.ttf single fonts or .ttc font collections)
    • FontRenderer API: Convenient high-level wrapper for rendering at specific pixel heights
      • fl::Font::loadDefault() - Load embedded Covenant5x5 font
      • fl::Font::load(fontData) - Load custom TrueType font from memory
      • fl::FontRenderer(font, pixelHeight) - Create renderer at specified size
      • renderer.render('A') - Render character with 2x2 antialiasing (default)
      • renderer.renderNoAA('A') - Render without antialiasing for crisp pixels
      • renderer.measureString("Hello") - Calculate string width with kerning
    • Advanced features:
      • Grayscale antialiasing with configurable oversampling (1x1 to NxN)
      • Automatic kerning support for professional text layout
      • Font metrics query (ascent, descent, line gap, bounding boxes)
      • Glyph metrics (advance width, side bearings, per-character bounds)
      • Unicode codepoint support
      • Scaled metrics calculation for any pixel height
    • GlyphBitmap output: Rendered glyphs as 8-bit grayscale bitmaps (0=transparent, 255=opaque)
      • Easy pixel access via getPixel(x, y) with bounds checking
      • Proper glyph positioning with xOffset/yOffset for baseline alignment
      • Direct mapping to LED coordinates for seamless integration
    • Minimal API: Simple 3-step workflow - load font, create renderer, render glyphs
    • Memory efficient: Shared font instances via fl::shared_ptr, on-demand rendering
    • Platform agnostic: Works on all FastLED platforms with C++ support
    • Example usage:
      #include "fl/font/truetype.h"
      #include "fl/font/truetype.cpp.hpp"  // Include ONCE
      
      auto font = fl::Font::loadDefault();          // Load embedded font
      fl::FontRenderer renderer(font, 10.0f);       // 10px height
      fl::GlyphBitmap glyph = renderer.render('A'); // Render with AA
      
      // Draw to LED matrix
      for (int y = 0; y < glyph.height; ++y) {
          for (int x = 0; x < glyph.width; ++x) {
              uint8_t alpha = glyph.getPixel(x, y);  // 0-255
              // Blend alpha onto LED at (x + glyph.xOffset, y + glyph.yOffset)
          }
      }
    • Unit tested: Comprehensive test suite with 303 lines covering font loading, metrics, glyph queries, bitmap rendering, and kerning
    • Files:
  • NEW: WS2812B-V5 and WS2812B-Mini-V3 Chipset Support: Added support for newer WS2812B variants with tighter timing specifications
    • WS2812B-V5: Newer variant with 220/580ns timing (T0H: 220-380ns, T1H: 580-1000ns)
    • WS2812B-Mini-V3: Compact 3535 package with identical timing to V5
    • Both variants use tighter timing tolerances compared to original WS2812B (250/625ns)
    • Usage: FastLED.addLeds<WS2812BV5, DATA_PIN, GRB>(leds, NUM_LEDS); or FastLED.addLeds<WS2812BMiniV3, DATA_PIN, GRB>(leds, NUM_LEDS);
    • Supported across all platforms with clockless controller support
    • See timing comparison table in README.md
  • NEW: Native RGBW Support Without Emulation: The following platforms now support true RGBW LED strips (SK6812, etc.) with hardware-native 4-channel output:
    • RP2040/RP2350 (Raspberry Pi Pico): Full RGBW support with parallel output driver
    • STM32: Native RGBW output on STM32 ARM platform
    • Teensy 3.x Series: Native RGBW support added for Teensy 3.0/3.1/3.2/3.5/3.6
    • nRF52 (Nordic nRF52, Bluefruit boards): Native RGBW support via PWM peripheral
      • 4-channel RGBW output using hardware PWM peripheral
      • PWM buffer sized for maximum (RGBW), runtime selects RGB or RGBW mode
      • Separate code paths for RGB (3 bytes) and RGBW (4 bytes) for optimal performance
      • Supports up to 144 LEDs per string in RGBW mode
      • File: src/platforms/arm/nrf52/clockless_arm_nrf52.h
    • Note: Previous RGBW support via software emulation (ESP32, Teensy ObjectFLED) remains available
  • NEW: HD108/NS108 16-bit SPI Chipset Support: High-definition LED chipset with built-in gamma correction
    • 16-bit color depth (65,536 levels per channel) vs APA102's 8-bit (256 levels)
    • Automatic gamma correction (gamma 2.8) provides smooth perceptual brightness transitions
    • Higher PWM frequency (27 kHz) reduces visible flicker compared to APA102's ~20 kHz
    • 5-bit brightness control (0-31) per LED for current limiting
    • 40 MHz max clock speed (25 MHz default for stable operation on long strips)
    • Dual-byte header encoding for brightness/current control
    • Manufacturer: Newstar LED (NS108 = HD108, same chip)
    • Protocol: APA102-like but extended to 16-bit with 8 bytes per LED
      • Start frame: 64 bits (8 bytes)
      • LED frame: 2 header bytes + 6 data bytes (16-bit RGB, big-endian)
      • End frame: (num_leds / 2) + 4 bytes of 0xFF
    • Usage: FastLED.addLeds<HD108, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    • Implementation: Enhanced showPixels() with brightness caching and optimized gamma correction
    • No SD (standard definition) option available - all HD108s use gamma correction
    • See detailed protocol documentation in src/chipsets.h:1040-1183
    • Unit tests: Comprehensive test suite in tests/chipsets/test_hd108.cpp
    • Related: GitHub Issue #1045, Pull Request #2119 (thanks to @arfoll for initial implementation)
  • NEW: Vorbis Audio Decoder: Added support for decoding Ogg Vorbis audio files via stb_vorbis integration
    • Streaming Decoder: VorbisDecoder class provides frame-by-frame audio decoding from ByteStream
    • Convenience API: Vorbis::decodeAll() decodes entire files to AudioSample vectors in one call
    • Metadata Parsing: Vorbis::parseVorbisInfo() extracts sample rate, channels, and stream info without full decoding
    • Float PCM Output: Decodes to floating-point audio samples (-1.0 to 1.0 range) compatible with FastLED audio processing
    • Low-Level Wrapper: StbVorbisDecoder provides direct access to stb_vorbis for advanced use cases
    • Memory-Based: Requires entire Vorbis file in memory (suitable for embedded audio playback)
    • Platform Support: Works on all platforms with sufficient memory for audio buffers
    • Third-Party Integration: Uses Sean Barrett's stb_vorbis single-header library
    • Usage: auto decoder = Vorbis::createDecoder(); decoder->begin(byteStream); decoder->decodeNextFrame(&sample);
    • See API documentation ...
Read more

FastLED 3.10.4

Choose a tag to compare

@zackees zackees released this 16 Jun 00:05
adedfc4

FastLED 3.10.4

Bumps the bundled zccache floor to >=1.12.7 to pick up zackees/zccache#763, which version-namespaces the cache root and closes the version-shadow chain at zackees/zccache#762.

Practically: side-by-side installs (e.g. PyPI + bundled fbuild copies) no longer trample each other's daemon state, fixing the silent mid-build daemon death reported in zackees/zccache#759 and the 1.12.6 self-hash regression in zackees/zccache#760.

No FastLED source code changes — Arduino API and runtime behaviour are identical to 3.10.3.

FastLED 3.10.3: W2812 timing update - stm32F4 board support

Choose a tag to compare

@zackees zackees released this 20 Sep 20:40
  • WS2812B Reset Time Update: Enhanced compatibility with newer WS2812B chipsets
    • Updated default reset time from 50μs to 280μs across all platforms
    • Fixes intermittent issues where only first LED responds to fill_solid() and similar operations
    • Addresses GitHub issue #2067: WS2812B strips showing ~80% failure rate with latest FastLED
    • Updated 18 ARM platform clockless controllers (Apollo3, STM32, SAMD, Teensy, etc.)
    • ESP8266 clockless controller timing updated for better reliability
    • Maintains backward compatibility while supporting newer WS2812B chip revisions
  • STM32F4 Support Added: BlackPill STM32F411CE and STM32F4 family support
    • Added STM32F4 platform detection using canonical STM32F4 preprocessor define
    • Full GPIO pin mapping support for WeAct Studio BlackPill V2.0 (STM32F411CE)
    • Consolidated STM32F1/STM32F4 pin definitions to reduce code duplication
    • Added CI testing with GitHub Actions build badge for continuous validation
    • Compatible with PlatformIO ststm32 platform and Arduino framework
  • Silicon Labs MGM240 Support Added: Arduino Nano Matter and SparkFun Thing Plus Matter support
    • Resolves GitHub issue #1750: Platform support for MGM240 (EFR32MG24) wireless modules
    • Added complete platform implementation with ARM Cortex-M33 @ 78MHz support
    • Silicon Labs EMLIB integration for optimized GPIO control and clock management
    • Clockless LED controller support for WS2812, SK6812, and other standard chipsets
    • Board definitions for mgm240 target with siliconlabsefm32 platform
    • Added CI testing with GitHub Actions build badge for continuous validation

For a compile environment please see https://github.com/fastled/platformio-starter

FastLED 3.10.2

Choose a tag to compare

@zackees zackees released this 22 Aug 20:58
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 and fastmath compiler settings for this one file.
  • Ease Functions - lots and lots of ease functions! Great for animations!
  • 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
  • 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.
  • 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 and std::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
    • STM32F1 pin mapping fixes (blue pill)
  • 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

Color Boost Demo
image (3)

3.10.1 - Bug Fix for 3.10.0

Choose a tag to compare

@zackees zackees released this 24 Jun 00:45
  • 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

Choose a tag to compare

@zackees zackees released this 16 Jun 06:26
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.

Full Changelog: 3.9.20...3.10.0

3.9.20: Misc Fixes

Choose a tag to compare

@zackees zackees released this 05 Jun 04:27

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

Choose a tag to compare

@zackees zackees released this 29 May 04:44

For more information see this bug fix thread.

Hot fix #2 for

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)) or volatile 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!

Choose a tag to compare

@zackees zackees released this 28 May 07:24
  • Reverted AVR memory blow up
  • Fix odd even bug on leds on avr

#1930

FastLED 3.9.17 - stdlib compatibility, audio preview, xypath

Choose a tag to compare

@zackees zackees released this 24 May 22:12

New Project

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
    • 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
  • 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.
    • 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.
    • 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.