release_notes.md
.ttf single fonts or .ttc font collections)fl::Font::loadDefault() - Load embedded Covenant5x5 fontfl::Font::load(fontData) - Load custom TrueType font from memoryfl::FontRenderer(font, pixelHeight) - Create renderer at specified sizerenderer.render('A') - Render character with 2x2 antialiasing (default)renderer.renderNoAA('A') - Render without antialiasing for crisp pixelsrenderer.measureString("Hello") - Calculate string width with kerninggetPixel(x, y) with bounds checkingfl::shared_ptr, on-demand rendering#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)
}
}
FastLED.addLeds<WS2812BV5, DATA_PIN, GRB>(leds, NUM_LEDS); or FastLED.addLeds<WS2812BMiniV3, DATA_PIN, GRB>(leds, NUM_LEDS);setRgbw(RgbwDefault())FastLED.addLeds<HD108, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);VorbisDecoder class provides frame-by-frame audio decoding from ByteStreamVorbis::decodeAll() decodes entire files to AudioSample vectors in one callVorbis::parseVorbisInfo() extracts sample rate, channels, and stream info without full decodingStbVorbisDecoder provides direct access to stb_vorbis for advanced use casesauto decoder = Vorbis::createDecoder(); decoder->begin(byteStream); decoder->decodeNextFrame(&sample);FastLED.addBulkLeds(), BulkClockless, BulkStripConfig) have been deprecated and removedfl/channels/channel.h for the new API documentationaddBulkLeds() methods removed from FastLED classBulkClockless template class removedBulkStripConfig struct removedFastLED.setXXX() pattern - no need to access internal managersFastLED object, full functionality ESP32-only, safe no-op stubs on other platforms):
FastLED.setDriverEnabled(name, enabled) - Enable/disable specific driver by nameFastLED.setExclusiveDriver(name) - Enable only one driver, disable all others (forward-compatible)FastLED.isDriverEnabled(name) - Query if a driver is currently enabledFastLED.getDriverCount() - Get total number of registered driversFastLED.getDriverInfo() - Get full state of all drivers (name, priority, enabled state)// Force RMT driver only (disables SPI, PARLIO, and any future drivers)
FastLED.setExclusiveDriver("RMT");
// Or selectively enable/disable
FastLED.setDriverEnabled("SPI", false); // Disable SPI
FastLED.setDriverEnabled("PARLIO", true); // Enable PARLIO
// Query driver state
if (FastLED.isDriverEnabled("RMT")) {
Serial.println("RMT driver is active");
}
// Inspect all registered drivers
auto drivers = FastLED.getDriverInfo();
for (const auto& driver : drivers) {
FL_WARN(driver.name << ": priority=" << driver.priority
<< " enabled=" << (driver.enabled ? "YES" : "NO"));
}
getDriverInfo() returns fl::span with cached results (no heap allocations)setExclusiveDriver() automatically disables future drivers, ensuring predictable behaviorexamples/Validation/Validation.ino for usage with FastLED.setExclusiveDriver("RMT")FastLED.addLeds<APA102, 2, 12>(leds, NUM_LEDS) - pick any DATA/CLOCK pins you wantUCS7604 or UCS7604HDFastLED.addLeds<UCS7604, DATA_PIN, GRB>(leds, NUM_LEDS);FastLED.addLeds<UCS7604HD, DATA_PIN, GRB>(leds, NUM_LEDS);#define FASTLED_ESP8266_UART before including FastLED.hFastLED.addLeds<UARTController_ESP8266<GRB>>(leds, NUM_LEDS);fl::ParlioLedDriver instance (see example)#define FASTLED_ESP32_LCD_DRIVER before including FastLED.h#define FASTLED_ESP32_LCD_DRIVER before including FastLED.h#define FASTLED_ESP32_LCD_RGB_DRIVER before including FastLED.hstatic_assert check in clockless controllers prevents compilation with these pinsFASTLED_ASSERT in driver group initialization catches dynamic pin assignmentsFASTLED_UNUSABLE_PIN_MASK for ESP32-S2/S3fl/isr.h): Unified interrupt handling across all platforms
fl::isr::attachTimerHandler(config, &handle) / fl::isr::attachExternalHandler(pin, config, &handle)fl/pin.h): Cross-platform digital and analog I/O with Arduino-compatible API
analogWrite16(pin, value) for 16-bit PWM control (platform-dependent support)fl_parallel_spi_isr_rv.h/cpp):
SingleSPI_Blocking_ESP32, DualSPI_Blocking_ESP32, QuadSPI_Blocking_ESP32EZWS2812_GPIO: Always-available GPIO controller with cycle-accurate timing for 39MHz and 78MHz CPUsEZWS2812_SPI: Optional SPI-based controller for maximum performance (define FASTLED_USES_EZWS2812_SPI)fill_solid() and similar operationsSTM32F4 preprocessor definenucleo_f429zi, nucleo_f439ziststm32 platform and Arduino frameworkmgm240 target with siliconlabsefm32 platform-O3 and fastmath compiler settings for this one file.inoise8(x, y, z)) range utilization improved from 72.9% to 88.6%
#define FASTLED_USE_ADAFRUIT_NEOPIXEL before including FastLED#define FASTLED_HSV_CONVERSION_RAINBOW (default)#define FASTLED_HSV_CONVERSION_SPECTRUM#define FASTLED_HSV_CONVERSION_FULL_SPECTRUM-DFASTLED_HSV_CONVERSION_RAINBOW-DFASTLED_HSV_CONVERSION_SPECTRUM-FASTLED_HSV_CONVERSION_FULL_SPECTRUMfl::await or install a callback to be invoked. The latter is recommended.std:string and std::sstream, which is missing on platforms like avr. So we had to write our own api to handle this../testEVERY_N_MILLISECONDS_RANDOM(MIN, MAX) macro for sketches.CRGB CRGB::blendAlphaMaxChannel(const CRGB& upper, const CRGB& lower) for fx blending without alpha.blendAlphaMaxChannel(...)fl/time_alpha.h
update(...) will give you the current time progression.uint8_t from 0 -> 255 representing current animation progression.new
#define FASTLED_NOT_USES_OBJECTFLED before #include "FastLED.h"FASTLED_DBGFASTLED_WARNFASTLED_ASSERT#define FASTLED_RMT_USE_DMA#include "FastLED.h"#define FASTLED_ESP32_USE_CLOCKLESS_SPISpecial thanks to Yves and the amazing work with the 12 way parallel driver. He's pushing the limits on what the ESP32-S3 is capabable of. No joke.
If you are an absolute performance freak, check out Yves's advanced version of this driver with ~8x multiplexing through "turbo" I2S:
https://github.com/hpwit/I2SClockLessLedVirtualDriveresp32s3
#define FASTLED_USES_OBJECTFLED#include "FastLED.h" - that's it! No other changes necessary!#define FASTLED_OVERCLOCK 1.2 @ a 20% overlock.#define FASTLED_RMT5_RECYCLE=1 before #include "FastLED.h"FASTLED_ASSERT(true/false, MSG) now implemented on ESP32, other platforms will just call FASTLED_WARN(MSG) and not abort. Use it via #include fl/assert.h. Be careful because on ESP32 it will absolutely abort the program, even in release. This may change later.#define FASTLED_RMT5_RECYCLE=1. The new behavior may become the default if it turns out this is more stable.FastLED.h in the last release (oops!)IRAM_ATTR#define FASTLED_RMT5_RECYCLE=0 before you #include "FastLED.h"FASTLED_ALL_PINS_HARDWARE_SPI is active.fl - the new FastLED namespace
fl namespace. This is now located in the fl/ directory. These files have mandatory namespaces but most casual users won't care because because all the files in the fl/ directory are for internal core use.-DFASTLED_NAMESPACE=1. This will force it on for the entire FastLED core.fl::string: a copy on write String with inlined memory, which overflows to the heap after 64 characters. Lightning fast to copy around and keep your characters on the stack and prevent heap allocation. Check it out in fl/str.h. If 64 characters is too large for your needs then you can change it with a build-level define.fl/vector.h:
fl::FixedVector: Inlined vector which won't ever overflow.fl::vector: Do you need overflow in your vector or a drop in replacement for std::vector? Use this.fl::SortedHeapVector: If you want to have your items sorted, use this. Inserts are O(n) always right now, however with deferred sorting, it could be much faster. Use fl::SortedHeapVector::setMaxSize(int) to keep it from growing.fl/map.h
fl::SortedHeapMap: Almost a drop in replacement for std::map. It differs from the fl::SortedHeapVector because this version works on key/value pairs. Like std::map this takes a comparator which only applies to the keys.fl::FixedMap: Constant size version of fl::SortedHeapMap but keeps all the elements inlined and never overflows to the heap.fl/set.h
fl::FixedSet: Similar to an std::set. Never overflows and all the memory is inlined. Ever operation is O(N) but the inlined nature means it will beat out any other set as long as you keep it small.fl/scoped_ptr.h:
fl::scoped_ptr.h:
std::unique_ptr, this allows you to manage a pointer type and have it automatically destructed.fl::scoped_array.h: Same thing but for arrays. Supports operator[] for array like access.fl/slice.h: Similar to an std::span, this class will allow you to pass around arrays of contigious memory. You can pop_front() and pop_back(), but it doesn't own the memory so nothing will get deleted.fl/ptr.h
fl::Ptr<T>, a ref counted intrusive shared pointer. "Intrusive" means the referent is inside the class the pointer refers to, which prevents an extra allocation on the heap. It's harder to use than std::shared_ptr because it's extremely strict and will not auto-covert a raw pointer into this Ptr type without using Ptr<T>::TakeOwnership(T*). This is done to prevent objects from double deletion. It can also take in pointers to stack/static objects with Ptr<T>::NoTracking(T*), which will disable reference counter but still allow you usefl::XYMap which is the class
form of this. This also means that you can apply blur effects with multiple led panels, where XY() assumed you just had only one array of leds.sensors/pir.h
fl::Pir: This is a basic PIR that will tell you if the sensor is curently triggered. It doesn't do much else.fl::AdvancedPir: An extended version of fl::Pir which gives transition effects as it turns on and off. Here is what the
the constructor looks like: fl::Pir(int pin, uint32_t latchMs = 5000, uint32_t risingTime = 1000, uint32_t fallingTime = 1000).
You will give it the pin, an optional latch time (how long it stays on for), the rising time (how long to go from off to on) and the falling
time which is how long it takes to go from on to off. By default it will ramp on for one second, stay on for 5 seconds at full brightness, then
start turning off for one second. All you have to do is give it the current millis() value.examples/fx/NoiseRingFASTLED_OVERCLOCK
#define FASTLED_OVERCLOCK 1.2 (gives 20% overclock)."FastLED.h"ESPAsyncWebServer.h namespace collision with fs.h in FastLED, which has been renamed to file_system.hExample of how to enable overclocking.
#define FASTLED_OVERCLOCK 1.2 // 20% overclock ~ 960 khz.
#include "FastLED.h"
fl
FASTLED_FORCE_NAMESPACEFASTLED_RMT5=0 to get back the old behavior.FASTLED_HD_COLOR_MIXING=0.FASTLED_DEFINE_AVR_MILLIS_TIMER0_IMPL=1For sketches that do a lot of heavy processing for each frame, FastLED is going to be significantly faster with this new release.
How much faster?
I benchmarked the animartrix sketch, which has heavy floating point requirements (you'll need a Teensy41 or an ESP32S3 to handle the processing requirements).
FastLED 3.7.X - 34fps FastLED 3.9.0 - 59fps (+70% speedup!)
Why?
In FastLED 3.7.X, FastLED.show() was always a blocking operation. Now it's only blocking when the previous frame is waiting to complete it's render.
In the benchmark I measured: 12 ms - preparing the frame for draw. 17 ms - actually drawing the frame.
@ 22x22 WS2812 grid.
So for FastLED 3.7.X this meant that these two values would sum together. So 12ms + 17ms = 29ms = 34fps. But in FastLED 3.9.0 the calculation works like this MAX(12, 17) = 17ms = 59fps. If you fall into this category, FastLED will now free up 17ms to do available work @ 60fps, which is a game changer.
As of today's release, nobody else is doing async drawing. FastLED is the only one to offer this feature.
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS).setRgbw(RgbwDefault());PixelController<>::as_iterator(...)FASTLED_EXPERIMENTAL_ESP32_RGBW_ENABLEDBoard support added
Adds Arduino IDE 2.3.1+ support in the idf-5.1 toolchain The following boards are now tested to compile and build
This is a feature enhancement release
This is a bug fix release
show() would then block forever. We now given a max timeout so that in the worse case scenario there will be a momentary hang of portMAX_DELAY.This release incorporates valuable improvements from FastLED contributors, tested and explored by the world-wide FastLED community of artists, creators, and developers. Thank you for all of your time, energy, and help! Here are some of the most significant changes in FastLED 3.7.0:
This release incorporates valuable improvements from FastLED contributors, tested and explored by the world-wide FastLED community of artists, creators, and developers. Thank you for all of your time, energy, and help! Here are some of the most significant changes in FastLED 3.6.0:
This release incorporates dozens of valuable improvements from FastLED contributors, tested and explored by the world-wide FastLED community of artists, creators, and developers. Thank you for all of your time, energy, and help! Here are some of the most significant changes in FastLED 3.5.0:
We also want to note here that in 2020, Github named FastLED one of the 'Greatest Hits' of Open Source software, and preserved an archived copy of FastLED in the Arctic Code Vault, the Bodleian Library at Oxford University, the Bibliotheca Alexandrina (the Library of Alexandria), and the Stanford University Libraries. https://archiveprogram.github.com/greatest-hits/