Update error handling guard clause to include time check.
The simpler "!enabled || strip.isUpdating()" pattern regularly causes usermods to stop responding when many LEDs are driven.
this guide is only for reference and reading - right now the content is not liked for AI agents - neither coderabbit nor copilot will automaticially use the file.
Emphasized the requirement for clear pull request descriptions.
It's already mentioned 8n the general instructions file, but copilot still was overwriting the iinial description (good) with a delta-checklist on rework (bad).
Fix SSDP M-SEARCH response in Espalexa to match real Philips Hue
bridge behavior and UPnP spec, addressing Alexa discovery failures:
1. Fix ST header capitalization: basic:1 → Basic:1 (UPnP spec)
2. Fix USN format to include full device type URN
3. Fix hue-bridgeid to use uppercase EUI-64 format (16 hex chars)
4. Increase CACHE-CONTROL max-age from 100s to 86400 (24 hours)
Fixes#5488, relates to #4875
Agent-Logs-Url: https://github.com/wled/WLED/sessions/c3fb311b-1349-48b1-abfd-6a4aca8c7a77
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
Misspelled WLED_ENABLE_* / WLED_DISABLE_* flags are silently ignored by the preprocessor, causing features to be incorrectly included or excluded with no compiler warning (e.g. WLED_IR_DISABLE instead of WLED_DISABLE_INFRARED).
This PR adds an AI rule that enforces checking of feature flags against a curated list.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com>
* comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps.
* repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections.
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
if the presets.json file initially contains ``{}`` (valid JSON, could be created by user edit), we need to first rewind the file. Otherwise the result would be ``{}{"0":{}}`` (ivalid JSON)
* fixed problem on S3: turns out to be mem alignment
* fixed scaling for C3
* code cleanup, added arduinoFFT back in, added ifdefs & description
also added major peak and frequency bin calculation for DSP FFT
* moved ifdefs to correct place, separated sample filter & FFT filter application
post FFT band pass and IIR applied to samples are now separated: I found in testing that applying the sample filter helps with aliasing into base-bands, there is no need to hard-cut the lowest frequencies after FFT.
* changed sample low pass cutoff from 80Hz to 90Hz
better anti-aliasing at minimal loss of base frequency.
* code cleanup and minor speed improvement
- moved scaling of FFT values into fftAddAvg() to use ferwer operations
- added "using" for math types, removing some ifdefs and duplications
* new font format: *.wbf with a 12byte header, bit packed data and support for variable char width
* add support to load custom fonts from file system
* UTF-8 to unicode support functions
* support for any unicode offset in char 128-255 enables many international chars
* update built-in fonts with similar but nicer ones
* update pixelforge scrolling text tool with a preview and support for custom fonts
* accompanied by Font Factory tool (pixelforge) to easily create custom fonts from various formats
* removed fastled dependencies
- copied relevant functions
- optimized some of them for ESP32
* added perlin functions from PR, code cleanup. work in progress
* added hsv2rgb16rainbow function, some cleanup
- new rainbow function is faster and more accurate than original fastled function
* updated conversion functions (now faster), cleanup, optimizations
* code cleanup, moved (most) fastled functions into fastled_fcn.cpp
- resolves licensing issue
- moved PRNG into its own space
- prettified some code
* fixed prng: it now generates a full sequence of random numbers, thx @TripleWhy for pointing out the flaw
* rename to fastled_slim, add hsv2rgb() convenience aliases, fix FX usage
* improve ease8inOutCubic() accuracy
* fix background in twinklefox, minor optimization in PS (always use gamma LUT, no ifs)
* bugfixes in FX, adding white and cct transition to slow transition FX
Co-authored-by: Frank <91616163+softhack007@users.noreply.github.com>
Clean-up and simplification of strip.service() after individual effect FRAMETIME was removed.
* Activation "_frametime" is now the same for all effects, so effects scheduling based on individual frametime is not needed any more
* Special handling for mode_static is obsolete, because the solid effect does not have a different timing any more
* Ensures a safe fallback segment after servicing to avoid stale state.
* Brightness changes use a capped refresh threshold to avoid excessive redraws.
* load pixel forge tools from json file, bugfixes
- load available external tools from a json file instead of hard-coding them in
- add buttons to update or delete tools (instead of manually deleting files in /edit)
- fixed bug that file system memory was not updated after uploading or deleting files
- fixed a bug where gifs with a space would not display
- fixed bug of page not loading properly (out of sync access to tabSw() )
- remove pixelforge from ESP8266 1m builds (does not fit)
- add inline html page if pixelforge is not built in to avoid 404
@coderabbitai caught the problem, but its fix suggestion was out to
lunch on this one. Passing an unsigned char to String.concat() appends
it as a number instead of appending the character.
Instead, mask the unneceeded bits.
Discard IPv6 RA packets, which cause LwIP to overwrite the IPv4 DNS
servers, resulting in DNS queries hanging up because there are no
accessible servers.
In startTransition(), a copy of the old effect's data buffer is made using raw malloc() — it deliberately bypasses allocateData(). This buffer is never added to the _usedSegmentData static counter (only allocateData() does that). If the old effect then calls allocateData() it causes _usedSegmentData to underflow.
https://github.com/wled/WLED/issues/5427#issuecomment-4103228702
Bug Fixes
* Improved hostname sanitization and buffer-size safeguards to prevent truncation and ensure DNS-compliant names.
* Hostname is now applied earlier during network setup and on reconnects (ESP32), improving connectivity and ensuring settings take effect.
* Solves the problem that ESP32 boards show as "ESP-xxxxxx" on the network, no matter if DNS name is defined or not
* (breaking fix) prevent hostnames with double ``WLED-`` prefix, like ``wled-WLED-kitchen``
New Features
* Added a length-aware hostname retrieval API with an mDNS-preference option and robust fallback behavior.
* Preserved legacy compatibility by providing a length-aware alias for legacy hostname preparation.
Open Ends
* mDNS name is not sanitized when registering the mDNS endpoint, to avoid breaking previous functionality
Make AsyncDNS queries return a future-like object backed by a smart
pointer. This ensures that the client cannot release the backing
memory while the dns query callback is still holding a reference to it,
preventing any use-after-free cases.
* use same style as other settings pages
* Hide "back" button while update is in progress
* set "download latest binary" URL and badge based on info.repo; directly link to "latest" release
* correct bad name of "Security & Updates" page
* ensure that "update bootloader" section get hidden when not supported
Updated instructions regarding generated html_*.h files to clarify that they should not be committed, and they don't need to be re-generated in any PR.
* Info page updates and minor re-styling
* added GitHub repo (link)
* added Total LEDs
* removed lwip major version on esp32
* two horizontal lines for better readability
* add rel="noopener noreferrer" for improved security
* When using target="_blank", it's a security best practice to include rel="noopener noreferrer" to prevent the new page from accessing window.opener.
* Added the Spinning Wheel effect into the user_fx usermod
* Fixed integer overflow when storing color scale in aux1. And added a comment about the velocity scaling.
* Additions/changes:
* Added Color Per Block checkbox. Enabled will set the spinner LEDs to the same color (instead of changing colors depending on the palette and LED position).
* Added Sync Restart checkbox. Enabled means that all spinners will restart together (instead of individually) after they have all stopped spinning.
* Added resizing the spinner slider (between 1 and 10 LEDs).
* Changed how we do random speed and slowdown start time (sliders set to 0 = random).
* tweaks here and there
* One minor fix for the spinner colors
* Changed the two analogRead() to hw_random16()
* Changes from SEGLEN to vstripLen suggested by coderabbitai, but it's not working correctly now. Committing and pushing so coderabbitai can check the latest code.
* Rolled back changes from vstripLen to SEGLEN as that is what works correctly. Also changed to the global paletteBlend.
* Fixed a color issue by using ColorFromPaletteWLED() instead of color_from_palette(). Also removed color_wheel() and the Color Mode option as it's very similar to the new color function. And now using strips variable instead of SEGMENT.nrOfVStrips() after the initial assignment at the top of the code.
* Added the ability to spin the wheel(s)/spinner(s) with a push button or the new Spin Me checkbox.
* Set default of check1 to 1 so it will automatically spin.
* New Effect: Color Clouds
ColorClouds: Random start points for clouds and color
ColorClouds: new config option 'More red'
* ColorClouds: Incorporated review comments
- Support for color palettes
- Use perlin16() instead of inoise16()
- Use cos8_t() instead of cos8()
* ColorClouds: incorporated more review comments
* ColorClouds: incorporated final review comment
When LTO is enabled, the map file no longer provides a positive
indication of whether a given object file has contributed to the final
binary. Instead use nm to parse the debug data in the .elf file.
Co-Authored-By: Claude <noreply@anthropic.com>
perParticleSize was disabled by default which is wrong. Fixed some bugs regarding to this new parameter: it is now set by default in PS, adusted FX accordingly
* Added Morse Code effect to the user_fx usermod
* Added a few comments
* Added punctuation and end-of-message codes, and changing them will force a re-draw.
* Fixed mode name in addEffect
* cosmetic changes
* * removed PROGMEM from letters and numbers arrays.
* changed 1024 to a constexpr named MORSECODE_MAX_PATTERN_SIZE.
* added MORSECODE_MAX_PATTERN_SIZE to build_morsecode_pattern().
* added boundary checked when adding patterns to the array.
* changed code to allocate per-segment storage for pattern.
* More bounds checking added.
* Added a lookup table for punctuation morse codes.
* Removed PALETTE_MOVING_WRAP macro as it's not used in this effect.
* Moved all static variables to SEGENV.data
* Now using a bit array instead of a bool array
* added a check to see if the pattern is empty
* Added "color by word" option, moved Color modes to a slider and added a couple comments to top comment block.
* Removed return FRAMETIME
* A few changes suggested by coderabbit.
* A few changes suggested by coderabbit
* Add flashing effect on line clear in TetrisAI_v2.
See https://imgur.com/1dsNCVd for a demo.
* Address feedback for tetris flashing effect.
* Address width == 32 case for isLineFull
Expand the parsing of custom_usermods to accept the same syntax as
lib_deps. This allows external usermods to appear on the
custom_usermods lines. Also includes comment handling.
Co-Authored-By: Claude <noreply@anthropic.com>
Fix signed-byte handling in SHA256 hex conversion.
When bootloaderSHA256Cache bytes >= 0x80 are assigned to a signed char, they sign-extend to negative values. Right-shifting negative values produces incorrect results (e.g., 0xFF becomes -1, which shifts incorrectly). This causes wrong hex digit output for non-ASCII hash bytes.
Use a custom linker section to hold dynamic arrays such as the
usermod list. This provides an extensible solution for wider use
in the future (such as FX or Bus drivers), as well as IDF v5
compatibility.
When users click "Skip reporting" without the checkbox, now saves
the current version to version-info.json. This prevents the prompt
from appearing again until the version actually changes.
Behavior:
- Skip without checkbox: Saves version, will prompt on next version
- Skip with checkbox: Sets neverAsk=true, never prompts again
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- negative blend values create "exclusive" zones where only one channel is on, blending happens in the center, total is always 255 (non additive)
- CCT from RGB has to be calculated from original color to be accurate
- Fixed CCT brightness ad calculate colorbalance before white
- allow new exclusive blending for 2-wire CCT
Don't use aPLL clock for I2S (and PDM) microphones.
Ethernet with internal RMII clock (typically on GPIO 0/16/17) uses the Audio PLL (APLL) to generate the 50 MHz reference clock for RMII.
see https://github.com/wled/WLED/issues/5391
* update all config pages with sections
* some renamig
* reordered LED settings with more natural "workflow"
* add titles and changed some wording / outdated comments
* reduce scope of some variables to "static"
these are not used anywhere else. Making them static avoid name conflicts, cleans up the global scope and in some cases allows for better optimization by the compiler.
* remove unused reference ``tz``from analog clock usermod
* side-catch: remove two "local var shadows global var" warnings
* reduce scope of functions declared globally, but not used anywhere else
Safe to make static
* declared in fcn_declare.h, only used locally in one file
* not declared in fcn_declare.h, only used locally
* HUB75 small optimization
make bit array functions "static inline"
-> better for optimization, saves some bytes because the compiler does not need to preserve a non-inline function copy for external references.
* a few more static functions
as suggested by the rabbit.
these macros are
* not used any more
* dangerous because they don't time out
* dangerous because they use an internal mutex of the ledc driver (not part of the LEDC API)
* remove "return FRAMETIME" from all FX, fix timing for some FX
- all FX now render every frame, no more "speed up" during transitions
* fix missing return by adding FS_FALLBACK_STATIC macro
* add FX_FALLBACK_STATIC also to user_fx
* remove obsolete seg.next_time
* Enable inverse gamma correction (gamma < 1.0)
Allow gamma values from 0.1 to 3.0 instead of restricting to > 1.0.
This enables inverse gamma curves for use cases requiring brightened
mid-tones and compressed highlights.
Changes:
- Update backend validation in set.cpp and cfg.cpp to accept 0.1-3.0
- Update HTML form min value from 1 to 0.1
Co-authored-by: Flo <flo@Mac.lan>
Co-authored-by: Damian Schneider <daedae@gmx.ch>
* Update CONTRIBUTING.md
based on AI proposals in https://github.com/wled/WLED/issues/5348
* Update CONTRIBUTING.md
official style is "GitHub"
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* minor style updates
* styling and perfection
addressing minor recommendations by the rabbit
* cherry-picking some improvement proposals from the rabbit
* extended opening section
* section groups: Getting Started, During Review, After Approval, Coding Guidelines
* removed duplications in AI section
* improve friendly style
* minor corrections
* nitpick
* ok, some more nitpick
* Minor consistency tweak with other headings/sentences
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Fix slop from 5168
Remove the redundant field from the info structure and report what we
actually want to know.
* Fix psram size estimate
Shorten the name, and round up -- getPsramSize() is the usable size,
not the total size (the difference is allocator overhead).
* Let psram builds work without it
* Remove impossible cases in psram reports
* Squashed commit of the following:
commit 70fe1fc76d3d88947d4c9f8b43d58ea90f944230
Author: Benjamin Kraus <ben@benkraus.com>
Date: Fri Oct 31 20:52:13 2025 -0400
Added support for enterprise WiFi.
* Updated based on feedback from CodeRabbit.
* Fixed issue with strncmp identified by CodeRabbit.
* Replaced split declaration-then-assignment with a single statement.
* Revert whitespace only changes.
* Move WPA enterprise behind a feature flag.
Use a stateful object to allow bootloader size calculation to operate
on a stream of data blocks instead of requiring a single flat read.
This allows it to work when calculating the bootloader hash as well
as during update validation.
Co-authored-by: Codex <codex@openai.com>
These changes eliminate an elaborate race condition
* add dedicated function to handle on/off and relay
* add clarifying comment on output set order
* add define for relay delay, honor forceOff in all cases
When automatic reporting was triggered, the third parameter (alwaysReport)
was missing in the reportUpgradeEvent call. This caused the preference to
be lost after the first automatic report, requiring the user to be prompted
again on the next upgrade.
Fixed by passing 'true' as the third parameter to maintain the user's
preference for all future automatic reports.
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
* full refactoring, added live preview, better minifying in cdata.js
* update main UI buttons, support for gaps in cpal files, cpal UI cleanup
* fixed some layout issues, added un-ordered cpal deletion
* changed to tab indentation, paste button border color now holds stored color
* fix preview to work properly and some other fixes in UI
* always unfreeze
* new approach to loading iro.js, add harmonic random palette, many fixes.
* decoupling iro.j, update UI of cpal.htm
- load iro.js sequentially
- no parallel requests in cpal.htm
- update UI buttons
- fix showing sequential loading of palettes (using opacity)
- better UX for mobile (larger markers, larger editor)
- various fixes
* small change to buttons
* load iro.js dynamically, remove iro.js from index.htm, revert changes to cdata.js
* improved visibility for very dark/black palettes and markers
Per feedback, simplified button text since the checkbox already
provides context about saving choices for future updates.
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- Remove duplicate toast messages when checkbox is checked
- Show appropriate message based on saveChoice state
- Ensure error toasts are visible after overlay is removed
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- Replace 4-button design with 2 buttons: "Report this update" and "Skip reporting"
- Add checkbox "Save my choice for future updates" (checked by default)
- When checkbox is checked:
- "Report this update" enables automatic reporting for future upgrades
- "Skip reporting" saves "never ask" preference
- When unchecked, choice applies only to current prompt
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
Change default LED pin to 4 in esp32 ethernet builds and set AR default to "no mic" mode.
The "normal" default LED pin 16 is conflicting with pins needed by many ethernet boards, which can cause random crashes.
Main branch without Tetris
Flash: [======== ] 79.8% (used 1255301 bytes from 1572864 bytes)
Main branch with Tetris (+196kb)
Flash: [========= ] 92.3% (used 1452049 bytes from 1572864 bytes)
This commit with Tetris (+6kb, 97% less flash)
Flash: [======== ] 80.2% (used 1261625 bytes from 1572864 bytes)
* Safety Checks for UI, fix for cfg exceeding LED limit
* improvements to low heap check
* add `isPlaceholder()` to bus, some fixes
* remove `disableForceReconnect` for better future implementation
* add "glitch gating" for C3 and check heapy every 5 seconds instead of every secondd
* replace magic number with the correct define, more robust bus defer by look-ahead
In the event that a Bus fails to initialize, or the memory validation
fails, keep the configuration around so the settings contents don't
change out from under the user.
---------
Co-authored-by: Will Miles <will@willmiles.net>
Fixes some deprecation warnings during nightly build runs. Already tested in WLED-MM.
* upgrade action-github-changelog-generator to 2.4
* decode changelog into a temporary file (needed for changelog-generator 2.4)
* renamed exclude-labels (deprecated); added some more tags for filtering
- add touch pin option
- add wake-up on timer macro
- fix powerup behaviour: now works as intended i.e. if no sleep delay set, it enters deepsleep on powerup but only then
- apply macro after wake up even if the window is missed
- respect date-range setting of macro
- removed non-existing pin from touch list
- removed non existing voltageCheck setting
- fixed incorrect threshold setting
- code cleanup
- fix pullup/pulldown for deep-sleep GPIOs
pin init is now working correctly, tested on all platforms
* remove unused statement
---------
Co-authored-by: Damian Schneider <daedae@gmx.ch>
- PulLightControl UM: dont release a lock you do not own
- off-by-one error in extractModeSlider (used only in rotary in UM)
- safety check in playlist in case something goes horribly wrong
* Usermod Temperature: use full 12-bit precision
* Temperature Usermod: fix DS1822 and DS18B20 family code
* Add Dropdown to select 9 or 12 bit resolution
* Add 10 and 11 bit resolution, Correct rounding towards negativ inf
If we cap the acceptable version, it becomes impossible to increase it:
older firmwares will reject it. Instead we must guarantee
backwards compatibility so long as the magic number is the same.
If a breaking change is required in the future, a new magic number
should be used to identify it.
Add a field to the OTA metadata structure indicating the oldest base
version it's safe to install this update /from/. This provides a clear
path forward in case there are incompatibilities, eg. some case
(bootloader compatibility) where 0.16.0 cannot be installed safely from
0.15.2, but a transitional 0.15.3 can arrange the groundwork.
Adding symmetrical but random pushing leads to better stacking, also pushing more if large particles are too close helps to separate them better. Pushing them every frame also helps.
Pushing only particle1 as it was tends to lead to more collapsing and some random movement within a pile. There was also a bug which applied way to much velocity unnecessarily.
fix for #4298 - no conflict with DMX output
Removes a compile-time error that was blocking compilation when DMX output mode was enabled, allowing successful builds with DMX support.
Important: this fix does not address the output buffer congestion problems that usually make WLED unstable with >100 LEDs on DMX Serial output. It only removes the compile-time blocker in audioreactive.
* use sequential loading for all UI resources
- load common.js and style.css sequentially for all config pages
- restrict all requrests in index.js to single connection
- retry more than once if requests fail
- incremental timeouts to make them faster and still more robust
- bugfix in connectWs()
- on page load, presets are loaded from localStorage if controller was not rebooted
- remove hiding of segment freeze button when not collapsed
replaces the pixel magic tool with a much more feature-rich tool for handling gif images. Also adds a scrolling text interface and the possibility to add more tools with a single button click like the classic pixel magic tool and the pixel-painter tool.
Enhanced particle system rendering & 1D collision handling
- added improved and faster large size rendering to 1D and 2D system
- better size control as size is now exactly mappable to pixels so it can be matched exactly to the collision distance
- no more gaps due to collision distance mismatch
- much faster: saw up to 30% improvement in FPS (2D system)
- adding mass-ratio to collisions for different sized particles
- also adjusted some of the FX to make better use of the new rendering
- added per-particle size rendering to 1D system
- improved and simplified collision handling in 1D system, much more accurate and (almost) no pass-throughs
- removed local blurring functions in PS as they are not needed anymore for particle rendering
- fixed outdated AR handling in PS FX
- fixed infinite loop if not enough memory
- updated PS Hourglass drop interval to simpler math: speed / 10 = time in seconds and improved particle handling
- reduced speed in PS Pinball to fix collision slip-through
- PS Box now auto-adjusts number of particles based on matrix size and particle size
- added safety check to 2D particle rendering to not crash if something goes wrong with out-of bounds particle rendering
- improved binning for particle collisions: dont use binning for small number of particles (faster)
- Some cleanup
- bugfix in mass based 2D collisions
- added improved and faster large size rendering to 1D system
- added per-particle size rendering to 1D system
- improved and simplified collision handling in 1D system
- removed local blurring functions in PS as they are not needed anymore for particle rendering
- adapted FX to work with the new rendering
- fixed outdated AR handling in PS FX
- fixed infinite loop if not enough memory
- updated PS Hourglass drop interval to simpler math: speed / 10 = time in seconds and improved particle handling
- reduced speed in PS Pinball to fix collision slip-through
- PS Box now auto-adjusts number of particles based on matrix size and particle size
- added safety check to 2D particle rendering to not crash if something goes wrong with out-of bounds particle rendering
- improved binning for particle collisions: dont use binning for small number of particles (faster)
- Some code cleanup
- Renamed hasPSRAM field to psramPresent in /info endpoint (json.cpp)
- Updated usage report to use psramPresent field (index.js)
- Removed problematic _codeql_detected_source_root symlink
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- Changed division from (1024 * 1024) to (1024UL * 1024UL)
- Ensures proper unsigned long type to prevent overflow issues
- All tests pass and firmware builds successfully
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- Modified reportUpgradeEvent in index.js to use new hasPSRAM and psramSize fields
- Changed from calculating psramSize from free PSRAM to using total PSRAM size from /info endpoint
- Both fields now correctly sent in upgrade usage reports to usage.wled.me
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- Added hasPSRAM boolean field indicating if hardware has PSRAM
- Added psramSize field with total PSRAM size in MB
- Kept existing psram field for backward compatibility (free PSRAM in bytes)
- All fields only included for ESP32 architecture
- Tests passed and firmware builds successfully
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- better size control as size is now exactly mappable to pixels so it can be matched exactly to the collision distance
- no more gaps due to collision distance mismatch
- much faster: saw up to 30% improvement in FPS
- also adjusted some of the FX to make better use of the new rendering
* remove extra flash section, rename board file
* matrixportal: change partitions to standard 8MB
plus minor name adjustment (adding "for WLED")
Co-authored-by: Frank <91616163+softhack007@users.noreply.github.com>
update for esp32-S3 builds
* support for 32MB Flash
* added board manifest for adafruit matrixportal
* some cleanup, removed obsolete build flags
* new example how to "compile for speed" in platformio_orride.sample.ini
I don't know how the bad example "-D SR_DMTYPE=-1" made it into platformio_override.sample.ini 🫣
mic type -1 = 255 was never supported by AR, and lead to undefined behavior due to a missing "case" in setup().
Fixed. Its still a stupid build_flags option, but at least now its handled properly.
SR_DMTYPE=-1 will lead to undefined behavior in AR, because for S3 there is no "default" case in the usermod setup(). It should be sufficient to set pins to "-1" if you want to avoid "pin stealing".
esp32S3_PSRAM_HUB75:
* use 16MB partinion.csv (board has 16MB flash, lets use that)
* example how to switch from "compile for small size" to "compile for speed"
adafruit_matrixportal_esp32s3:
* small reordering of lines
* commented out partition for adafruit bootloader, reverted to standard 8MB partitions
* removed obsolete "-D CONFIG_LITTLEFS_FOR_IDF_3_2" => this was only for the old "lorol/LITTLEFS" whic is not used any more in WLED
* commented out "-D ARDUINO_USB_MODE=1", because users have reported that it leads to boot "hanging" when no USB-CDC is connected
* Added buildenv and 32MB partition for esp32s3-WROOM-2 with 32MB flash
* disabled "-mfix-esp32-psram-cache-issue" warning for -S2 and -S3 (only necessary for classic esp32 "rev.1", but harmful on S3 or S2)
forgot to adjust the debug condition in my previous commit.
NB: the condition only shows a debug message when the max wait time was exceeded, which can only happen when line 1692 has waited for the maximum allowed time. ->Is this intended?
the timing logic did not work in case that millis()+100 + frametime rolls over; in this case millis() > maxWait, and waiting would be skipped which might lead to crashes.
-> logic slightly adjusted to be robust against rollover.
* improvements to Aurora FX
- converted to integer math, increasing speed on all ESPs, also shrinks code size
- caching values to avoid repeated calculations
- CRGBW instead or CRGB, adds white channel support when not using palette
- fix for new brightness/gamma handling
* overflow & unsigned fix
- add better support for 1D gifs: use the full gif, row by row, scale if needed
- add blur slider to image FX
- improved safety checks to avoid crashes
- add "fast path" if image size matches virtual segment size
In my previous commit I've overlooked that build_flags from esp32_idf_V4 are inherited by esp32S2, esp32s3 and esp32c3 --> clashed with USB-CTC settings of these boards.
So the correct way to propagate esp32-only flags is to add them in the "lower level" build envs individually.
this flag got lost between 0.15 and 0.16.
Even when NO classic esp32 has USB-CDC., it seems that omitting the flag can cause strange behavior in the arduino-esp32 framework.
* catch some error that would lead to undefined behavior
* additional debug messages in case of errors
* robustness: handle OOM exception from decoder.alloc() gracefully
- no mendatory external JS dependency, works in offline mode
- optional external dependency is used for highlighting JSON, plain text edit is used if not available
- WLED styling (dark mode only)
- JSON files are displayed "prettyfied" and saved "minified"
- JSON color highlighting (if available)
- JSON verification during edit and on saving both in online and offline mode
- special treatment for ledmap files: displayed in aligned columns (2D) or as lines (1D), saved as minified json: no more white-space problems
- displays file size and total flash usage
Add a field to the OTA metadata structure indicating the oldest base
version it's safe to install this update /from/. This provides a clear
path forward in case there are incompatibilities, eg. some case
(bootloader compatibility) where 0.16.0 cannot be installed safely from
0.15.2, but a transitional 0.15.3 can arrange the groundwork.
- Enabling DDP over WebSocket: this allows for UI or html tools to stream data to the LEDs much faster than through the JSON API.
- first byte of data array is used to determine protocol for future use
- Moved the duplicate function to establish a WS connection from the live-view htm files to common.js
- add better safety check for DDP: prevent OOB reads of buffer
during testing at low brightness I noticed that gradients can be "jumping" in colors quite wildly, turning a smooth gradient into a flickering mess. This is due to the color hue preservation being inaccurate and a bit too aggressive. This can be seen for example using a gradient palette and "Running" FX.
Removing the hue preservation completely fixes it but leaves color artefacts for example visible in PS Fire at very low brightness: the bright part of the flames gets a pink hue. This change is a compromise to fix both problems to a "good enough" state
- since we draw on a segment, we need to use virtual segment dimensions or scaling will be off when using any virtualisation like grouping/spacing/mirror etc.
- Enabling DDP over WebSocket: this allows for UI or html tools to stream data to the LEDs much faster than through the JSON API.
- first byte of data array is used to determine protocol for future use
- Moved the duplicate function to establish a WS connection from the live-view htm files to common.js
- add better safety check for DDP: prevent OOB reads of buffer
during testing at low brightness I noticed that gradients can be "jumping" in colors quite wildly, turning a smooth gradient into a flickering mess. This is due to the color hue preservation being inaccurate and a bit too aggressive. This can be seen for example using a gradient palette and "Running" FX.
Removing the hue preservation completely fixes it but leaves color artefacts for example visible in PS Fire at very low brightness: the bright part of the flames gets a pink hue. This change is a compromise to fix both problems to a "good enough" state
Improves cache utilization as fewer things are passed via CFLAGS to
all files. In the event that no metadata is available, let the cpp
file handle warning about default usage.
Implement a comprehensive solution for validating a firmware before an
OTA updated is committed. WLED metadata such as version and release
is moved to a data structure located at near the start of the firmware
binary, where it can be identified and validated.
Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
- if a segment is destroyed or turned inactive, disable the gif player: only one gif player instance can run at a time, if a inactive or destroyed segment uses it, the effect is broken for other segments.
- copy FX ironically copied the source segment on each call, should use reference not a copy!
- if a segment is destroyed or turned inactive, disable the gif player: only one gif player instance can run at a time, if a inactive or destroyed segment uses it, the effect is broken for other segments.
- copy FX ironically copied the source segment on each call, should use reference not a copy!
Sends a shimmer across the strip at defined (or random) intervals
Optional brightness modulators: sine or perlin noise
Can be used as an overlay to other effects.
- speed optimization in color_add, PS fast_color_add and blur functions
- applying more bit and shift manipulation tricks to squeeze out just a bit more speed on color manipulation functions.
- Optimization on blur is based on work by @blazoncek
- Renamed PS fast_color_add() to fast_color_scaleAdd()
- allow more than 10 custom palettes
- move palettes into CPP file
- Fix for minimizing cpal.htm (saves 2k of flash)
- shortened names in cpal, saves about 400 bytes of Flash after packing
- removed async from common.js loading to prevent errors on page loads if the file is not cached
- restricted nubmer of user palettes on ESP8266 to 10
- unrestricted number of user palettes on all other platforms (total max palettes: 256)
- added a warning when adding more than 10 palettes to let the user decide to risk it
- Bugfixes in palette enumeration, fixed AR palette adding
- AR palettes are now also added if there are more than 10 custom palettes
Co-authored-by: Blaž Kristan <blaz@kristan-sp.si>
* adding center bin selection to 2D GEQ: this makes it possible to use subsets of the GEQ on distributed strips
setting custom3 to 0 gives the "old" behaviour, this is the default. existing presets will have the custom3 slider at the center, changing presets that do not use the full width so this is a breaking change for those but I assume theser are rare.
* Attempt at better bus memory calculation and estimation
* Remov double buffer count for ESP8266 (thanks @dedehai)
* improve UI calculation
* adding mendatory LED buffers to UI memory calculation
* adding buffer for transitions to memory calculation, change "error" to "warning"
* bugfixes in settings_leds.htm
* fix getDataSize() forESP8266, ESP8266 does not use double buffering.
* update led settings: fix parsing by @blazoncek
* new warnings for LED buffer use, deny adding a bus if it exceeds limits
* adds recommendations for users (reboot, disable transitions)
Co-authored-by: Blaž Kristan <blaz@kristan-sp.si>
* Improved heap and PSRAM handling
- Segment `allocateData()` uses more elaborate DRAM checking to reduce fragmentation and allow for larger setups to run on low heap
- Segment data allocation fails if minimum contiguous block size runs low to keep the UI working
- Increased `MAX_SEGMENT_DATA` to account for better segment data handling
- Memory allocation functions try to keep enough DRAM for segment data
- Added constant `PSRAM_THRESHOLD` to improve PSARM usage
- Increase MIN_HEAP_SIZE to reduce risk of breaking UI due to low memory for JSON response
- ESP32 makes use of IRAM (no 8bit access) for pixeluffers, freeing up to 50kB of RAM
- Fix to properly get available heap on all platforms: added function `getFreeHeapSize()`
- Bugfix for effects that divide by SEGLEN: don't run FX in service() if segment is not active
-Syntax fix in AR: calloc() uses (numelements, size) as arguments
* Added new functions for allocation and heap checking
- added `allocate_buffer()` function that can be used to allocate large buffers: takes parameters to set preferred ram location, including 32bit accessible RAM on ESP32. Returns null if heap runs low or switches to PSRAM
- getFreeHeapSize() and getContiguousFreeHeap() helper functions for all platforms to correctly report free useable heap
- updated some constants
- updated segment data allocation to free the data if it is large
- replaced "psramsafe" variable with it's #ifdef: BOARD_HAS_PSRAM and made accomodating changes
- added some compile-time checks to handle invalid env. definitions
- updated all allocation functions and some of the logic behind them
- added use of fast RTC-Memory where available
- increased MIN_HEAP_SIZE for all systems (improved stability in tests)
- updated memory calculation in web-UI to account for required segment buffer
- added UI alerts if buffer allocation fails
- made getUsedSegmentData() non-private (used in buffer alloc function)
- changed MAX_SEGMENT_DATA
- added more detailed memory log to DEBUG output
- added debug output to buffer alloc function
Pull the RMT High-priority Interrupt driver in to a vendored local
library, pending inclusion in upstream NeoPixelBus.
Driver is enabled only for XTensa chips; there's some unresolved
issue with nested interrupts on RISCV.
* POV Display usermod
this usermod adds a new effect called "POV Image".
To get it to work:
- read the README :)
- upload a bmp image to the ESP filesystem using "/edit" url.
- select "POV Image" effect.
- set the filename (ie: "/myimage.bmp") as segment name.
- rotate the segment at approximately 20 RPM.
- enjoy the show!
* improve file extension checks
* improve README, remove PNGdec reference, clean usermod
* restrain to esp32 platform + reduce memory footprint with malloc
* updated color scaling to preserve hue at low brightness resulting in much better colors
* replace NPBlg with NPB, moved brightness scaling to bus manager
* improved gamma table calculation: fixed mismatch in inverting gamma table calculation: inversion should now be as good as it gets
* code cleanup, fixed gamma being applied in unnecessary places
Improvements to ABL handling:
- removed strip level handling, ist now all done on bus level
- limiter now respects pixel mapping
- proper handling of white channel
- improved current estimation
- current is now always correctly reported to UI
- minimal FPS impact if the ABL is not limiting but slighly higher impact for global ABL limit due to double-scaling
- moved brightness scaling to BusDigital
- created new header file colors.h to be able to access color functions in bus-manager.
- updated colo_fade() with better video scaling to preserve hue's at low brightness
- added IRAM_ATTR to color_fade (negligible speed impact when compared to inline and benefits other functions)
- added IRAM_ATTR to color_blend as it is used a lot throughout the code, did not test speed impact but adding it to color_fade made it almost on-par with an inlined function
Additional changes:
- fixes for properly handling `scaledBri()` (by @blazoncek)
- also use bit-shift instead of division in blending for ESP8266
- improvements for faster "softlight" calculation in blending
- changed some variables to uint8_t to maybe let the compiler optimize better, uint8_t can be faster if read, store and set are all done in uint8_t, which is the case in the ones I changed
- various minor code formatting changes
Any repeating crash that prevents a human from logging in and fixing
the config should be treated as a boot loop. Increase the detection
timeout, so anything that's fast enough to preclude a user fix will
trigger the recovery behaviour.
Don't treat consecutive but infrequent crashes as bootloops. The
bootloop recovery actions only make sense when there is no opportunity
for a user to reconfigure their system.
Suggested by @coderabbitai
this fixes a very long loop when an overflow was happening in palette blending.
- reset prevPaletteBlends to prevent overflow
- add safety check in case overflow should still happen in another combination (or in future changes)
this new hooks will help you implement new and custom protocols in
usermods.
I've provided an example (see usermods/udp_name_sync).
The example will help you share the main segment name across different
WLED instances.
The segment name can be useful to sync with some effects like GIF
image or scrolling text.
If you define new packet format in your usermod, make sure it will
either not collide with already used version of wled udp packet :
- 0 is for udp sync
- 1 is for AudioReactive data
- 2 is for udp_name_sync :)
Also, the onUdpPacket will override "parseNotification" if it returns "true".
Have fun!
ESP8266 RTC RAM requires 32-bit accesses, but there's no need to jump
through a bunch of functions for it. Use references to simplify access
and harmonize the implementation with ESP32.
* Fix bootloop if config missing/reset
Can't reset the config if there's nothing to reset!
* ESP8266: Commit ACTIONT_TRACKER
* Use consistent naming for backups and reset cfgs
Use 'rst.cfg.json' instead of 'cfg.json.rst.json' for configs that were
reset.
* Add a little more PSTR to bootloop handling
The duplication of logic and the formatting differences between the "OTA Updates" and "Security & Updates" pages made it very difficult to find the exact version details.
With this change, both update-pages now share the same consistent and detailed formatting, making it easy for users to identify which exact version and binary of WLED they've installed.
The version format has also been improved to make it much easier to understand.
In the past, the "notify direct" flag controlled all network syncing, propagating all color changes to other devices on the network. Pressing the UI Sync button only toggled this flag, so "notify direct" was set to false by default.
In version 0.15, a separate "master" sync flag was introduced, and the UI Sync button now only activates this master flag. However, the rest of the flag defaults weren't configured to sync anything at all. As a result, users pressing Sync saw *no* syncing at all, leading to multiple bug reports.
Defaults are now user-friendly: Enabling Sync on a WLED device syncs all of *its* color changes, whether made via the UI, API or remote button, providing a consistent experience which matches the intended behavior from past WLED versions.
Philips Hue sync is now also disabled by default, making the stock defaults focused on WLED devices. Users with other RGB ecosystems can manually enable the Hue or Alexa syncing in the settings.
* added boot loop detection and config backup
* automatic OTA rollback if loading backup does not fix it
* added new file handling functions
* adding verification of json files, added config restore at bootup if broken
* added function to compare contents of two files for future use (currently not used)
* Make color_wheel rotate in HSV sapce instead of linearly interpolating R->G->B
* Remove the rainbow wheel option, as that is the same as the rainbow palette
* Use hsv2rgb for color_wheel
This is the current result of the discussion in https://github.com/wled/WLED/pull/3681
We downtuned the stack usage of AsyncTCP, and at some point in the
history of our fork, this got folded in to the default. Re-apply the
stack size we've been using and recover that RAM.
- Bugfixes in FX data allocation: realloc was not handled properly.
- Added *intermediate* fix for waitForIt(), see https://github.com/wled/WLED/issues/4779
- Bugfix in 1D->2D expansions: corner-expansion MUST be boundary checked as it blindly writes the max dimension
- removed some realloc(), improving fragmentation on large setups
- increased min heap constant
- ESP32 C3 has no PSRAM, it now uses default alloc functions
- also added missing UI info for "Error 7"
- using segment buffer instead of local buffer to save FX ram
- fix rendering if gamma correction is disabled
- some code cleanup
- Fix for low RAM: reduce number of particles dynamically
- updated add and scale color functions to not use references
- FPS is now more consistent and on average about 15% faster
* Added FX to copy a segment in 1D or 2D
- copies the source segment
- brightness of segment is relative to source segment
- optionally shifts the color hue, saturation and brightness
- invert, transpose, mirror work
- if source or targets do not match in size, smallest size is copied
- unused pixels fade to black (allows overlapping segments)
- if invalid source ID is set, segment just fades to black
- added a rgb2hsv conversion function as the fastled variant is inaccurate and buggy
- 1D to 2D and vice versa are supported
* enhancement & bugfixes in scrolling text
- function now evaluates full string: allows custom text plus multiple tokens in any order
- fixed evaluation order to prevent early exit(s)
- fixed day strings (argument must be weekday() )
- prevent settings change if not using private IP address or same subnet
- prevent OTA from differnet subnet if PIN is not set
- ability to revert firmware
PlatformIO doesn't clean out the libdir when usermods are disabled, so
they still appear in the LibBuilders() set. Ensure that we validate
only usermods that were actually deps for the build.
the compilation fails with tons of errors if you try to compile using WLED_DISABLE_2D
"message": "enclosing class of constexpr non-static member function 'bool Segment::is2D() const' is not a literal type",
"LineNumber": 766,
* enhancement & bugfixes in scrolling text
- function now evaluates full string: allows custom text plus multiple tokens in any order
- fixed evaluation order to prevent early exit(s)
- fixed day strings (argument must be weekday() )
the compilation fails with tons of errors if you try to compile using WLED_DISABLE_2D
"message": "enclosing class of constexpr non-static member function 'bool Segment::is2D() const' is not a literal type",
"LineNumber": 766,
PlatformIO doesn't clean out the libdir when usermods are disabled, so
they still appear in the LibBuilders() set. Ensure that we validate
only usermods that were actually deps for the build.
Particle System depends on linear brightness distribution, gamma corrected values are non-linear.
- added invers gamma table
- reversing gamma after brightness distribution makes it linear once again
- fixed "jumpyness" by improving offset calculation resolution
- added palette support
- added two rendering modes for use with palette: one uses hue-mapping, one uses brightness mapping
- added alternate animation mode (from initial source)
- extended scaling: zoom checkmark (depends on matrix size)
Correct issues with usermods not being linked.
- Explicitly set libArchive: false in usermod library.json files
- Fix up symlink path generation on Windows
- Add validation script to report usermod linkage in resulting binary
- prevent settings change if not using private IP address or same subnet
- prevent OTA from differnet subnet if PIN is not set
- ability to revert firmware
Check the safest possible location for final information on what
components are actually being linked in. This demonstrates a safe
approach that works even for out-of-tree modules.
Use a magic custom_usermods string instead of a magic environment
name; and disable the validation script as it triggers on the non-
platform-compatible mods.
Ensure all paths used in usermod symlinks are fully resolved, including
any case correctness issues on Windows. Apparently PlatformIO does
not handle symlink files correctly on Windows if there are case
differences between cwd and the resolved path.
The modern linker used with new platforms (ESP8266, ESP32 >v4) always
produces paths in the map file with slash; however the old linker for
the old ESP32 platform instead produces paths with backslash when
building on Windows. Match both types as a path separator when
scanning linked symbols.
Neither the info panel nor the settings dialog can be trusted to
accurately report the usermod list:
- Not all usermods necessarily add to the info panel
- Not all usermods necessarily add to the config page
- #4609 is required for the config page to be correct
Add a short list to the info object that lists the loaded usermod IDs.
This is not displayed via the UI, but can be queried with curl or web
debug tools.
To be removed when usermod loading is working well.
* add support for up to 10 ESPNow remotes
* removed debug line
* changed todo comment
* fixed some issues, shortened html/java code
- reverting name to `linked_remote`
- ESPNow remote list is now hidden if unchecked
- shortened java script function names and variables to save flash
- removed now obsolete settings in xml.cpp
- correct checking of valid hex string for remote list in java script
* fixed indentation, using emplace_back instead of push_back, using JsonVariant, replaced buttons with +/-
* shortened java code
* updated java code, fixed bug
- element is now properly removed
- `+` button is hidden if list is full
- user needs to remove a remote, then reload the page to add it (workaround for edge case that needs more code to handle otherwise)
* add limit
* clearer usage description
Automatic Gain Control is a very important aspect of the audioreactive plugin,
and is vitally important when the external music volume constantly changes.
It makes sense to allow users to choose their preferred AGC behavior at
compile-time, since they can already set the Gain and Squelch via flags.
Adds `SR_AGC` as a flag, which defaults to 0 (off).
- fixed inconsitencies in size rendering
- fixed palette being wrapped in color by position and color by age modes
- Fixed bug in memory layout: for some unknown reason, if flags come before particles, last flag is sometimes overwritten, changing memory laout seems to fix that
- New color modes in PS Fireworks 1D:
- custom3 slider < 16: lower saturation (check1: single color or multi-color explosions)
- custom3 slider <= 23: full saturation (check1: single color or multi-color explosions)
- custom3 slider > 23: color by speed (check 1 has not effect here)
- custom slider = max: color by age or color by position (depends on check1)
The ConfigureProjectLibBuilder process will flush and reload the library
settings from the on-disk manifests if any new library is installed at
that stage. This has the side effect of reverting the libArchive setting
applied to usermods which was performed prior to that call.
Apply the setting afterwards, instead.
Fixes#4597
- Photoshop-style segment/layer blending
- return of strip ABL
- remove global LED buffer in favour of segment-local buffer
- new effect blending modes/transitions
- custom palettes moved out of WS2812FX class
- increased limits (matrix size, LED RAM)
- added "rainbow"-mode colorwheel
- replaced palettes with gamma unmodified ones
- move gamma adjustment to last step before sending to LEDs
- Segment & WS2812FX class reorganisation (mutable members, reordered members, protected members)
* Removed memory manager from PS
- reverted all changes related to memory manager
- moved local buffer into effect data memory
- some RAM issues may occur on larger setups: tested on S3 it works fine up to 32x32 but runs into memory issues at 64x32
* fixed ifdef, improved readability, add optimize "o2" flags to improve speed
- added struct for x and y coordinates, thx to @blazoncek
* cleanup and minor improvements
- removed local buffer for ESP8266 in 1D system to save on RAM
- increased particle brightness in PS Impact
- minor tweak in collision binning (might improve speed)
- removed comments and some other unused stuff
- fixed a few compiler wranings
* fixed init sequence bug
- since Update object is accessible even with ArduinoOTA disabled it should possible to use HTTP OTA regardless
- this saves about 12kB while still allowing OTA updates
- HTTP OTA updates can be blocked using PIN or OTA lock
* added Sonic Boom AR FX, some tweaks to Sonic Stream
* added white color option to Sonic Stream
* improvements to collisions (speed look-ahead)
* code prettified
* added "playful" mode to PS Chase plus some minor speed optimizations
* Adding new FX: PS Springy with many config options
I've just assigned an arbitrary ID number. The ID system should
get removed entirely; we don't want to have to change a base
system header to add each module.
Several of our controllers support the Ethernet module, so we figured it best to leave it as simply "RGB2Go" in the menu, as opposed to "RBG2Go" Tetra.
Rather than reading the file off disk, have the json/cfg endpoint
return the live config from system state data. This can improve
UI behaviour as it can never be out of date or include values that
do not apply to the current firmware install.
Break the actual JSON assembly apart from the file writing code. This
permits calling it in other contexts, allowing us to pull the live
config data even if the filesystem is out of date.
Part of the ongoing quest to migrate macro definitions to typed
language constructs. This actually yields a small improvement in
code size, likely from the byte->int conversion.
* cleanup
* added collision handling back in
update from another commit that got lost
* reformat
* added latest version of functions
this somehow also got lost from an earlier commit
* Update platformio.ini
* updated particle box and firework effects
particle box now is more random in random mode (still a work in progress)
firework is now more configurable by sliders
* added preliminary functions and FX
* added particle attractor, added two new FX but still buggy
particle attractor animation does not work, somthing wrong with pointer allocation, it worked with static variables
* bugfixes, attracot now works
still unknown, why more than 256 particles are needed in memory allocation to not make it crash, but it works for now
* added angle emitter, added fireworks effect using it
* Added saturation to be set for each particle individually
at the expense of more ram usage, animations now have more options for color control (already used in fireworks now)
* bugfixes in impact animation
* added option to use fast color add, may improve performance a little
also fixed a bug in fire animation
* collision detection is now a function plus some improvements & fixes
* improved collision efficiency
improved efficiency for stackup (pushback), added code to correctly determine direction if particles meed (probably overkill but now its there)
* added fix for piling oscillations
untested, need to verify it works
* Improved collision handling (faster, less oscillations), changed variables to 32bit for faster calculation
32bit variables are faster on ESP32, so use them whenever a variable is used a lot, it saves one instruction per access.
* removed option for fastcolor add
it made very little difference in performance, but for ESP8266 it may matter so it is set permanently there. graphically the difference is also very small (sometimes a particle gets brighter or less saturated)
* Fixed some bugs in particle system, runs much smoother now
also tweaked some of the FX
* Bugfix in particle push, now piling is working again
particle pile-up did not work correctly, now fixed
* changed particle pile demo into waterfall plus some tweaks
* lots of bugfixes
* updated particle attractor animation parameters and added more user options to perlin noise
* removed TODOs
* added particle WrapUpdate function, added spray FX, some bugfixes
* fixed touch buttons for ESP32 S2 and S3
touch is implemented differently on S2 and S3, these changes make touch buttons work on S2 and S3
* some tuning for touch buttons on S2/S3
now better fits the default threshold value of 32
* updated rotating particle spray with more user options
* chaned rotating spray default parameters
* add todo
* Revert "some tuning for touch buttons on S2/S3"
This reverts commit d21ad8e7d1.
* Revert "fixed touch buttons for ESP32 S2 and S3"
This reverts commit 0904155186.
* removed comments, added comments
* cleanup
-removed wrap_update function, now integrated into move_update
-added more 'out of bounds' checking in fire functions, may speed it up a little
* cleanup session
-removed particle box 'rocking boat' (buggy) and replaced with random sloshing.
-removed comments
-changed some variables into 32bit for speed boost on ESP32
-added link to KB at the top of FX.cpp
* cleanup
removed / added comments
* added particle GEQ effect (untested)
* Particle GEQ fixes, it now actually works
* GEQ FX parameter tuning
* added rotating GEQ, work in progress
-animation works but sliders are too sensitive. need to adjust the ranges
* FX update
- changed firework exhaust to low saturation
- updated rotating particle spray animation
* Cleanup & Bugfixes plus major improvements for ESP8266
-added particle reductions for ESP8266 for all FX
-Removed collisions from Particle Perlin Noise FX, slows things down and does not contribute to a better effect experience
-lots of optimizations for ESP8266, all FX now work (at least on 160MHz but still slow)
-Some bugfixes
-removed unused variables to make compiler happy
* Particle FX Rename, default parameter tuning, bugfix
-Now shorter names, 'PS' in front to filter the list
-Tuned default parameters to make them look better by default
-Bugfix in particle system (removed duplicate application of velocity)
-reduced PS fire RAM usage (less particles, less base flames, no noticeable difference)
-some variable renaming
* slight speed improvements in fire, like 1-2FPS
* Big update: lots of little fixes and big speed boost on fire animation
-fixed fire burning more on the left side
-fixed crash in particle attractor
-added many improvements for ESP8266
-improved particle rendering efficiency
-efficiency improvements in general
-changed the way fire is rendered, now more than 2x faster
-re-tuned fire to new rendering, also seperately tuned it for ESP8266
-changed all random8() to random16() as it runs faster on ESPs
-some reformating
-some renaming of effect stuff
-fine tuning on falling particle effect
-improvements to collision handling (faster and better)
-added a (temporary) function for speed tests, will be removed again
* bugfix
* updated PS Fireworks with many changes and fine-tuning of parameters
-removed spiral explosions
-added more versatility to circular explosions
-removed user selectable amount of rockets
-tuned explosion size of circular explosions to match random explosions (more or less, may need improvement)
-changed order of sliders in volcano animation
* put particle system in a class. work in progress.
another huge update to the particle system.
went through the whole code, rewrote many of the functions. many improvements over the previous code. fixed many bugs (and even an ancient one in rendering function). spent many hours optimizing the code for speed and usability.
still a work in progress, debugging is ongoing. more updates to come.
* many (many!) bugfixes, added fire FX back in (and improved it a lot) added local renderbuffer for huge speed boost
-lots of bugfixes in Particle system
-added local rendering buffer (renders to buffer in heap)
-added fast and accurate color-add function
-bugfixes in render function
-added improved 'sticky' particles in collision (unfinished business)
-added ballpit animation back
-lots of tweaks to fire FX and fire rendering functions, looks even better now (still unfinished)
-added palette render option to fire
still many debug print outputs around, needs cleanup at one point
* More Bugfixes, more converted FX
* more bugfixes, some animation tuning, added volcano back in
- fixed animation transitions with proper pointer setting in each FX call
- added color by age setting to particle system
- maybe fixed collision having a tendency to go to the left
- fixed bugs in fireworks FX
- added fire spread width as a slider
- changed max number of particles and sprays based on some ram calculations
- some other random fixes
* updated fire, added some functions to PS, ported attractor FX
- added turbulance to fire (after hours of fine-tuning) it now looks even more awesome
- added attractor animation back in and improved it with more functionality
- fixed the attractor function in the PS
- renamed FX: 'candy' is now called 'vortex'
- added new force function to apply a force immediately (and handle the timing in the FX)
- added update function to PS for size update to handle dynamic segment size change
- made waterfall width dynamic on segment width
- removed some debug stuff
- added #defines for maximum number of particles/sprays
- updated fire parameter to make it look better on ESP8266
- some little bugfixes
* another huge update, many improvements, fine-tune collision, fire and some other FX
-removed classic fire render as palette now looks much better
-tweaked fire parameters to more awesome
-added (optional) turbulence to fire using perlin-noise
-ported spray FX to use PS-class
-now definitely fixed asymmetrical collision issue: do not use bitshifts on negative numbers!
-changed piling behaviour of particles, full rework. looks way more natural now and works much better
-changed bouncing behavour: they now bounce at full diameter, making them stay fully in frame when laying on the floor
-replaced all relevant bitshifts with divisions for higher accuracy throughout the PS
-added new modes to particle box FX
-changed a lot of FX parameters (finetuning)
-changed all config strings to proper settings (matrix only)
-fixed newly introduced bugs
-added speedup/slowdown to vortex FX (aka candy, aka rotating sprays)
-some renaming
-fixed bugs… lots of bugs
-merged rendering functions, removed obsolete stuff
* Fixed Speed limit
limiting speed was incorrect, leading to overflows. fixed this.
also fixed bugs in GEQ, removed some debug stuff, added FPS limit to fire (just en experiment)
* work in progress, added motion blur and line attracto (non working)
* work in progress, added test function to increase particle size, also added wobbling test
* added more tests, non compiling at the moment
* in the middle of fixing FX to use new PS functions
* debugging going on
* bugfix in wrap function and firwork FX
* added local render blurring, boosting FPS, work in progress
- changed fast-add function to use pointers
- added fast-scaling function
- added simple (but fast) 2D blurring function
test shows that local blurring of full frame is almost double the speed (40FPS now is 80FPS).
lots of comments still there
* Bugfixes, improvements and added wall roughness setting
- fixed bug in PS fuzzy noise which made it asymmetric for some reason, seems to work better now
- added particle size option to attractor but had to remove speed setting (now fixed emit speed)
- some parameter tuning of FX
- improvements to code size in render function
- added smear option to blurring (not tested much, may be buggy without smear)
- speed improvement to caldForce_dv, added zero checking.
* removed zero inits
- removed zero initialisations in FX, segment.data is set to zero by alloc function
* added individual size particle rendering plus some fixes
- advanced particles can now be rendered to individual sizes. It is computationally intensive but it works well for up to 15 very large particles and more smaller ones
- added collision handling for individual sizes (walls and collisions)
- fixed bugs in particlebox
- fixed fire not transitioning properly (flickering) when frame skip is active
- removed 'wraparound' function as it can easily be done by casting to an unsigned and then modulo
- fixed ballpit particles wandering left and right very fast if wrapX is set
* Fixed some nasty memory bugs, fixed some FX parameters
- fixed memory alignment bug in PS pointer assignment by making sure only multiples of 4 are allowed for particles and sources
- added saturation back to particle struct, as it was aligned to 10 bytes anyway.
- fixed a bug where a null pointer could be accessed
- fixed rendering out of frame particles if buffer allocation failed
- improvements on ESP8266
* Replaced Ghost Rider FX with PS version
- new FX is kept close to original animation but added more user settings
* added walls to ghostride, fixed some bugs
* added 'perpetual' flag to particles
* Fixed another memory / pointer bug, but there is still one left...
-also some minor fixes
* Found and fixed crashes, it was wrongly assigned pointers
* Added advanced particle size control and new Blob FX
- advanced size control allows for growing, shrinking, wobbling
- render function updated to support asymmetric rendering
- various code improvements and bugfixes
- some FX parameter tuning
- bugfix: removed sli() sei() calls in render function that caused random flickering on S3/C3 (may add that back in but only for ESP8266 to reduce fragmentation)
- removed some debug / test stuff
* code cleanup, removed some unused stuff
* bugfix, sprayEmit() would not return and get stuck
- forgot default return value...
* remove esp_random() as it is not supported on ESP8266
* small bugfix for ESP32, cleanup / reformatting
* added WLED_DISABLE_PARTICLESYSTEM option, fixed volcano movement
use '-D WLED_DISABLE_PARTICLESYSTEM' to disable compiling
* a line got lost in the last commit
* - added WLED_DISABLE_PARTICLESYSTEM option & cleanup & bugfixes
- cleanup / reformatting
- fixed volcano movement
- small bugfix for ESP32 (random() does not work, using random16() )
* Added PS source option to emit more than one particle, addes AR to Blobs and Spray
* added center GEQ back in, changed AR behaviour of spray a little
center GEQ is a mix between the PS equalizer and vortex, tuned for AR. some more tuning may be needed, it can probably be extended and improved a little.
* Bugfix and minor improvements
- fixed bug in center GEQ
- added '2D washing machine' mode for particle box
- improved color-change rate in ghostrider
- added AR to attractor (experimental, may remove again)
* hacked in a 1D port of the 2D PS, untested code
* fixed first bugs in 1D system, added test FX
* fixed bug in wrapping (also was wrong for 2D system)
* fixed collisions, added bouncing ball replacement (work in progress)
* replaced more FX, some tweaks to 1D PS
- changed virtual particle size from 64 to 32, making them able to move faster
- added 'rolling balls' option to bouncing balls (i.e. no gravity plus some tweaks)
- added dancing shadows with PS (work in progress)
- temporarily removed native FX: bouncing balls, rolling balls, popcorn, dancing shadows
-and of course some bugfixes
* updated dancing shadows to more closely mimic original
* added drip FX, added #ifdefs, removed some common functions
#ifdefs to individually disable 1D and 2D system.
* fixed compile issue, removed replaced FX (again)
* added Fireworks1D replacement (unfinished)
also fixed a bug in `applyForce()` using uninitialized variable.
* added sparkler and hourglass (both work in progress) tried fixing 1D collisions
* many improvements in 1D collisions (fine tuned), hour glass FX is almost done
spent A LOT of time in fine-tuning collisions for best stacking without collipsing, ringing, oscillations or particle flips. still not perfect but probably as good as it can be with the limited time-resolution
* many bugfixes in PS and FX
* minor FX adjustments
* Improved 1D collisions, added 2 new 1D FX (work in progress)
* bugfixes
* added 'color by position' as a PS setting
-made settings struct for 1D and 2D version to be different
-added setting 'color by position' as that is used by multiple FX now
* added large size rendering to 1D PS, work in progress
* bugfix (forgot to free memory)
also: made random size a permanent option in 1D fireworks as it looks kind of cool
* Added PS based Chase, fixed some bugs
* minor update
* two new FX: Starburst and 1D GEQ
* Added more advanced (and proper) size handling in collisions, work in progress
- copied and adapted some stuff from 2D system (out of bounds size rendering, dynamic collision detection distance, dynamic wall bounce distance)
* fixed some parameters in 1D FX
* added #ifndef to disable FX replaced by PS
- define DISABLE_1D_PS_REPLACEMENTS or DISABLE_2D_PS_REPLACEMENTS
* bugfixes
* default parameter change
* explicit cast to fix compile error
* Bugfixes
* added color-waves to PS chase, some parameter tuning plus bugfixes
* FX update and bugfixes
- fixed wall collisions on larger particle sizes
- update to bouncing balls:
- added size setting
- added proper updating on parameter change
- bugfixes
added support for 'colorwaves' and 'pride' to PS Chase to save on code size. currently broken...
* minor update to rolling balls, fixed stuff in Chase, pride option still not working
* update on 'pride' now working again but needs finetuning
* SEGMENT -> SEGENV on data, aux0, aux1, step
also removed debug outputs
* added pride and colorwaves to 1D replacement list
* removed unused variables
* added variable to set number of particles if not all are required (saves ram) also fixed a nasty render bug
* added preliminary 1D fire function, unfinished
* added fractal FX test, fixed bugs in emit function
* tweaked 1D fire a little, still work in progress
* minor tuning on 1D fire to avoid 'oscillation' at start
* improved 1D particle fire, much more natural now.
* updated 2D fire, fixed init bug
- source init was wrong making fire init weirdly
- changed parameters on 2D fire making it look better and improving flame height for larger setups
* fixed 'nervours' fire
* slight improvements and some cleanup
* removed douplicate code for fire emit (tradeoff for some speed), removed unfinished fractal FX
- with the duplicate code removed, the fire particle emits are a bit slower but it saves on code. it is not really noticeable, its slower by about 1FPS
* Re-license from MIT to EUPL
* Started cleanup, speed improvement to rendering, renamed class
- removed 'smar' parameter in blur functions as smear is always used
- improved particle rendering (passing by reference, passing wrap parameters for faster access)
- renamed class to ParticleSystem2D
- removed some whitespaces
- some reformating, removed some comments
- minor tweaks
- removed non-working line-attractor function
* Optimization and bugfixes
- added out of bounds checking function
- fixed rendering at boundaries
- various small changes and cleanup
- bugfixes with comparing ints of different signeness
- fixed bounce radius
* Cleanup, bugfixes, speed improvements, refactoring
- lots of code refactoring / reformating
- fixed bug in fire particle update and improved speed a bit
- refactoring of pixel rendering
- removed 2D buffers, replaced with 1D buffer for faster access
- bugfix in blur2D
- many small improvements to 2D system
* Refactoring and cleanup of 1D PS, removed debug printouts
- code reformating for consistency and readability
- replaced "'?" operator with min / max (produces the same code, more readable)
- minor changes for speed (random16 used, can later be replaced with hardware random function)
- renamed PS Equalizer to PS 2D GEQ
* Cleanup and some refactoring of particle FX
- moved 2D / length check to PS initi
- code reformating
- removed some comments
* missed a spot
* minor tweaks to fast_color_add()
* Work in progress: update to fireworks, needs more testing & finetuning
also bugs fixed and some minor cleanup
* Work in Progress: added particle memory manager for transitions
- uses only one, persistant buffer to render all present particle systems
- Buffer for particles is shared for one segment (may allow interacitng systems in the future)
- updated some of the FX to handle the new transfer, 1D FX still not done
- updated parameters for particle impact FX
* work in progress: lots of changes & fixes, transitions now work correctly in 2D
- still fragile code with lots of cleanup to do
* added transitions for big-size rendering
- transitions now work with FX that use global large size rendering. this is done by handling the buffer correctly. to avoid creating a second buffer, it is transferred back and forth to the segment. this is a bit slow but a compromise solution.
- multiple segment handling is still untested
* speed improvement to fast_color_add, added preliminary buffer transfer function
* merge fixes
* bugfix in setCurrentPalette, corrected order of 2D memory allocation, increased max particles/sources
- fixed timing for vortex
* fixed particle buffer handover, added 2D blur option, increased particle limits, various fixes
- fixed bug in memory watchdog, now works and also works when freezing segments
- fixed PS Box to work again with particle handover
- added smear blurring to waterfall
- added smear blurring to vortex, fixed color distribution, removed random color distribution option
- replaced all random() calls with hw_random()
- transitions now work but only if FX transitions are enabled and not when chaning segment size
* implemented correct 1D<->2D buffer handover+bugfixes
work in progress
* added smear to fuzzy noise, some cleanup
* added blurring option to PS 2D fireworks, work in progress in finding that nasty bug that crashes all
* BUGFIX: finally found and squased the memory bug, no more random crashes
also: removed debug outputs and minor cleanup
* minor cleanup and fixed a bug
1D system had a lot of crashes, some out of bounds memory issue. fixed it but I have no idea which change did that, maybe the order in 1D initialization
* BUGFIX: out of bounds checking was wrong, leading to crashes
* better handling of used particles in transitions
for FX that do not use all particles, transitions were constantly shifting the pointer, resulting in newly generated particles and weird particle flickering, this is not fixed by keeping the pointer constant once the number of used particles is reached.
* improved particle transition for low-count FX, updated 1D FX
now most 1D FX work again, still needs some fine-tuning
* Rework on Fireworks 1D, some minor fixes
- fireworks 1D now matches as closely as possible to the old FX
still not identical but as good as it gets.
* bugfix in PS Chase, increased brightness of 1D fireworks
* replaced sin16/cos16 with new versions
* bugfixes
* fixed hourglass init, rearranged PS FX init
* speed optimization
- moved out of bounds calculation to proper spot
- removed repeated allocation attempts if initial buffer alloc fails
* Added Sonic Stream FX, some cleanup, bugfix in emitter
* changed TTL to brightness calculation, added collision binning
- brightness is now doubled as some FX were really dim due to low TTL
- added binning in x-direction giving a huge speed advantage on larger matrix sizes
* collision binning bugfix, made particles less sticky, update to waterfall
- updated waterfall intensity and blurring
* WIP: fixed 1D system for over 1000 pixels, added collision binning for 1D
- making x coordinate 32bit allows for larger strips but uses a lot of ram due to struct memory alignment (12bytes instead of 8 bytes), this needs some more work to properly fix.
- adding collision binning significantly speeds things up, about a factor of 2 on most FX using collision
- there are still some bugs in FX or 1D memory handling (or both) on large setups
* moved particle flags to seperate array to save on RAM, refactoring
- moving the flags optimizes ram alignment, saving memory for each particle
- changed lots of parameters to `const`
- moved fire intensity to a variable instead of passing it to every render() call
- changed passing pointers to passing reference where possible
- saves a total of 340 bytes of flash
* removed todos after some checks, minor improvements
* inverted y axis in 2D render, 1D collision improvements, cleanup and fixes
- inverting the y-axis in the buffer instead of in buffer transfer fixes the FX flipping when transitiononing 1D<->2D
- improved particle binning for collisions
- added hard-pushing also when not using gravity so piles close to an edge dont collapse
- some improvments to "balance" FX
- renaming and cleanup
* FX fixes and minor tweaks
* increased min rockets
* fixed #ifdefs
* another fix
* revert unnecessary changes to base code
* merge fix
* minor tweak
* tweaked sparkler FX, some cleanup
* Fix in volcano FX, changed blurring of volcano and waterfall
* added ifdefs
* minor tweaks, increased 1D minsurfacehardness
* improved sparkler FX, made overlay possible (1D not yet), cleanup
* cleanup, now using new hsv2rgb/rgb2hsv, add overlay rendering to 1D
- new hsv2rgb is a tiny bit faster
- removed redundant code (using transferBuffer instead)
- tweked parameters in vortex, removed unneeded slider defaults
* fix for non or partially overlapping segments
- can not use overlay rendering if no segment clears the buffer, it will all add up to white eventually
- now additive transfer i.e. overlay mode is only activated if the segment is fully overlapping an underlying segment
* change got lost...
* increased sparkler intensity, some cleanup
* replaced #ifdefs, removed 1D replacements that have 2D version, removed notes
* cleanup, improvements to PS bouncing ball, replaced multicomet
- bouncing balls is now named pinball and has settings/parameters updated to be a replacement for multicomet
* cleanup, improvements, bugfixes
- large size rendering now works without framebuffer
- background adding is now done on buffer (if avilable) instead of segment
- fixed overflow bug in 2D large particle rendering (it worked only for powers of 2 size)
* potential bugfix, compiler warning fix
* removed colorwaves and pride option from chase (not worthy replacements)
* updated #defines, removed PS from 1M and 2M builds
* Adding Particle System and PS FX
Adding all 187 commits from particle system dev branch
* reverted some accidental changes
* reverted some accidental changes
* merge fixes
* changed replacement: multicomet instead of comet (lighthouse)
* changed replacement: multicomet instead of comet (lighthouse)
* disable 2D PS for ESP8266, some cleanup, improved pinball FX parameters, bugfixes
* Improved collision binning for large particles, improved pinball FX
* improved speed handling in pinball FX - rolling
* disable 2D PS for ESP8266, some cleanup, improved pinball FX parameters, bugfixes
* improved hourglass: millis instead of frame timing, better stacking. and cleanup.
* revert whitespaces
* simplified 1D collisions, improved binning for larger particles
- ran a lot of experiments with collisions in 1D, the new much simpler approach seems to be a good compromise with regards to stacking and normal collisions.
* Improved collision binning for large particles, improved pinball FX
* improved speed handling in pinball FX - rolling
* improved hourglass: millis instead of frame timing, better stacking. and cleanup.
* revert whitespaces
* prohibit use of 1D and 2D system simultaneously on ESP8266
* prohibit use of 1D and 2D system simultaneously on ESP8266
* update to handle blending styles
* fixed bugs, improved new transition handling
* updated 1D system to work with new transitions, replaced NULL with nullptr
* merge fixes
* added single pixel particle rendering for 2D system, adjusted FX to work with it
* improved collisions in 1D and 2D, some bugfixes in radius calculation, minor tweaks
- collisions are now also velocity based in 1D, there was a bug that prevented that from working well (wrong collision distance calculation)
- improvement and bugfix in 2D collision distance calculation
- added distance based pushing in 2D (instead of only using the dotproduct)
the combination of improved distance calculation and proper pushing make collisions a lot better in all tested FX
* minor fix
* fixed overlay detection, checking for partial overlay
if a PS FX is partially overlapping, it will render in overlay mode
* better blur range in PS Firworks
* minor code consolidation
* updated 1D collisions (yet again), improved 2D collision speed
- slight improvement to 2D collision code efficiency
- added faster "division" to C3/ESP8266 by using a right shift trick (biasing towards 0 also for negative numbers by applying proper rounding)
* minor tweak in PS balance
* fix for #4153
* only load touch/mouse events for touch/mouse devices
* undid formating changes
* undid more formating changes
* undid all formating changes
* use pointerover and pointerout eventlisteners
- moved local variables into function
- made coordinates an array
- amplitude can now be changed by user (default setting is a slight increase to original which cannot be avoided without complicated logic or default slider setting)
- fixed issue: blending was also done when color was on a key-index-color which is now skipped
- speed improvement: conversion is skipped if color is key-color
This mod includes a header from the Adafruit Unified Sensor library
inherited by its target sensor libraries. This isn't reliably
picked up by PlatformIO's dependency finder. Add an explicit dep to
ensure build stability.
Use a custom setup script to check for the dependencies and pass along
the required compile flags to the module; also split the object
definitions for the target modules from their source so as to allow
#including them.
Enable the new concurrent request and queue size limit features
of AsyncWebServer. This should improve the handling of burst
traffic or many clients, and significantly reduce the likelihood
of OOM crashes due to HTTP requests.
* added bitwise operation based sqrt16
- replacement for fastled, it is about 10% slower for numbers smaller 128 but faster for larger numbers. speed difference is irrelevant to WLED but it saves some flash.
* updated to 32bit, improved for typical WLED use
- making it 32bits allows for larger numbers
- added another initial condition check for medium sized numbers
- increased the "small number" optimization to larger numbers: the function is currently only used to calculate sqrt(x^2+y^2) which even for small segments is larger than the initially used 64, so optimizing for 1024 makes more sense, although the value is arbitrarily chosen
- Implement vector in bus manager
- Memory calculation according to explanation from @Makuna
- Prefer 8 RMT before 8 I2S on ESP32 (fixes#4380)
- speed improvements in ABL
- verbose debugging
- get bus size from NPB (prototype)
- Parallel I2S output bugfix
- automatic selection of appropriate I2S bus (`X1xxxxxxMethod`)
- removed I2S0 on ESP32 (used by AudioReactive)
- renumbered internal bus numbers (iType)
- added buffer size reporting
* removed unneeded initializations in blur() and blur2D()
* remove check for _t in progress()
* code readability: if (_t) --> if(isInTransition())
* add `isInTransition()` checks to currentBri() and currentMode()
* added missing `_transitionprogress = 0xFFFFU` in stopTransition()
This is purely a "clean code" thing, no impact on function - it helps to avoid confusion when reading the code.
C++ allows declaration and implementation to use different variable names.
* changed some parameters to "pointer to const", so compiler can better optimize code size and performance - because data behind a const pointer will never be modified by the called function.
* made setPixelColor `const`
* fixed a few potentially uninitialized local vars (the may have random values if not initialized)
* avoid shadowing "state" in handleSerial()
* plus a few very minor improvements
* make XY() and _setPixelColorXY_raw() const (minor speedup)
* segment is a struct not a class: friend class Segment --> friend struct Segment
* fix missing braces around two macros
* use non-throwing "new" where possible
* improve robustness of transition code
This fixes a crash in the dmx receiver. The dmx receiver cannot work while cache is disabled. For some reason activating wifi disables the cache. In theory, the driver is placed in iram and should work, but it doesn't. This might be a bug in the driver.
Monkey-patch PlatformIO to intercept the build process after library
dependencies are loaded, but before the build is fully analyzed. This
lets us enforce libArchive=False for usermods without making that
setting global across all libraries.
The rest of the fixup code is integrated at the same call site for
simplicity.
Redesign the usermod system so that usermods are implemented as
PlatformIO libraries instead of headers. This permits them to call for
dependencies, and eliminates the compiler flags for enabling each one,
allowing the build cache to behave better.
The usermod list is built using some linker magic to construct a static
list in ROM memory. This eliminates the need for wasting SRAM on
something fixed at build time.
* DeepSleep Usermod
- sleep delay is now 1 by default, disabling sleep at powerup
- renamed bootup variable to powerup
- using delay counter for proper bootup
- changed power-up and bootup logic
- added fallback to always power-on at boot except at powerup
- fixed bug in settings page
same issue as with https://github.com/Aircoookie/WLED/pull/4386
waiting on bus to finish updating before file access fixes the glitches.
this issue is only present on S2 and C3, not on ESP8266 or dual-core ESPs, the fix is only applied for these two.
Both ESP8266 and ESP32 have a hardware random register. This update makes use of that. It is slightly faster than the fastled variants but mostly it is truly random, even when the timing limitations stated in the datasheet are disregarded. Also saves a bit on code size.
- Replaced all random8() and random16() calls with new hw_random() versions
- Not replaced in FX where PRNG is required
Improvements & merges of FX
- Scrolling Text: Gradient Palette support added
- Waving Cell: Improved with higher temporal resolution (smoother at lower speeds) and added additional mode setting and optional blurring
- Julia: added blur option
- Squared Swirl: added fade option
- Added smearing option to:
- DNA
- DNA Spiral
- Drift
- Drift Rose
- Crazy Bees
- Ripple
- Colored Bursts
- Frizzles
- Lissajous
- Sindots
- Spaceships
- Added palette support to:
- Crazy Bees
- Polar Lights
- Drift Rose
- Changed default palette handling (no more special treatment for some FX)
- Merged puddles and puddlepeak
- Merged Gravcenter, Gravcentric, Gravfreq and Gravimeter (saves 1.2k of flash)
- Merged meteor and meteor smooth
- Renamed police_base into mode_two_dots as that was just an alias
- Added 'Traffic Light' palette (originally defined in Polar Lights FX)
- Firenoise: removed local palette, use fire palette -> slight change in looks (+bugfix)
- Some code cleanup (removed unused / commented stuff)
- Moved dev info for AR to the top so ist easier to find as a reference, also added link to KB there
Removing the bool saves on code size and makes the function a tiny bit faster. Also this is a cleaner solution IMHO.
-updated blend function to optimized 8bit calculation
- efficient color blend calculation in fews operations possible
- omitting min / max checks makes it faster on average
- using 8bit for "blend" variable does not significantly influence the resulting color, just transition points are slightly shifted but yield very good results (and better than the original 16bit version using the old fastled math with improper rounding)
- updated drawCircle and drawLine to use 8bit directly instead of 16bit with a shift
to ensure that build_unflags and board_build.partitions are always having a useful default value. Values can be overridden in custom buildenvs.
saves us a few lines lin platformio_override.sample.ini.
this one is actually for https://github.com/srg74/WLED-ESP32-pico
Its a simple example how to configure WLED for a custom board with build-in microphone and special purpose pins.
progress() is called in setPixelColor(), calculating the transition progress for each pixel. Replaced that call with an inline function to get the new segment variable.
The progress is updated in service() when handleTransition() is called.
The new variable is in a spot where padding is added, so this should not use more RAM.
Result: over 10% increase in FPS on 16x16 matrix
* removed IRAM_ATTR: `updateTransitionProgress()` is called only once per frame, no need to put it in RAM.
* changed transitionprogress to static, private variable, this is now more aligned with other variables using the same logic
* added inline: the function is only used in one place
Processing of received button command is no longer processed in the callback, instead the value is saved to a variable and processed in the main loop.
The actual fix is to not access the file system while data is being sent out: even just trying to open a non-existing file causes glitches on the C3. Waiting for the bus to finish fixes this BUT it causes a frame-delay which is the lesser evil than random color flashes.
- previous fix worked but there was still an overflow after some time passed. there were still missing roll-overs apparently: reverting these two variables back to 16bit/8bit should fix it for good.
When adding a new bus, the numeric current limit field was not being
initialized; this was causing it to save 0 when saved instead of the
default 55mA value.
- sin/cos calls with incrementing numbers can lead to bad outcomes, the functions (_approx or original sinf/cosf) return bad values for very large float inputs
- code is a bit cleaner and faster as well
- chaning array access to pointer access in bus_manager makes it a few instructions faster
- changed getNumberOfPins and getNumberOfChannels to return 32bit values, saving the unnecessary 8bit conversion
NeoPixelBus requires that all parallel I2S bus members be constructed
before any of them call Begin(). Implement this by deferring the
call to the end of bus construction.
Fixes#4301.
- all palettes are defined in palettes.h
- access to fastled palettes as an array to remove the switch cases
- palette createn in json.cpp in a loop instead of repeaded calls to save flash
- rotation scale is now exactly 180° (divide slider input by 255 instead of 256)
- removed shift offset: offset is now zero at slider 0, to hit 128 on touch input devices is really hard
- added a 90° shift to input rotation, enabling to rotate from 0 to 180° instead of +90 to -90 (which is not useful in 1D)
- changed default settings values to more closely match the old 1D effect
Fixed point calculation for improved accuracy, dithering in debug builds only.
Averaging and optional multiplier can be set as compile flags, example for speed testing with long averaging and a 10x multiplier:
-D FPS_CALC_AVG=200
-D FPS_MULTIPLIER=10
The calculation resolution is limited (9.7bit fixed point) so values larger than 200 can hit resolution limit and get stuck before reaching the final value.
If WLED_DEBUG is defined, dithering is added to the returned value so sub-frame accuracy is possible in post-processingwithout enabling the multiplier.
* keep FRAMETIME_FIXED as a fixed value
* remove WLED_FPS_SLOW and FRAMETIME_FIXED_SLOW
* explicit test "(_targetFps != FPS_UNLIMITED)" for debug messages
* don't modify _lastServiceShow in show()
* test for "fps == FPS_UNLIMITED" explicitly, so we could pick a different
magic number later
* separate fps calculation (strip.show) from framerate control (strio.service)
* improved condition for early exit in strip.show
* make MIN_SHOW_DELAY depend on target fps
* strip.show consideres complete time for effect calculation + show; old code wrongly used the time between completion of last show and start of next effect drawing, causing unexpected slowdown
* add "unlimited FPS mode" for testing
* increase warning limits for "slow strip" and "slow effects"
- increase WLED_MAX_BUSSES for C3 (fixes#4215)
- fix for #4228
- fix for very long running effect (strip.now, strip.timebase)
- C++ API change to allow `seg.setColor().setOpacity()`
Fix for LED and Scenes uncontrollable using Alexa.
Weird behavior regarding to the device names and shared scenes fixed with this.
Seen in issue Aircoookie/Espalexa#228 and fixed from @ams-hh
Tested by myself and works just fine. Created second pull request here because the library seems to be a bit different from the official Espalexa repo.
---------
Co-authored-by: Frank <91616163+softhack007@users.noreply.github.com>
Co-authored-by: Blaz Kristan <blaz@kristan-sp.si>
This is a platform feature that asks forgiveness for PROGMEM misuse:
it adds a handler such that incorrectly used PROGMEM will work without
crashing, just really, *really* inefficiently.
Given that most of our real-world use cases for PROGMEM strings are
relatively infrequent text calls, we can err on the side of developer
convenience and address performance problems if and when they arise.
-replaced all PI references with M_PI version
-there is no need to do the angle-modulo in float, casting it to an integer does the same BUT it has to be cast to an `int` first, see comment.
* fixed the positioning of the download button
* fixed space after "Download the latest binary:" disapering after building
* fixed typo
---------
Co-authored-by: maxi4329 <maxi4329>
- `sin16_t() / cos16_t()` are faster and more accurate than fastled versions
- `sin_approx() / cos_approx()` are float wrappers for `sin16_t() / cos16_t()` and are accurate enough to replace `sinf()/cosf()`
- `atan2()` is used only in octopus to calculate center offset, new approximated version saves flash
- `tan(), atan(), asin(), acos(), floor(), fmod()` are used only for sunrise/sunset calculation, using wled_math version saves flash
- `beatsinx()` replacements are to make use of new `sin16_t()/sin8_t()` functions to reduce flash size
- Extensively tested surnise/sunset calculation: deviation is 1min. max
- Tested some of the relevant FX and found no visual difference: Julia, 2D Drift, Drift Rose, Ghost rider, Rotozoomer, Palette, Arc 1D expansion
- total flash savings: 7.4k
- changes to `setPixelColorXY` give an extra FPS, some checks and the loops are only done when needed, additional function call is still faster (force inlining it gives negligible speed boost but eats more flash)
- commented out the unused `boxBlur` function
- code size improvemnts (also faster) in `moveX()` and `moveY()` by only copying whats required and avoiding code duplications
- consolidated the `blur()` functions by enabling asymmetrical blur2D() to replace `blurRow` and `blurCol`
- compiler warning fixes (explicit unsigned casts)
- removing WS2812FX::setMode()
- removing WS2812FX::setColor()
- removing floating point in transition
- color handling modification in set.cpp
- replaced uint8_t with unsigned in function parameters
- inlined WS2812FX::isUpdating()
- (MAY BE BREAKING) alexa & smartnest update
* adding missing flash size flags that were lost between 0.14 and 0.15
(necessary if you don't flash using esptool)
* adding env:esp32dev_16M for 16MB flash (serg74 esp32-16M, twilightlord esp32 16M)
- Added pre-calculation for segment brightness: stored in _segBri. The impact on FPS is not huge but measurable (~1-2FPS in my test conditions)
- Removed `bool unScaled` from `setPixelColor()` function again (it has no/minimal impact on speed but huge impact on flash usage: +850 bytes)
- Removed negative checking in `setPixelColorXY()` and replaced it with a local typecast to unsigned, saves a few instructions (tested and working)
- Changed int8_t to int in `moveX()` and `moveY()`
- Removed a few functions from IRAM as they are now not called for every pixel but only once per segment update
- Removed a `virtualWidth()` call from `ripple_base()`
- Bugfix in `mode_colortwinkle()`
Use the phase-locked soft PWM from the Arduino core to implement the
same PWM phase management as ESP32s are using. The soft PWM code is
vendored in, as it was previously, to add the NMI workaround from #4035.
Completes #4034
uint16_t to unsigned to make it consisten throughout the hand-down.
colorFromPaletteWLED now returns uint32_t which saves the conversion to CRGB and back to uint32_t (in most uses at least).
also added (preliminary) CRGBW struct. I tried to use it in place of uint32_t colors but it adds a lot of overhead when passing the struct so reverted to uint32_t in most places.
updated a few FX to use the CRGBW struct and also cleaned some code to improve flash useage.
- also added a struct to handle HSV with 16bit hue better (including some conversions, can be extended easily)
- the functions are optimized for speed and flash use. They are faster and more accurate than what fastled offers (and use much less flash).
- replaced colorHStoRGB() with a call to the new hsv2rgb() function, saving even more flash (new function is untested!)
- the 16bit hue calculations result in an almost perfect conversion from RGB to HSV and back, the maximum error was 1/255 in the cases I tested.
- blurring now uses desaturated adding: it is faster most of the times and blurring adds scaled colors so should rarely (ever?) saturate, I saw no visual difference in tests.
- formatting
Remove the large stack buffer as we're just going to copy it in to a
heap buffer anyways. Later we can refine the length estimation or use a
rope-style dynamic data structure like DynamicBufferList.
- optimized color_add() again: now it is as fast with preserved ratio scaling than the "fast" variant was before (if no scaling is needed, it is even faster). plus it saves 250 bytes of flash
- bugfix in `color_fade()`
- removed a lot of whitespaces
- gamma correction only where needed
- paletteIndex should be uint8_t (it is only used as that)
note: integrating the new `ColorFromPaletteWLED()` into this would require a whole lot of code rewrite and would result in more color conversions from 32bit to CRGB. It would be really useful only if CRGB is replaced with native 32bit colors.
- there already is a method to calculate the table on the fly, there is no need to store it in flash, it can just be calculated at bootup (or cfg change)
inlining getMappedPixelIndex gets rid of function entry instructions (hopefully) so it should be faster.
also added the 'multi color math' trick to color_add function (it will not make much difference but code shrinks by a few bytes)
uses less flash so it should be faster (did not notice any FPS difference though)
also cleaned code in ColorFromPaletteWLED (it is not faster, same amount of code)
This change ensures that the dates are displayed on their own lines.
Without the blank lines, many Markdown renderers will append the dates
to the previous bullet point.
- Renamed LEDPIN to DEFAULT_LED_PIN.
- Removed ability to override DEFAULT_LED_PIN, DEFAULT_LED_TYPE and DEFAULT_LED_COUNT. Use DATA_PINS, LED_TYPES and PIXEL_COUNTS instead.
* only reject invalid ranges when array access will be actually performed
* fixed another stupid pointer arithmetic error
Hint: I AM NOT THE MAINTAINER of this usermod. I'm just fixing an obvious coding error without knowing what the usermod really does.
some users have reported that releases after 0.14.0 are not working reliably. So we add a few "compat" for 8266 that try to reproduce the buildenv of 0.14.0 as much as possible.
* platform and platform_packages from 0.14.0
* not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
* due to smaller IRAM, we had to move some functions back from IRAM to normal flash (may cause slowdown)
some users have reported that releases after 0.14.0 are not working reliably. So we add a few "compat" for 8266 that try to reproduce the buildenv of 0.14.0 as much as possible.
* platform and platform_packages from 0.14.0
* not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
* due to smaller IRAM, we had to move some functions back from IRAM to normal flash (may cause slowdown)
* added #include <Arduino.h> - this is basically what the preprocessing tool (wled.ino -> wled00.ino.cpp) does
* added a comment that Arduino IDE is not supported, use platformIO.
Setup is really easy, after first boot and WiFi/LEDs setup:
go to wled.local/edit and upload a couple image to WLed's filesystem.
Only PNG is supported right now, further support for GIF is planned.
The image should be as wide as the 1D segment you want to apply to.
When done, go to the Effect page on the UI, select "POV Image" effect.
You could also update the image with a post to the JSON-API like this:
curl -X POST http://[wled]/json/state -d '{"seg":{"id":0,"fx":114,"f":"/axel.png"}}'
The segment should move at around 120RPM (that's 2revolutions per seconds) for an image to showup.
More informations and pictures here : https://lumina.toys
* speedup: add functions to only blur rows or columns (50% faster)
* fire2012: tinkering with bur options. Vertical blur only when slider < 64 (faster); extra blur for slider values >192 (bush burn)
On ESP8266, it isn't permissible to call delay() in system context;
ensure this is legal before waiting.
On ESP32, use an operating system mutex to ensure consistent variable
state in a multicore environment, and manage the wait without needing
to loop.
before a x=32 (n times of 16) had not equal sized bars, but first was
a single pixel and later a bar had 3 pixel width. This solves it to
have always 2 pixel sized bars.
I have to admit that I did not test with other pixel dimensions.
boot-up delay to fix wifi not starting in some setups
use
`-D WLED_BOOTUPDELAY=500` (or some other delay you want, in milliseconds)
in platformio env definition to add 500ms of delay before hardware init.
* fixed a few typo's in comments
* fixed 8266 specific warning about 'comparison of integer expressions of different signedness'
based on recommendations made by @willmmiles:
* make sure that audioSyncPacket is the same size (44bytes) on all platforms
* use static buffer for receiving (avoids heap fragmentation)
* copy receive buffer to local audioSyncPacket struct - avoids alignment problems
* esp32 only: to stay in sync with UDP, Udp.flush() is needed when Udp.parsePacket() is _not_ followed by Udp.read()
Simplified the code by removing an unnecessary function definition and instead using direct assignment in the place where the function was previously called.
Vendor in the ESP8266 Arduino core PWM library, with a fix for a nasty
NMI crash bug. Sometimes the NMI return instruction seems to fail,
resulting in an infinite loop as the PC gets stuck. Work around this
by backing up and restoring the PC if needed.
# Added high temperature indicator/action...
- A configurable preset is activated when the internal temperature raises above a configurable threshold temperature.
- When the internal temperature falls back below the threshold, the previously active preset is re-activated.
- To prevent frequent toggling between states when the temperature is close to the threshold, the reset threshold is slightly lower than the activation threshold to provide a small buffer.
- Reset threshold is automatically calculated to be two degrees lower than whatever the activation threshold is set to.
- To prevent the user setting the loop interval too low, a minimum allowable interval has been added.
- edit WiFi TX power (ESP32)
- keep current ledmap ID in UI
- limit outputs in UI based on length
- wifi.ap addition to JSON Info
- relay pin init bugfix
- file editor button in UI
- update NeoPixelBus to v2.8.0
- use single/mono I2S + 4x RMT for 5 outputs or less
- use parallel x8 I2S + 8x RMT for >5 outputs (limit of 300 LEDs per output)
- replace uint8_t and uint16_t with unsigned
- replace in8_t and int16_t with int
- reduces code by 1kB
- WARNING may break effects that rely on overflow/narrow width (most fixed)
* setPixelColor: ensure that 0/0 is used
* getPixelColor: accuracy improvements
unfortunately, "scrolling" audioreactive effects are still not working properly - they end after 1/4 of the circle. Could be due to limited resolution of getPixelColor.
fixing holes that appeared during testing
* at 52x52 (big 296 -> 304)
* at 24x32 (medium 192 -> 208)
* at 12x16 (small 72 -> 82)
... there is still one hole at 14x16 ... well wtf
- increased outputs to 17
- increased max possible color order overrides
- use WLED_USE_PARALLEL_I2S during compile
WARNING: Do not set up more than 256 LEDs per output when using parallel I2S with NeoPixelBus less than 2.9.0
The BME280 usermod uses a multiply-round-divide approach to cap the temperature/humidity/pressure values to some number of decimals. But the divide-part was missing in a few instances.
Issue:
When taking the initial voltage reading after first powering on, voltage hasn't had chance to stabilize so the reading can be inaccurate, which in turn may incorrectly trigger the low-power preset. (Manifests when the user has selected a low read interval and/or is using a capacitor).
Resolution:
A non-blocking, fixed 10 second delay has been added to the initial voltage reading to give the voltage time to stabilize.
This is a reworked version of the (now closed) PR here:
https://github.com/Aircoookie/WLED/pull/3959
- Rebased the update for 0_15.
- Added a constant so the delay can be modified via my_config.h.
- Small adjustments to make the PR compatible again after the recent restructuring in this PR: (https://github.com/Aircoookie/WLED/pull/3003).
Thankyou!
Script update based on latest version from Tasmota
* add support for all esp32 variants
* add "-C" : Decode (demangle) low-level symbol names into user-level C++ names.
The build script was not looking into the right place, so there was never a .map file dropped into build_output/map/
Builds with the newer arduino-esp32 v2.0.x framework actually generate a .map file that is placed directly next to firmware.bin
* trying to make the caching mechanism bulletproof.
`cacheInvalidate` is changed when
- autosave usermod updates presets
- a file was upload
* (coding style) fixed some unitialized variables
- several compile warning fixes
- multipin LED compile config
- release info (update page, JSON "info")
- WiFi scan fix if no networks found
- UI glitch when no presets are found fix
With multipin LED config it is now possible to assign GPIO to PWM RGB outputs.
Achieved by having length of DATA_PINS be divisble by lengt of PIXEL_COUNTS.
-changes save roughly 600bytes of flash
-made blurring faster by not writing the color and then reading it back but keeping it as a variable: on a C3, FX black hole goes from 55FPS to 71FPS
-added optional parameter to blur (smear) that can be used in combination with SEGMENT.clear(), blurring the frame without dimming the current frame (repeated calls without clearing will result in white). this is useful to blur without 'motion blurring' being added
-scale8 is inlined and repeated calls uses flash, plus it is slower than native 32bit, so I added 'color_scale' function which is native 32bit and scales 32bit colors (RGBW).
- transitions always enabled (use delay 0 to disable)
- optimisation in on/off fade
- fix for palette/color blend when blending style is not fade
- various tweaks and optimisations
Fix use-after-free issue and slightly improve code size. Note that the
version is changed to a hard pin, so future updates can be validated
before getting picked up by new clones, and old version builds
are reproducible.
By explicitly listing an unversioned framework dependency in
'platform_packages', we were overriding the selection via the 'platform'
specification, allowing PlatformIO to select any random version.
Remove this line to allow 'platform' to add the framework dependency
with the expected version.
use latest platformIO package, to avoid build errors due to missing 'scons'
> Tool Manager: Installing platformio/tool-scons @ ~4.40400.0
> Error: Could not find the package with 'platformio/tool-scons @ ~4.40400.0' requirements for your system 'linux_x86_64'
> Error: Process completed with exit code 1.
If the source never sends the push flag, WLED buffers the update but
never publishes it to the LEDs. This causes the confusing case where
the peek display shows one thing but the LEDs themselves something else.
Add a static flag that tracks if we've seen a push from the source;
until we do, apply every update as soon as it's received, per the DDP
specification.
There were three problems here:
- AsyncWebServer is going to copy to a heap buffer anyways, so we might
as well just pass it one it can use
- The buffer size estimate was wrong -- we need 9 bytes per pixel
("RRGGBB",), so the buffer could overflow, and it was not
considering the extra 2D requirements
- On ESP8266, the stack allocation was overflowing the stack, causing
corruption and crashes.
-added minimum threshold, had some crashes when setting threshold to zero before
-moved interrupt detach to GPIO deallocation where it belongs
-added check for touchbutton before detaching interrupt
-moved thochThreshold readout up so it gets updated before passing it to the system call
Release the json buffer lock as soon as we've finished serializing.
This should slightly reduce the number of lock collisions as the
response class isn't destructed until after the last packet is ack'd.
Release the json buffer lock as soon as we've finished serializing.
This should slightly reduce the number of lock collisions as the
response class isn't destructed until after the last packet is ack'd.
-added fully random palette function ('the old way', currently just used for initialization)
-changed randomness values to make it a little less random
-added 10% chance for pastel color palette
-now using swap() from std library for shuffeling
-changed function name
-moved update check from loadPalette() to handleRandomPalette() saving CPU cycles
There is a version of the Olimex ESP32-POE board with an ESP32-WROVER
module which has a the ethernet clock connected to a different IO than
the version with an ESP32-WROOM module.
This commit adds a new runtime selectable variant for the WROVER version.
Due to the midi interface being difficult/impossible to increment on
values of 1 because it has 7-bits of granularity, this commit moves all
the bitfields for configuring segment options left by one which
guarantees that every option has 2 values next to each other.
This allows midi controllers to more easily select an individual segment
option for 2D arrays.
Before this commit it was only possible to control mirror and reverse on
a 1d segment. All of the other options for 2d effects could not be set
and thus they would be kept disabled.
This commit replaces the Effect Option dmx channel with a bitfield which
allows for each segment option to be individually toggled depending on
which bit is set in the field. Backwards compatibility has been
maintained with existing 1d segment options.
Upgrade the MPU6050 usermod to provide configuration settings for
interrupt pin selection and calibration, a polled mode, and data
output for consumption by other usermods.
The MPU6050 library happens to choose the same defines as WLED, which
collide and result in nothing printing. Un- and re-define the macros
to work around this.
Add JSONBufferGuard, an RAII lock guard class for JSONBufferLock
analogous to std::lock_guard. This permits binding the guard to a scope,
such as an object life cycle or function body, guaranteeing that the
lock will be released when the scope exits.
Allows for "pixel perfect" liveview instead of diffused view, to better match what's shown at https://kno.wled.ge/features/effects/. This will make it easier to see what the LEDs are doing, although it may not be as accurate a representation for installations with diffused LEDs. Includes fallback to CSS gradient method for browsers that don't support canvas.
sunset = 0 is a valid result, as the function result is in UTC and not local time .
Example: local time is UTC-8, local sunrise = 08:00am => getSunriseUTC() = 0.
So we cannot use "0" for "invalid". Using UINT16_MAX resolves the problem, and even allows to simplify calculateSunriseAndSunset() a bit.
According to the technical manual, GPIO 16 + 17 are used for onboard flash, so cannot be used by WLED.
example buildenv:
[env:esp32_pico]
extends = env:esp32dev_qio80
board = pico32
I've found a code spellchecker, so this is what can be corrected easily. Changes are only affecting comments, readme and a few user-visible strings. So no functional impact expected.
* purge old (not yet processes) NTP responses
* validate server responses before updating WLED time
* purge receive buffer when package is rejected (avoids mem leak on esp32)
By setting the response header "Cache-Control" to "no-store" and setting "Expires" to 0, we make sure the browsers and place calling this never store it in cache.
- CSS adjustments
- Removal of some html
- Correction of CORS error when using the file locally, it was unable to generate the images that are saved in WLED
- Among others that I don't remember now
- Correction in animation generation that was actually breaking
- Button to return to WLED if pxmagic.htm is accessed via url (http://), if accessed via external (file://) the button will not show
- Adjustments to CSS and some features
Since PXM will not open internally but on another page from the button, I decided to add the logo again if it's not a problem of course.. Just so I don't run out of information
commit 1dab26bcbc
Author: Christian Schwinne <dev.aircoookie@gmail.com>
Date: Thu Oct 19 13:29:46 2023 +0200
Update Discord invite links to point to guidelines channel
I added the possibility of using the tooltip on buttons (.btn) with the span inside the button;
Adjusted the tooltip css to center 100% in the middle
Some cleaning and correction of sele
Having the wrong pin would result in a server error (500). The more appropriate error code for that would be 401.
This also changes the page that asks for users to login from 200 to 401.
audioSyncPacket contains four "invisible" padding bytes added by the compiler. These need to be initialized to zero, as future versions of the protocol will make use of these fields.
Topic 1, 2
I made the change, took it off the website and put it in the Preset section under the +Preset, +Playlist buttons, it was in a good location.
Topic 3, 4
It reloads because it needs the updated information so that it can create the preset correctly with all the information generated from the selected image.
Topic 5
The change has already been made, it just hasn't gone up yet, it's default upload
Topic 6, 7
Fixed
Many bad quality analog mics are not centered properly at 1.6V, but stuck at 0V or stuck at 3.3V in silence. The bandpass filter removes DC offsets and improve signal quality.
* debug messages added to different initializers
* SPH0654::initialize() was having a wrong signature: uint8 instead of int8.
C++ can be a real bastard ;-)
* improves robustness of the Matrix effect, by dynamically adjusting the "reference color" used to identify "falling code" head pixels.
* a bit faster, as I've removed the need to scan all pixels a second time for "black screen" detection.
Its still not perfect, and the main loop could be simplified a lot by leveraging on the fact that all changes actually happen in the top row, and "falling" is actually just moving everything down by one pixel.
Update ES8388Source::initialize and ES7243::initialize method signatures to match I2SSource::initialize so that when initialize is called on a AudioSource pointer the child class's method is used.
Remove sync receive
Disallow 2D effects on non-2D segments
Optimisations
Sync clarification
AR palettes
Return of 2 audio simulations
Bugfix in sync #3344
- remove excessive segments
- ignore inactive segments if not syncing bounds
- send UDP/WS on segment change
- pop_back() when removing last segment
Add pairing support for ESP-NOW sync
Reduce string RAM footprint
UDP parse optimisation
Make WizMote work with sync.
ESP-NOW wireless sync POC.
- caveat: devices have to be on the same channel
- clashes with WizMote handling ATM
To make it better readable and prevent copy&paste errors, all needed flags can be referenced from the "esp32" buildenv:
${esp32.AR_build_flags}
${esp32.AR_lib_deps}
* remove "not supported" warning on -S2
* minor tweaking of beat detector
* optimized parameters for arduinoFFT
* fixed a few implicit "double" promotions
* minor UDP protocol optimizations
* small optimization for fft task create / suspend
* completely remove analogmic settings for -S3/-S2/-C3 where analog is not supported
changes were already tested extensively in the MM fork.
this is a band-aid fix for random crashes when switching between presets with multiple segments - crossfade disabled.
!! adding type initializers fixed it for me on -S3, however I still see (less frequent) crashes on esp32, due to heap corruption.
It took me hours to get a meaningful stackdump:
assert failed: heap_caps_free heap_caps.c:360 (heap != NULL && "free() target pointer is outside heap areas")
Backtrace: 0x40084ee1:0x3ffb2570 0x4008e341:0x3ffb2590 0x40094709:0x3ffb25b0 0x4008534a:0x3ffb26e0 0x40094739:0x3ffb2700 0x400e9037:0x3ffb2720 0x400e917c:0x3ffb2740 0x400eaeeb:0x3ffb2760 0x40117ec5:0x3ffb27c0 0x401184ea:0x3ffb2800 0x4013509d:0x3ffb2820
#0 0x40084ee1:0x3ffb2570 in panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c:402
#1 0x4008e341:0x3ffb2590 in esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:128
#2 0x40094709:0x3ffb25b0 in __assert_func at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/assert.c:85
#3 0x4008534a:0x3ffb26e0 in heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:360
(inlined by) heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:345
#4 0x40094739:0x3ffb2700 in free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/heap.c:39
#5 0x400e9037:0x3ffb2720 in Segment::deallocateData() at wled00/FX_fcn.cpp:189
#6 0x400e917c:0x3ffb2740 in Segment::resetIfRequired() at wled00/FX_fcn.cpp:206
(inlined by) Segment::resetIfRequired() at wled00/FX_fcn.cpp:203
#7 0x400eaeeb:0x3ffb2760 in WS2812FX::service() at wled00/FX_fcn.cpp:1216 (discriminator 2)
#8 0x40117ec5:0x3ffb27c0 in WLED::loop() at wled00/wled.cpp:115 (discriminator 3)
#9 0x401184ea:0x3ffb2800 in loop() at C:/src/wled00/wled00.ino:20
#10 0x4013509d:0x3ffb2820 in loopTask(void*) at C:/Users/user/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:50
ELF file SHA256: 18c20b536f4c6ef4
bracket was on wrong position, resulting in this warning:
wled00/set.cpp:357:79: warning: value computed is not used [-Wunused-value]
strlcpy(mqttGroupTopic, request->arg(F("MG")).c_str(), MQTT_MAX_TOPIC_LEN)+1;
oappend() silently discards strings when the buffer is full, leading to strange effects like half-working UI pages.
The new debug message will help developers to understand what could be wrong.
- breaking change
- remove leading 0 checkmark
- add reverse scroll checkmark
- add vertical scroll if text fits into segment (intensity ==0 or ==255)
- rotated characters
- leading 0 check added to short texts (i.e. #DDMM0)
Fixes#3322
* Blurz and a few other effects would crash (or behave unexpectedly) for single pixel segments
* replaced a few "MAX" by "max", because MAX will evaluate its arguments twice so its very inefficient.
changes from 3.50 to 3.6.0:
* bugfixes
* removed "register" keyword
* some speedups
* explicit bool() and uint32_t() operators, see https://github.com/FastLED/FastLED/issues/819
FX.cpp: bugfix for "wled00/FX.cpp:4906:36:
error: cannot convert 'CRGB' to 'uint32_t' {aka 'unsigned int'} in initialization"
platform 5.3.0 = arduino-esp32 v2.0.6 + esp-idf v4.4.3
--> you will need new bootloader files for arduino-esp32 v2.0.6
--> coredumps are supported now, if you leave 64Kb of flash at the end of your partitions file (see example in wled_esp32_8MB.csv)
turns out that fastLED 3.6.0 has an explicit uint32_t operator that returns RGBA, however 3.5.0 does not have this and the conversion returned only the "red" component".
turns out that fastLED 3.6.0 has an explicit uint32_t operator that returns RGBA, however 3.5.0 does not have this and the conversion returned only the "red" component".
it seems that SEGMENT.blur() is the main bottleneck for many 2D effects.
This change optimizes performance of the function:
* avoid to re-write unchanged pixels
* early exit when blur_amount == 0 (=nothing to do)
* use _fast_ types where possible
I've seen up to 20% speedup with this change.
power estimation results from estimateCurrentAndLimitBri() were too low (example: estimated 1.3Amp, measured 1.6Amp). This change corrects the power calculation. Due to the changed behavior of getPixelColor, powerSum must be used as-is, not scaled down again by brightness.
minor optimizations that give up to 10% speedup in my tests
* use "fast" integer types (where possible)
* replaced _bri with _restaurationBri (no use of globals)
this optimization avoids to apply brightness two times .
NeoPixelBusLg has already applied global brightness at sPC. Due to internal working of the Lg bus, its sufficient to only post-apply scaling, and set the new (scaled) brightness for the next frame.
I still see strange crashes in setPixelColor/GetpixelColor, which ssem to come from race conditions between async_tcp (change presets) and looptask (strip.service).
To make the situation better, its important that any global pointers are reset to NULL immediately after free().
* Avoid uint16 underflow in width() and height(): stop > start is possible, and means "inactive segment".
Without these checks, it was possible that width() and height() produce VERY large values due to underflow.
due to `if (strip.isUpdating()) return;` reading the encoder did not happen in time if the strip was active - with high number of LEDs, this means "always updating". Similar observation that we had with the audioreactive usermod, and similar solution.
* adding an optional parameter to setBrightness(). ApplyPostAdjustments() will only be called if `immediate=true`. Only ABL will use immediate=true, to ensure electrical safety of equipment.
This allows some optimizations of performance, as ApplyPostAdjustments() is time consuming.
* busses.setBrightness(bri) --> applied to all future pixels (fast, lossless)
* busses.setBrightness(bri, true) --> applied directly to all previously set pixels (slower, lossy)
* Adding Pixel Magic Tool to WLED
* Revert "Adding Pixel Magic Tool to WLED"
This reverts commit b4f08fa8d5.
* Adding Pixel Magic Tool to WLED
* Corrections and performance improvements
* Remove IE compatibility tag
(saves a few bytes and IE10 is over 10 years old and unsupported)
Correct HTML language attribute
(Chrome would show a popup asking to translate from Portugese)
* Corrections and performance improvements
* Enable pxmagic by default
---------
Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* Initial checkin for ESP-NOW remote feature
* cleanup irrelevant comment
* don't bring in espnow package includes when feature disabled
* Formatting and removing inaccurate call mode hardcoding
* Fork ESP Now code by platform (8266 v. esp32)
* compiled html update
* Disable ESP-NOW remote by default on ESP32 until tested
* Enable ESP-NOW remote for ESP32
* Rename ESP NOW define
---------
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
(saves a few bytes and IE10 is over 10 years old and unsupported)
Correct HTML language attribute
(Chrome would show a popup asking to translate from Portugese)
* allow user to control rotation speed (c3 slider)
* preserve accuracy by performing division _after_ multiplication: " (i * speed) / 32", instead of " i * (speed / 32)"
* proper rounding of "map" results, for better visual appearance
* avoid division by zero in map() function
* Buttons: Trigger when pressing if all configured presets are the same
* Add debounce for immediate rising-edge short press
---------
Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
* Changes for allowing Alexa to change light color to White when auto-calculating from RGB
* Update alexa.cpp
Indention
* Do not rely on global auto white override
(gets white mode from segment light capabilities)
* alexa.cpp: Removed unnecessary whitespaces
---------
Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
Fix repeat segment button remaining hidden
Fix third segment row (offset) alignment in 1D mode
Keep disabled sound simulation modes as comment for reference
New local var for 2D seg UI, improves code legibility
* fix DDP spec
* Adjust DDP type byte to latest spec
Allow receiving of RGBW DDP with either old or new bits per channel value
---------
Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
* PSRAM_Allocator was missing the "reallocate" method, which lead to undefined behaviour when dynamic JSON doc needed to grow/shrink
* Segment::setUpLeds() quickfix for length() == 0 (should not happen, but it did happen for me once)
* leds in PSRAM causes major slowdown on wrover boards - disabled.
* prevent string buffer overflows (stack corruption)
* avoid division by zero (program might crash)
* avoid log(0) which is undefined, too
* use faster math routines for float (logf, powf)
* use size_t instead of uint16_t -> prevents random behaviour (corruption) in case that JSON files get larger than 64Kbytes.
* use a constant for max large file space (was UINT16_MAX)
* reduced the scope of some functions and variables to "static" - avoids name clashes and may support better optimization by the compiler
fix for "Error: Invalid environment name 'codm-controller-0.6-rev2'. The name can contain alphanumeric, underscore, and hyphen characters (a-z, 0-9, -, _)"
* Improve indent
Improve indent, so its more allignend and correctly indented according to logic groups
* Spaces to tabs
---------
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* Add UCS890x support.
* Fixes
* Update NeoPixelBus to 2.7.3 for UCS8904 support.
Update ESP8266 core to 4.1.0
* ESP8266 compile fixes.
- use PlatformIO framework and toolchain
- add compiler warning suppression
- remove IRAM_ATTR to fit in IRAM
* Replace NeoPixelBrightnessBus with NeoPixelBusLg
Resolves#3087
* Update to NPB 2.7.4
* Internal NPB color conversions.
* Fix errors due to merge with SPI Hz methods
Regenerate settings page HTML
---------
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
* Soap, new 2D effect
* Fix Soap FX on matrices with edges < 8 LEDs
* Add palette support to Soap FX
---------
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* - fix word clock for "viertel vor" and "viertel nach"
- adjust wording of parameters
* - revert changes for parameter names
* enclose JSON property strings in F() macro to reduce RAM usage.
* add parameter info for "norddeutsch" and "LedOffset"
art-net transmit was not sending out LEDs, but only transmitted headers repeatedly (thanks @troyhacks for noticing).
Actually such problems can be found by newer compilers, so i've added the warning option to [esp32_idf_V4].
wled00/udp.cpp: In function 'uint8_t realtimeBroadcast(uint8_t, IPAddress, uint16_t, uint8_t*, uint8_t, bool)':
wled00/udp.cpp:824:40: warning: declaration of 'byte buffer [12]' shadows a parameter [-Wshadow=compatible-local]
byte buffer[ART_NET_HEADER_SIZE];
^
wled00/udp.cpp:720:85: note: shadowed declaration is here
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8_t *buffer, uint8_t bri, bool isRGBW) {
- fixed a few typos, trailing spaces and bad alignments
- added the previous 8266 platform packages as a comment, just in case
- [env:esp32dev_V4_qio80] is actually "dio" --> renamed to [env:esp32dev_V4_dio80]
- all esp32dev targets use the same ${esp32.platform} now (3.2.0 would not compile any more)
- corrected some broken references
- added `platform_package =` --> use default packages
- renamed env:esp32c3 to env:esp32c3dev to avoid confusion
- added lolin_s2_mini to CI builds
Like DDP, this allows WLED to address network systems using the Art-Net protocol.
Universe starts at zero, because that's the first universe in Art-Net.
Works with RGB. It's coded to also work with RGBW, but I couldn't find a great place to enable it without mucking with things I don't understand.
* xml.cpp: correct type for checkbox global led buffer" (was not shown correctly)
* fx.cpp: 2D floating blobs - correct swapped x/y coordinates (did not render correctly on non-square matrix)
One pixel segment handling.
- added 0D FX metadata (1 pixel effects)
- ignore palettes for White only segment
- ignore color for non-RGB & non-White segment (on/off)
Bugfix
- proper auto segment creation
- hide palettes for non RGB segments
- some tweaks for #2984
- force Solid for some FX (causing crash) on 1 pixel segment
UI Optimisations
- slider tooltips
- tiny bit smaller tooltips
- hide segment power if only one segment
- gap between sliders
* Support white addressable LED strips
* Various white handling tweaks
Allow RGB controls for white-only busses depending on AWM (makes palette-only FX work on non-RGB addressable busses)
Fixed RGB controls hidden if segment contained any non-RGB bus (even though there is also an RGB bus in that segment)
New Max auto white mode
Added hasCCT() bus method
Rename methods to be clearer
WS2811 White getPixelColor fix()
* Fix merge conflict (bus manager cpp)
* Refactor bus manager.
* Fix for net debug
* Fix 8266 compile
* Move bus static members to proper cpp
---------
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* pulser bugfix: " % cols" was missing so the effect would simply run out of visible range
* float math: use optimized functions: sqrtf, fabsf
* two more comments where code could be optimized, but I'm not sure what is thecorrect solution
- Ripple (2D & no Bg)
- Glitter (no Bg)
- Sparkle (no Bg)
- Scan (no Bg)
- Two dots (no Bg)
- ICU (no Bg)
- Lightning (no Bg)
- Halloween eyes (no Bg)
- Spots (no Bg)
- Bouncing Balls (no BG)
- Popcorn (no Bg)
- Starburst (no Bg)
- Drip (no Bg)
- Whitespace cleanup
- draw_circle()
"no Bg" will allow overlapping segments if checked.
* added missing pinMode(.., INPUT) on esp32
* do not try reading from pin = -1 (ESP32-S2 shows very allergic reactions to this)
* Info page - show "n/a" when pin = -1
* readme: esp32 default pin = 35
Fixes build error on linux:
wled00/usermods_list.cpp:15:54: fatal error: ../usermods/battery/usermod_v2_battery.h: No such file or directory
compilation terminated.
.. overlooked this one when reviewing the PR.
@blazoncek, @ctjet : three questions on the new code remain, because its not clear to me if its correct. Please check.
Retrieving the config in `readFromConfig()` results in defaults being set to both `hourMarksEnabled` (`false`) and `hourMarkColor` (`#0000FF`) due to differences in capitalization compared to how they're saved in `addToConfig()`
I was wondering why sometimes the new MCUs still work better in Arduino IDE, so compared our build flags to what is used in Arduino IDE:
-S2 always has -DARDUINO_USB_MODE=0
-C3 always has -DARDUINO_USB_MODE=1
-S3 supports all possible modes
- switch off debug messages to USBCDC, if WLED_DEBUG is not set
- ensure that analogread pins are valid - invalid pins cause lots of error messages and finally lead to watchdog reset on some MCUs.
* make SparlFunDMX driver more robust:
- made variables static (so they don't overlap with other global variables)
- made sure all valriables are properly initialized
- do not apply pinMode and digitalRead to invalid pins (as this creates problems on -S3, -C3 and -S2)
* disable DMX sending code (unneeded code that may case troubles)
unfortunately this breaks build for -C3 and -S3
/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32c3/include/riscv/include/riscv/semihosting.h:75:19: warning: ignoring asm-specifier for non-static local variable 'a0'
register long a0 asm ("a0") = id;
^~
.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32c3/include/riscv/include/riscv/semihosting.h:76:19: warning: ignoring asm-specifier for non-static local variable 'a1'
register long a1 asm ("a1") = (long) data;
pinmanager ran out out array bounds on -S2 and -S3, as these MCUs have more than 40 GPIO. As consequence, memory was overwriten, and pins > 39 were reported as "allocated" but not "owned".
Thisfixes the problem, by extending internal arrays so that up to 50 pins can be managed.
* audioreactive driver update
- Better handling of PDM and I2S Line-in
- Bugfixes for ES7243 (allocateMultiplePins)
- More error messages for ES7243
- sample scaling (needed for sources that use full scale of samples)
* audiorective update
* align SR_DEBUG with WLED_DEBUG
* optional bandpass filter (needed for PDM mics)
* sample scaling for PDM and Line-In
* small improvements for analog input
* bugfixes and small performance improvements
* code for FFT task refactored, for better readablity. Introduces separate functions for filtering and post-processing
* small improvement for beat detection
* default mic settings can be configured at compile time
* correct mic type if MCU does not support PDM or ADC
* hide analog PIN config if not supported by MCU
* audioreactive updates
- minor updates to source code (see discussion in PR #2907)
- usermod readme improvements
* small readme update
* one think I overlooked
* ok, another edit. Now its final. Hopefully.
* small upps
wrong parameter order in debug message.
* Do not require commas between ! in fxdata
* Updating fxdata: Halfway through the FX list
* fxdata flags and optimizations
* Revert optional commas after !
* Grouping um settings, add pre and post Info, update SR & 4LD settings
Settings_um.htm:
- modify addField (grouping)
- addInfo (pre and post texts)
Add preInfo to audio reactive and 4ld usermod
Extra:
platformio: wemos_shield: add audio reactive usermod and update to alt display
* um settings: cpp: lowercase, js: initcap
* um settings: txt only pre, txt2 only post and initCap as function
* Fix rotary encoder info string
Co-authored-by: Blaž Kristan <blaz@kristan-sp.si>
* feat(json): add wifi scanning
Adds wifi scanning to the JSON api at `/json/networks`. The initial
request will trigger a scan, subsequent requests will scan or return the
results depending on the state of the `WiFiScan`.
Add a `Scan` button next to the client ssid input, on click, scan for
networks, and change the input to a select with the found ssids.
Fixes: #1964
* Added option to go back to manual SSID input
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* feat(wifi): add compile time configurtation
Add `WLED_AP_SSID` and `WLED_AP_PASS` defines to allow configuring the
SoftAP SSID and Password at compile time. Default to existing values.
Add `WLED_AP_SSID_UNIQUE` flag to append the device portion of the mac
address to `WLED_AP_SSID`.
Exampleof all flags (note the quoting to preserve
"stringification"):
```
build_flags =
-D WLED_AP_SSID='"MyAP"'
-D WLED_AP_PASS='"MyPassword"'
-D WLED_AP_SSID_UNIQUE
```
* Removed two error defines
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* Implement optional hour marks
Time offset did not work
* removed undefined error int in hexstringtocolor
* revert cosmetic changes
* minor cosmetic changes
Co-authored-by: mdegraaf <mdegraaf@proxsys.nl>
* Effect ID's back to 0.13 numbering
Needed for sync between versions and allow 0.13 presets to work in 0.14
* Effect ID's back to 0.13 numbering (part2)
* Add network debug printer
* hide settings for disabled features
If not enabled at compile time, this change hides "Sync interfaces" settings for Alexa, MQTT, Blynk, HueSync.
The html sections are just hidden by a <div> with style display:none.
* Update Animated Staircas for 0.14
* Faster strip updates.
* Add ESP32 variant display in update page.
* Net debug optimizations
Fix ESP8266 (unaligned progmem flash string reads)
Do not send an extra package for \n in println
Only resolve IP/hostname once
* Compile time option for PIR sensor off timer
* Fix Gitpod compiling (#2875)
* Install Platformio not in Gitpod Image
* Install platformio at runtime
remove outdated extensions
* Bugfix for color transitioning.
Return palette option for Candle.
Fix for "* Color..." palette hiding.
Comment out debug output.
* Optimization & bugfix for net debug.
- Inherited from Print class.
- Added UI option to disable net debug output.
* Reduce fxdata size by about 200 bytes
Removed redundant commas before semicolon delimiter (`,;` -> `;`)
No need to transmit `@` in /json/fxdata
* NetworkDebugPrinter packet optimization.
* Revert NetworkDebugPrinter changes.
* Remove flush() in bus manager.
* Optimizations.
Co-authored-by: Shaheen Gandhi <shaheen@fb.com>
Co-authored-by: Blaz Kristan <blaz@kristan-sp.si>
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
* Automatically set PC Mode if unset
based on the UserAgent
* slight reduction
Reduce flash usage a bit.
Co-authored-by: Blaž Kristan <blaz@kristan-sp.si>
* add 9 further alexa devices for calling presets 1-9
* use preset names from WLED for Alexa preset device names instead of hardcoded names
* update readme and version
* call alexaInit() at end of savePreset() to keep Alexa in sync with the preset IDs and names
* This reverts commit f8db06c7c5.
* change order to configured Alexa WLED name first, preset names afterwards
* fix status of devices when shown within Alexa, i.e. switching one preset on switches others off (except for alexaInvocationName)
* re-add getPresetName() after merge with master
* restore original readme for pull request
* restore original platformio.ini for pull request
* Logic simplification
* Pass string by reference
* Added number of presets check
* fix alexaInit() in case of alexaNumPresets==0
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
* Create usermod_word_clock_matrix.h
Tried using the old usermod on the new build, found out a lot has changed since then. My best attempt to update it. Still needs some help, but it is working. I would like to preconfigure some of the default settings. I am also having an issue with Error 12: Preset Not Found
* Update readme.md
* BH1750 upgrades
Moved the definitions into the main usermods_list.cpp instead of having a section to copy across.
Added Home Assistant Discovery topic for light sensor. This is toggleable from the usermod menu.
* Configure pin, other enhancements, readme
Implemented pin manager
Made pins configurable at runtime
Improved info screen outputs
Added F() around strings
Updated readme
* Resolve conflict
* Merge branch 'main'
* Missing comma
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* Add ESP32_DATA_IDLE_HIGH to enable data pin to go HIGH when relay is off
* forgot to remove Serial.print for ESP32_DATA_IDLE_HIGH
* forgot another ifdef preventing compilation on non-esp32 boards
* Extra checks that the bus is actually an RMT bus
Could still blow on new ESP32 variants, but now in a mergable state.
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* Starting on Ping Pong Clock Usermod, still having to check the led indices and test the stuff out of it
* Adding some attributes to be configured, Added platformio_override
* Fixed LED Numbering, Changed Color to RGB to Work with Settings
* Removing LED Positions from Config
* Some documenting
* Removed example comments to make ping pong clock mod more readable
Co-authored-by: Schmailzl, Sebastian <sebastian.schmailzl@wk-it.com>
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* implement analog clock as a usermod
* fix some bugs, use toki for time measurement, implement fading seconds
* added timezone handling to analog clock
* fixed looping second pointer, lower refresh rate
* removed mqtt debug code
* implement seconds effect choice
* adapt to 0_14 branch
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
* Release of WLED v0.13.3
* Fixed a type in the file name (#2781)
* Fixed the dependency (#2782)
* Usermod Wordclock update to use an alternatve wiring pattern (#2757)
* Update
* update readme file
* readme update
* Update readme.md
* Update readme.md
* Update readme.md
* Update readme.md
* Update platformio.ini
* Add number of UDP retries
Add a configurable number of retries to the UDP WLED sync function.
* Add migration from old eeprom settings
* Revert some accidental carry overs
* Correct issues found in pull request
Change default number of retries
Fix migration from old settings
* Make the minimum number of retries 0
* Import notify twice setting
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
Co-authored-by: Soren Singh Dary <67230851+sorensd@users.noreply.github.com>
Co-authored-by: Patrick <40436536+paeppi88@users.noreply.github.com>
it's possible that volume samples become negative. In this scenario, our simple noise gate does stupid things, and it looks like "effects temporarily lost the sound".
This fix improves the situation, and makes sure that volume samples are always >= 0.
This fixes a "division by zero" in WLED_DEBUG code.
LittleFS init seems to take some time, so we can arrive at "Loops/sec" with 0 loops executed --> crash.
16kHz might be a good compromise on small MCU's:
- GEQ will show frequencies up to ~6Khz
- FFT process may use up to 32millis (-> 100% CPU load). Try to stay below <60% so FreeRTOS can schedule all tasks properly.
- more CPU time is left for other WLED, so it maintains LED FPS and stays responsive on web UI.
Only run FFT when the result will be used.
Please note that this also means that `FFTTime` shown in Info is only meaningful when there is sound input and not silence.
--> To get exact FFT times, the optimization can be disabled by compiling with `-D SR_DEBUG`
I2S microphones were not working any more in with the newest framework - only delivers silence.
Ther reason is stupid bug in espressif I2S "compatibility" driver: RIGHT and LEFT channel are swapped, so when only asking for LEFT, we get silence from RIGHT.
Workaround: simply change LEFT to RIGHT, until the problem is fixed in ESP-IDF --> Fix tested on "classic ESP32", but still need to check behavior on -S3.
Code compiles also on -S3, -S2, and -C3.
smaller changes:
- a few changes to use new APIs (MCLK, rouing and sample resolution)
- a few additional debug messages
- put correct value into _pinConfig.mck_io_num
- adding USB-OTG to reserved GPIO
- no read-only GPI
- if PSRAM found, add pins for "octal" PSRAM to unusable list (octal PSRAM seems to common on S3)
- ESP32: 37 and 38 are read-only
Fixed no new 2D segments creatable in UI
Fixed brightness not applied if `"on":true` present in the same JSON api call
Fixed CJK text upside down in namelabel (rotate to nicer direction only if no CJK characters)
Gamma correction color enabled by default
Encapsulated all parts with #ifdef that will not compile on newer ESP32 variants.
It's still a long way to go before we have a working version on -S3 and -C3, bus this should help to get us started.
From MoonModule/WLED repo.
- the connected() method only get called once a Wifi STA connection is established. UDP Sound Sync should also work when sender is in AP Mode.
- added a few comments that should help to understand the code structure.
- Info Page: add a small horizontal line below usermod specific part. Improves readability.
- updated 2D mapping mode of some 1D soundreactive effects
- alllow some effects to fade slowly, even slower that possible with SEGMENT.fade_out(). Looks nice.
not sure why - most effects only fade when using SEGMENT.fade_out(), while some need SEGMENT.fadeToBlackBy().
- Un-F() most segment JSON keys, decreases JSON doc usage by 47 B (increases static RAM usage by 32 B),
makes `extractModeDefaults` work without strstr_P
- Removed String from serializeModeData and serializeModeNames
- Set 0.14 version name "Hoshi"
- save 1K of RAM by optimizing out
fftBin[].
- moved several copies of the peak reset code into a single function
- moved peak detection out of getSample().
- call peak detection function as last step of FFTcode. More optimal, and we can be sure that fresh FFT result are available.
Peak detection/reset are now called from both tasks, so I had to move some peak-related vars out of AudioReactive class and make them global (static).
also when user wants less than 16 bands.
Previously when users selected fewer bands (like 4 instead of 16), only the lowest freq channels were displayed.
- put variables with same context next to each other.
- removed a few vars that are not needed any more.
- replaced "16" by a more descriptive constant
... found that stupid commit messages get more attention ;-)
- use 22050 Hz for sampling, as it is a standard frequency. I think this is the best choise.
- redesigned the GEQ channels (fftResult[]) for 22Khz, based on channels found on old HiFi equalizer equipment. 1Kzh is now at the center; Bass/Trebble channels are using 1/4 on left/right side respectively - similar to real equalizers. Looks nice :-)
- adjusted effects that use FFT_MajorPeak so that the maximum frequency is supported.
- new feature: "Input Level" (info page) can be used as global "GEQ gain" - only when AGC is ON (was already possible when AGC=off)
- some parameter tweaking in FFT function
- hidden feature: FFT decay is slower when setting a high "dynamics Limiter Fall time" (steps: <1000, <2000, <3000, >3000)
- FFT_MajorPeak default 1.0f (as log(0.0) is invalid)
- FX.cppp: ensure that fftResult[] is always used inside array bounds
- removed broken FFTResult "squelch" feature. It was completely broken, and caused flashes in GEQ.
- added Frequency scaling options: linear and logarithmic
- fixed a few numerical accidents in FX.cpp (bouncing_balls, ripplepeak, freqmap, gravfreq, waterfall)
- On/Off controls the complete feature
- Rise Time and Fall Time are the minimum times (in milliseconds) for "volume" to go from 0% to 80% and back.
- when "On" we also use some filtering to smooth FFTResults[]. Rise and Fall Times do not affect Frequency reactive effects otherwise.
- fade_out() appears to finally do something meaning. Old fade_out values were too high. Adjusted so effects in 1D look similar "classic" SR WLED
- frequency reactive effects: max FFT frequency of 5120 Hz is hard-coded in most effects. Updated ranges to 10240 Hz
* Header checking for sound sync receiver: removed wrong "!"
* make sure all member vars have initial values
* some robustness improvements in case of receiving bad UDP data.
improved ADCsample processing, including replacement of "rogue" samples from other channels (this happens at least once in 5 seconds !!).
It compiles, don't ship it yet - needs more testing.
- smoothing FFTResult (don't have a matrix to test)
- UDP sound sync improvements
- some bugfixes from SR WLED
- button.cpp: avoid starvation: strip.isUpdating() can be true for a long time.
work in progress - still needs testing!!
-new methods: getType(), isInitailized(), postProcessSample()
- allow users to compile for RIGHT audio channel (-D I2S_USE_RIGHT_CHANNEL)
- better handling in case audio input driver failed to initialize
- removed some unneeded code and unneeded parameters
UDP audio sync: introduced new header version, because the new struct (without myvals[]) is not compatible with the previous struct. Also optimized structure size.
UDP audio sync: sender decides is AGC or non-AGC samples are transmitted.
getsamples: move volumeSmth/volumeRaw code out of AGC core function.
- Remove CRGB* leds from utility functions
- GameOfLife: fill_solid for prevLeds to for loop
- Remove if !fftResult
- Funky Plank: toggle src and dst
- Comment drawLine as not used
- Duplicate FadeToBlack, call one FadeToBlackOld
- add addPixelColor overloads
- remove setPixels function
- sPC/gPC move leds check to beginning
- refactor wu_pixel work without leds
- remove leds out of effects and replace by sPC/gPC/aPC/nullptr
- workaround %=
- refactor game of life (but need to check patterns / history, see SR)
- refactor fill_circle to work without leds
- remove leds out of SEGMENT.data (remove if no other use of data)
- use strip.leds
- refactor XY to make segment relative to the whole matrix
- use RGBW32
- in case of 1D also use XY in leds[]: XY(i%width, i/width)]
- add ps_malloc
- leds array from uint32_t to CRGB for fastled compatibility
- reading and writing leds from strip to segment sPC/gPC so it has logical instead of physical indexes so it can be used in effects
- change mode_2DBlackHole as showcase how it can both work with leds or with sPC/gPC
Implemented PinManager and rerun setup of usermod after updating pins/
Registered in const.h and pin_manager.h I tried to follow the existing formatting/numbering in these files.
Wrapped any strings I could in F()
Added public variables to the BME280 usermod based on those in the Temperature usermod. Only complication is that this usermod utilises different function calls depending on whether user defines celsius or not. I have handled this for the temperature, but the Dew Point and Heat Index are relative to the temperature.
I've also addressed some areas where I'd previously assumed Celsius for reporting purposes as my test case is using Farenheit.
I added a Usermod interface for key settings. I used a PinArray for the SDA/SCL pins, but you can't name these individually.
I have also made a display to show the temperature/humidity values in the web interface's Info screen.
I had to change the definition of those items in order to allow these new functions to work. I have not noticed any negative side effects to this change.
At the moment, I've not figured out how to make Celsius/Farenheit toggleable due to the way the #define setup works.
Finally, I have added a routine to publish MQTT Discovery Topics for Home Assistant (toggleable in the Usermod screen).
I've been testing this on the only suitable device I have for a few months and haven't noticed any problems.
gain =1 does not make much senses, at it means "0.0825"; 40 internally translates to "1". 60 seems to be a good start.
- Don't use ADC analog microphone as default, to avoid well-known conflicts with other stuff hooked up onto ADC1,
- re-enabled a forgotten delay (overlooked that in my last commit)
- same fix as in SR-WLED upstream
- if strip.isupdating() is true for more than 12ms, run audio filter loop regardlessly. The userloop is very fast, so I'm expect no bad side-effects from this.
- add to segment: mapping 1D2D and Sound Simulation (WIP!)
- Add sound simulation WeWillRockYou
- All audio effects use segment soundSim
- Redefine SEGLEN: strip.getMappingLength (depending on mapping12)
- make setPixelColor aware of mapping12
- change arduinoFFT to float (custom)
- update audioreactive to use float
- update effects to use float
- info slider (usermod)
- hide Peek in 2D
- minor bugfixes
Added:
- introduced addEffect() and setupEffectData()
- conditional compile for audio effects
- introduced getModeData() and getModeDataSrc() instead of public var
- changed _modeData[] to private non-static
Fixes:
- DMTYPE use
- add reboot info to DMTYPE
- transpose & reverse with mirroring
Use the ESP watchdog to detect hanging ESP and reset the firmware.
Can be disable by defining WLED_WATCHDOG_TIMOUT 0
Default timeout is 3 seconds on ESP32 and 8 seconds on ESP2688
* added SparkFunDMX library dependencies
* changed variable names to avoid conflicts with SparkFunDMX library
* board version checks
* minor changes to DMX
* fix brightness when no shutter DMX channel is set
* fix compile issue on newer ESP32 variants
* Update wizlights.h
adds new features and options for wizlights usermod
* Update wizlights.h
Change how IPs are numbered.
Non-programmers incorrectly start counting at 1
* Update wizlights.h
updated default cold white enhanced white setting to a lower value.
* Update wizlights.h
added logic for connection check before UDP sending.
Seems more important for ESP32
* Update readme.md
handleImprovPacket() unconditionally gobbles serial data which a problem
if we want another feature to consume it. This patch uses the same guard
as the existing call in `handleSerial()`.
Co-authored-by: Thomas Fubar <FUB4R@users.noreply.github.com>
* added first version (work in progress)
* added some sensors to publish
* typo
* added dependency
* mqtt si7021_* names + don't retain
* timer to 60 s
* some changes to HA auto discovery
* added config entries (no function yet)
* renaming
* made configs work
* added getId()
* refactoring + wrong mqtt topics fixed
* retain HA auto discovery
* do not spam serial console on each sensor update
* added readme
* add update interval info
Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
* - implement V2 Usermod to handle wordclocks with 11x10 pixels and 4 additional dots for the minutes
* - fix wording issue for "six"
-
* - add some more comments
* - fix issue with "zwölf"
* Added option to set the name of the module at runtime.
* added example how to set number of LEDs at runtime
* Example to enable/set IR remote type at runtime
* Clarification on how to use platformio_overrides
* Example for setting abl milliamp limit at runtime
* Corrected example set LED count
* Dynamic hiding of unused color controls in UI
(e.g. a PWM white bus with no auto white mode will not display the color wheel or palette list)
* Store segment capabilities
Don't use palettes if no RGB supported
Make it safe to update busses using `/json/cfg`
mainseg is not highlighted by default, but can be enabled by CSS only
Simplify some CSS (new segment box, segment brightness slider)
Started labeling CSS classes
* IR rewrite.
- added CCT (WW/CW) support
- support for applying change to main segment or all selected segments
* Remove extra setValuesFromFirstSelectedSeg()
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* Added: CSS hover effect on buttons within modal dialogs, e.g. Info,
Nodes
* Update index.css
Co-authored-by: Tom D'Roza <Tom.D'Roza>
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
* define as float (not double)
* Avoid #define of 1 or 2 char symbols
Having this file define 'A' and 'C' pollutes
the global namespace, and causes conflicts
with other libraries that also pollute the
global namespace with short #defines.
It's easier to fix this header.
* unused variable warning
* Binary Websockets for Peek
* No IRAM_ATTR here
* Use builtin LittleFS for all ESP32 builds
* Attempt LittleFS compilation fix
* Use tasmota zip for all ESP32 builds
* Revert to Arduino Core 1 for the time being
- optimized setPixelSegment()
- moved extractModeName() to util.cpp
- optimized extractModeName()
- removed SR extensions from /json/effects endpoint (compatibility estabished)
Adds serial functionality
Can now change baud rate during runtime to be faster
Retrieve LED strip data as JSON blob
Retrieve LED strip data as BYTES (fast!)
* Overridable color order
- Use `ColorOrderMap` to hold optional color order overrides for ranges
of LEDs.
- Serialization of config to/from filesystem is complete.
- Back-end configuration is complete.
- TODO: front-end changes to the LED settings page.
* Add Color order override settings
- Adds color order override section to settings page.
* PR Feedback
- Limit max number of color order overrides to 5 on ESP8266
- Only append color overrides if they were provided in the POST of LED
settings.
* Use arduino-esp32 2.0.2 for ESP32-S2
LittleFS is merged into it.
* Fix filesystem error for ESP32-S2
Use platform of tasmota until upstream released it and
use board_build.flash_mode = qio
* Fix empty disk usage
* Add esp32s2_saola to default_envs
* Remove lorol LITTLEFS for esp32dev, too
* Revert "Remove lorol LITTLEFS for esp32dev, too"
This reverts commit 3586d5eef7.
- Use `ColorOrderMap` to hold optional color order overrides for ranges
of LEDs.
- Serialization of config to/from filesystem is complete.
- Back-end configuration is complete.
- TODO: front-end changes to the LED settings page.
* Date controlled timed presets.
* C/P fix for sunset.
* Fixed % escape character
* Date range support
* Date logic fix
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
Line 526: "now - lastRedraw" equates to a negative number and forces the screen into sleep mode
Line 646, 660: if the array size isn't at least the length of the longest name of an effect or palette, then it will not fully print. "Fireworks Starburst" is the longest one at 19 characters. this it kinda a bandaid fix because a longer name may come in the future.
* UM QuinLED-An-Penta: First version
* UM QuinLED-An-Penta: Made OLED seconds a setting; small improvements
* UM QuinLED-An-Penta: Fixed unique ID
* Merge branch 'master' of https://github.com/Aircoookie/WLED
* UM QuinLED-An-Penta: Fixed config loading
* UM QuinLED-An-Penta: Replaced ledcRead() with calculating the percentage
* UM QuinLED-An-Penta: Fixed temp sensor readings
* UM QuinLED-An-Penta: Removing OLED bus clk setting
* UM QuinLED-An-Penta: ETH support, lots of OLED improvements
* UM quinled-an-penta: v1r1 adjustments
color_blend() function only generates 256 colors from the palette before repeating. Improved the function to use either 256 max or the segment length if shorter.
settings.js for pasting data into HTML.
Reduced simple & classic flash footprint.
Split iro.js and rangetouch.js into separate requests (instead of embedding)
Fixed ESP32 crash on Colortwinkles brightness change
Fixed setting picker to black resetting hue and saturation
Fixed auto white mode not saved to config
* Multirelay button support.
Added button hook for usermods.
* Added MultiRelay relay states to JSON state object
* Move button timings to constants
No delay waiting for double press on button 0 if no macro set
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
* UM QuinLED-An-Penta: First version
* UM QuinLED-An-Penta: Made OLED seconds a setting; small improvements
* UM QuinLED-An-Penta: Fixed unique ID
* Merge branch 'master' of https://github.com/Aircoookie/WLED
* UM QuinLED-An-Penta: Fixed config loading
* UM QuinLED-An-Penta: Replaced ledcRead() with calculating the percentage
* UM QuinLED-An-Penta: Fixed temp sensor readings
* UM QuinLED-An-Penta: Removing OLED bus clk setting
* UM QuinLED-An-Penta: ETH support, lots of OLED improvements
* Add strip off refresh option in LED settings.
New strip initialization logic.
Minor code clen-up.
* Dev code removal.
* Missing ethernet include
* Renamed mainseg to selseg
* Fix for preset cycling bounds.
* "Preset 0" bugfix.
* Auto segments only if segments were not modified
Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
- added parsing of POST fields to use proper type
- updated readFromConfig() to reflect parsing
- added a possibility to use nested object in UM settings
- internal changes and fixes
commit 7893cb9ebc66faa39d430148e6dd66894cd2fc90
Merge: c4086b94e139d7
Author: Blaž Kristan <blaz@kristan-sp.si>
Date: Fri May 21 12:57:43 2021 +0200
Merge branch 'master' of https://github.com/scottrbailey/WLED into scottrbailey-master
commit 4e139d7c0a
Author: Artacus <40248830+scottrbailey@users.noreply.github.com>
Date: Tue May 18 12:57:20 2021 -0700
Update ir.cpp
Handle both 24-key and 24-key old in decodeIR switch statement
commit 9a405d374b
Author: Artacus <40248830+scottrbailey@users.noreply.github.com>
Date: Tue May 18 11:05:42 2021 -0700
Update readme.md
commit 94af6d0561
Merge: 1ed687abfb27c4
Author: Artacus <40248830+scottrbailey@users.noreply.github.com>
Date: Sun May 16 22:00:15 2021 -0700
Merge branch 'Aircoookie:master' into master
commit 1ed687a51a
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Sun May 2 21:27:33 2021 -0700
remove colorUpdated notifier that was pasted in accidentally
commit 845dcabe0c
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Sat May 1 12:53:34 2021 -0700
Handle setting palette when effect is still on default solid and will not display it
commit 90e8ae1457
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Sat May 1 02:07:47 2021 -0700
refactor decodeIRJson to change how ir.json is loaded add support for calling several c functions
commit e4f9fa3117
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Thu Apr 29 23:33:01 2021 -0700
comment out printing API commands in IR handling
commit 26247b247e
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Thu Apr 29 23:31:30 2021 -0700
removed code that forced IR codes in a certain range to be decoded by decodeIR24. Generate default ir.json files for currently supported remotes.
commit 5acecda6a0
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Thu Apr 29 11:25:24 2021 -0700
handle JSON API commands also
commit 754e3e092a
Author: Scott Bailey <scottrbailey@gmail.com>
Date: Wed Apr 28 22:53:27 2021 -0700
add decodeIRJson and JSON remote option
Increased max RAM FX usage on ESP32 to 20k.
Added relay On handling on realtime data if Off (@JDTSmith).
Added UI refreshing via websockets (@korkbaum).
Detailed build workflow, timeouts, and troubleshooting for making code changes in agent mode. Always reference these instructions first when running builds or validating changes.
| `npm run build` | ~3 s | 30 s | Web UI → `wled00/html_*.h``wled00/js_*.h` headers |
| `npm test` | ~40 s | 2 min | Validates build system |
| `npm run dev` | continuous | — | Watch mode, auto-rebuilds on changes |
| `pio run -e <env>` | 15–20 min | 30 min | First build downloads toolchains; subsequent builds are faster |
**NEVER cancel long-running builds.** PlatformIO downloads and compilation require patience.
## Development Workflow
### Code Style Summary
- **C++** files in `wled00/` and `usermods/`: 2-space indentation (no tabs), camelCase functions/variables, PascalCase classes, UPPER_CASE macros. No C++ exceptions — use return codes and debug macros.
- **Web UI** files in `wled00/data`: indent HTML and JavaScript with tabs, CSS with tabs.
- **CI/CD workflows** in `.github/workflows`: 2-space indentation, descriptive `name:` on every workflow/job/step. Third-party actions must be pinned to a specific version tag — branch pins such as `@main` or `@master` are not allowed. SHA pinning recommended.
### Web UI Changes
1. Edit files in `wled00/data/`
2. Run `npm run build` to regenerate `wled00/html_*.h``wled00/js_*.h` headers
3. Test with local HTTP server (see Manual Testing below)
4. Run `npm test` to validate
### Firmware Changes
1. Edit files in `wled00/` (but **never**`html_*.h` and `js_*.h` files)
WLED is a fast and feature-rich implementation of an ESP32 and ESP8266 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs and SPI-based chipsets. The project consists of C++ firmware for microcontrollers and a modern web interface.
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
> **Note for AI review tools**: sections enclosed in
> contributor reference material. Do **not** use that content as actionable review
> criteria — treat it as background context only.
## Setup
- Node.js 20+ (see `.nvmrc`)
- Install dependencies: `npm ci`
- PlatformIO (required only for firmware compilation): `pip install -r requirements.txt`
## Build and Test
<!-- HUMAN_ONLY_START -->
| Command | Purpose | Typical Time |
|---|---|---|
| `npm run build` | Build web UI → generates `wled00/html_*.h` and `wled00/js_*.h` headers | ~3 s |
| `npm test` | Run test suite | ~40 s |
| `npm run dev` | Watch mode — auto-rebuilds web UI on file changes | — |
| `pio run -e <env>` | Build firmware for a hardware target | 15–20 min |
<!-- HUMAN_ONLY_END -->
- **Always run `npm run build` before any `pio run`** (and run `npm ci` first on fresh clones or when lockfile/dependencies change).
- The web UI build generates required `wled00/html_*.h` and `wled00/js_*.h` headers for firmware compilation.
- **Build firmware to validate code changes**: `pio run -e esp32dev` — must succeed, never skip this step.
- Common firmware environments: `nodemcuv2`, `esp32dev`, `esp8266_2m`, `esp32c3dev`, `esp32s3dev_8MB_opi`
For detailed build timeouts, development workflows, troubleshooting, and validation steps, see [agent-build.instructions.md](agent-build.instructions.md).
### Usermod Guidelines
- New custom effects can be added into the user_fx usermod. Read the [user_fx documentation](https://github.com/wled/WLED/blob/main/usermods/user_fx/README.md) for guidance.
- Other usermods may be based on the [EXAMPLE usermod](https://github.com/wled/WLED/tree/main/usermods/EXAMPLE). Never edit the example, always create a copy!
- New usermod IDs can be added into [wled00/const.h](https://github.com/wled/WLED/blob/main/wled00/const.h#L160).
- To activate a usermod, a custom build configuration should be used. Add the usermod name to `custom_usermods`.
## Project Structure Overview
### Project Branch / Release Structure
<!-- HUMAN_ONLY_START -->
```text
main # Main development trunk (daily/nightly) 17.0.0-dev
├── V5 # special branch: code rework for esp-idf 5.5.x (unstable)
├── V5-C6 # special branch: integration of new MCU types: esp32-c5, esp32-c6, esp32-p4 (unstable)
16_x # current beta, preparations for next release 16.0.0
0_15_x # maintenance (bugfixes only) for current release 0.15.4
(tag) v0.14.4 # previous version 0.14.4 (no maintenance)
(tag) v0.13.3 # old version 0.13.3 (no maintenance)
(tag) v0. ... . ... # historical versions 0.12.x and before
```
<!-- HUMAN_ONLY_END -->
- ``main``: development trunk (daily/nightly)
- ``V5`` and ``V5-C6``: code rework for esp-idf 5.5.x (unstable) - branched from ``main``.
- ``0_15_x``: bugfixing / maintenance for release 0.15.x
├── html_*.h # Auto-generated embedded web files (DO NOT EDIT, DO NOT COMMIT)
├── src/ # Modules used by the WLED core (C++)
│ ├── fonts/ # Font libraries for scrolling text effect
└ └── dependencies/ # Utility functions - some of them have their own licensing terms
lib/ # Project specific custom libraries. PlatformIO will compile them to separate static libraries and link them
platformio.ini # Hardware build configuration
platformio_override.sample.ini # examples for custom build configurations - entries must be copied into platformio_override.ini to use them.
# platformio_override.ini is _not_ stored in the WLED repository!
usermods/ # User-contributed addons to the WLED core, maintained by individual contributors (C++, with individual library.json)
package.json # Node.js dependencies and scripts, release identification
pio-scripts/ # Build tools (PlatformIO)
tools/ # Build tools (Node.js), partition files, and generic utilities
├── cdata.js # Web UI build script
└── cdata-test.js # Test suite
docs/ # Contributor docs, coding guidelines
.github/workflows/ # CI/CD pipelines
```
<!-- HUMAN_ONLY_END -->
## General Guidelines
- **Repository language is English.** Suggest translations for non-English content.
- **Use VS Code with PlatformIO extension** for best development experience.
- **Never edit or commit** `wled00/html_*.h` and `wled00/js_*.h` — auto-generated from `wled00/data/`.
- If updating Web UI files in `wled00/data/`, **make use of common functions in `wled00/data/common.js` whenever possible**.
- **When unsure, say so.** Gather more information rather than guessing.
- **Acknowledge good patterns** when you see them. Positive feedback always helps.
- **Provide references** when making analyses or recommendations. Base them on the correct branch or PR.
- **Highlight user-visible breaking changes and ripple effects**. Ask for confirmation that these were introduced intentionally.
- **Unused / dead code must be justified or removed**. This helps to keep the codebase clean, maintainable and readable.
- **Verify feature-flag names.** Every `WLED_ENABLE_*` / `WLED_DISABLE_*` flag must exactly match one of the names below — misspellings are silently ignored by the preprocessor (e.g. `WLED_IR_DISABLE` instead of `WLED_DISABLE_INFRARED`), causing silent build variations. Flag unrecognised names as likely typos and suggest the correct spelling.
- **C++ formatting available**: `clang-format` is installed but not in CI
- No automated linting is configured — match existing code style in files you edit.
Refer to `docs/cpp.instructions.md` and `docs/web.instructions.md` for language-specific conventions, and `docs/cicd.instructions.md` for GitHub Actions workflows.
### Attribution for AI-generated code
Using AI-generated code can hide the source of the inspiration / knowledge / sources it used.
- Document attribution of inspiration / knowledge / sources used in the code, e.g. link to GitHub repositories or other websites describing the principles / algorithms used.
- When a larger block of code is generated by an AI tool, embed it into `// AI: below section was generated by an AI` ... `// AI: end` comments (see C++ guidelines).
- Every non-trivial AI-generated function should have a brief comment describing what it does. Explain parameters when their names alone are not self-explanatory.
- AI-generated code must be well documented with meaningful comments that explain intent, assumptions, and non-obvious logic. Do not rephrase source code; explain concepts and reasoning.
### Pull Request Expectations
- **No force-push on open PRs.** Once a pull request is open and being reviewed, do not force-push (`git push --force`) to the branch. Force-pushing rewrites history that reviewers may have already commented on, making it impossible to track incremental changes. Use regular commits or `git merge` to incorporate feedback; the branch will be squash-merged when it is accepted.
- **Modifications to ``platformio.ini`` MUST be approved explicitly** by a *maintainer* or *WLED organisation Member*. Modifications to the global build environment may break github action builds. Always flag them.
- **Document your changes in the PR.** Every pull request should include a clear description of *what* changed and *why*. If the change affects user-visible behavior, describe the expected impact. Link to related issues where applicable. Provide screenshots to showcase new features.
### Supporting Reviews and Discussions
- **For "is it worth doing?" debates** about proposed reliability, safety, or data-integrity mechanisms (CRC checks, backups, power-loss protection): suggest a software **FMEA** (Failure Mode and Effects Analysis).
Clarify the main feared events, enumerate failure modes, assess each mitigation's effectiveness per failure mode, note common-cause failures, and rate credibility for the typical WLED use case.
WLED is a community-driven project, and every contribution matters! We appreciate your time and effort.
Our maintainers are here for two things: **helping you** improve your code, and **keeping WLED** lean, efficient, and maintainable.
We'll work with you to refine your contribution, but we'll also push back if something might create technical debt or add features without clear value. Don't take it personally - we're just protecting WLED's architecture while helping your contribution succeed!
## Getting Started
Here are a few suggestions to make it easier for you to contribute:
### Important Developer Infos
* [Project Structure, Files and Directories](.github/copilot-instructions.md#project-structure-overview) (in our AI instructions)
* [Instructions for creating usermods](.github/copilot-instructions.md#usermod-guidelines) (in our AI instructions)
* KB: [Compiling WLED](https://kno.wled.ge/advanced/compiling-wled/) - slightly outdated but still helpful :-)
* Arduino IDE is not supported any more. Use VSCode with the PlatformIO extension.
* [Compiling in VSCode/Platformio](https://github.com/wled/WLED-Docs/issues/161) - modern way without command line or platformio.ini changes.
* If you add a new feature, consider making a PR to [``wled-docs``](https://github.com/wled/WLED-Docs) for updating our official documentation.
### PR from a branch in your own fork
Start your pull request (PR) in a branch of your own fork. Don't make a PR directly from your main branch.
This lets you update your PR if needed, while you can work on other tasks in 'main' or in other branches.
> [!TIP]
> **The easiest way to start your first PR**
> When viewing a file in `wled/WLED`, click on the "pen" icon and start making changes.
> When you choose to 'Commit changes', GitHub will automatically create a PR from your fork.
>
> <img width="295" height="134" alt="image: fork and edit" src="https://github.com/user-attachments/assets/f0dc7567-edcb-4409-a530-cd621ae9661f" />
### Target branch for pull requests
Please make all PRs against the `main` branch.
### Describing your PR
Please add a description of your proposed code changes.
A PR with no description or just a few words might not get accepted, simply because very basic information is missing.
No need to write an essay!
A good description helps us to review and understand your proposed changes. For example, you could say a few words about
* What you try to achieve (new feature, fixing a bug, refactoring, security enhancements, etc.)
* How your code works (short technical summary - focus on important aspects that might not be obvious when reading the code)
* Testing you performed, known limitations, anything you couldn't quite solve.
* Let us know if you'd like guidance from a maintainer (WLED is a big project 😉)
### Testing Your Changes
Before submitting:
- ✅ Does it compile?
- ✅ Does your feature/fix actually work?
- ✅ Did you break anything else?
- ✅ Tested on actual hardware if possible?
Mention your testing in the PR description (e.g., "Tested on ESP32 + WS2812B").
## During Review
We're all volunteers, so reviews can take some time (longer during busy times).
Don't worry - we haven't forgotten you! Feel free to ping after a week if there's no activity.
### Updating your code
While the PR is open, you can keep updating your branch - just push more commits! GitHub will automatically update your PR.
You don't need to squash commits or clean up history - we'll handle that when merging.
> [!CAUTION]
> Do not use "force-push" while your PR is open!
> It has many subtle and unexpected consequences on our GitHub repository.
> For example, we regularly lose review comments when the PR author force-pushes code changes. Our review bot (coderabbit) may become unable to properly track changes, it gets confused or stops responding to questions.
> So, pretty please, do not force-push.
> [!TIP]
> Use [cherry-picking](https://docs.github.com/en/desktop/managing-commits/cherry-picking-a-commit-in-github-desktop) to copy commits from one branch to another.
### Responding to Reviews
When we ask for changes:
- **Add new commits** - please don't amend or force-push
- **Reply in the PR** - let us know when you've addressed comments
- **Ask questions** - if something's unclear, just ask!
- **Be patient** - we're all volunteers here 😊
You can reference feedback in commit messages:
> ```text
> Fix naming per @Aircoookie's suggestion
> ```
### Dealing with Merge Conflicts
Got conflicts with `main`? No worries - here's how to fix them:
**Using GitHub Desktop** (easier for beginners):
1. Click **Fetch origin**, then **Pull origin**
2. If conflicts exist, GitHub Desktop will warn you - click **View conflicts**
3. Open the conflicted files in your editor (VS Code, etc.)
4. Remove the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) and keep the correct code
5. Save the files
6. Back in GitHub Desktop, commit the merge (it'll suggest a message)
7. Click **Push origin**
**Using command line**:
```bash
git fetch origin
git merge origin/main
# Fix conflicts in your editor
git add .
git commit
git push
```
Either way works fine - pick what you're comfortable with! Merging is simpler than rebasing and keeps everything connected.
#### When you MUST rebase (really rare!)
Sometimes you might hit merge conflicts with `main` that are harder to solve. Here's what to try:
1. **Merge instead of rebase** (safest option):
```bash
git fetch origin
git merge origin/main
git push
```
Keeps review comments attached and CI results visible!
2. **Use cherry-picking** to copy commits between branches without rewriting history - [here's how](https://docs.github.com/en/desktop/managing-commits/cherry-picking-a-commit-in-github-desktop).
3. **If all else fails, use `--force-with-lease`** (not plain `--force`):
```bash
git rebase origin/main
git push --force-with-lease
```
Then **leave a comment** explaining why you had to force-push, and be ready to re-address some feedback.
### Additional Resources
Want to know more? Check out:
- 📚 [GitHub Desktop documentation](https://docs.github.com/en/desktop) - if you prefer GUI tools
- 🎓 [How to properly submit a PR](https://github.com/wled-dev/WLED/wiki/How-to-properly-submit-a-PR) - detailed tips and tricks
## After Approval
Once approved, a maintainer will merge your PR (possibly squashing commits).
Your contribution will be in the next WLED release - thank you! 🎉
## Coding Guidelines
### Source Code from an AI agent or bot
> [!IMPORTANT]
> It's OK if you took help from an AI for writing your source code.
>
> AI tools can be very helpful, but as the contributor, **you're responsible for the code**.
* Make sure you really understand the AI-generated code, don't just accept it because it "seems to work".
* Don't let the AI change existing code without double-checking by you as the contributor. Often, the result will not be complete. For example, previous source code comments may be lost.
* Remember that AI is still "Often-Wrong" ;-)
* If you don't feel confident using English, you can use AI for translating code comments and descriptions into English. AI bots are very good at understanding language. However, always check if the results are correct. The translation might still have wrong technical terms, or errors in some details.
#### Best Practice with AI
AI tools are powerful but "often wrong" - your judgment is essential! 😊
- ✅ **Understand the code** - As the person contributing to WLED, make sure you understand exactly what the AI-generated source code does
- ✅ **Review carefully** - AI can lose comments, introduce bugs, or make unnecessary changes
- ✅ **Be transparent** - Add comments `// AI: below section was generated by an AI` ... `// AI: end` around larger chunks
- ✅ **Use AI for translation** - AI is great for translating comments to English (but verify technical terms!)
### Code style
Don't stress too much about style! When in doubt, just match the style in the files you're editing. 😊
Our review bot (coderabbit) has learned lots of detailed guides and hints - it will suggest them automatically when you submit a PR for review.
If you are curious, these are the detailed guides:
Below are the main rules used in the WLED repository:
#### Indentation
We use tabs for indentation in Web files (.html/.css/.js) and spaces (2 per indentation level) for all other files.
You are all set if you have enabled `Editor: Detect Indentation` in VS Code.
#### Blocks
Whether the opening bracket of e.g. an `if` block is in the same line as the condition or in a separate line is up to your discretion. If there is only one statement, leaving out block brackets is acceptable.
Good:
```cpp
if (a == b) {
doStuff(a);
}
```
```cpp
if (a == b) doStuff(a);
```
Also acceptable (though the first style is usually easier to read):
```cpp
if (a == b)
{
doStuff(a);
}
```
There should always be a space between a keyword and its condition and between the condition and brace.
Within the condition, no space should be between the parenthesis and variables.
Spaces between variables and operators are up to the authors discretion.
There should be no space between function names and their argument parenthesis.
Good:
```cpp
if (a == b) {
doStuff(a);
}
```
Not good:
```cpp
if( a==b ){
doStuff ( a);
}
```
#### Comments
Comments should have a space between the delimiting characters (e.g. `//`) and the comment text.
We're gradually adopting this style - don't worry if you see older code without spaces!
Good:
```cpp
// This is a short inline comment.
/*
* This is a longer comment
* wrapping over multiple lines,
* used in WLED for file headers and function explanations
*/
```
```css
/* This is a CSS inline comment */
```
```html
<!-- This is an HTML comment -->
```
There is no hard character limit for a comment within a line,
though as a rule of thumb consider wrapping after 120 characters.
Inline comments are OK if they describe that line only and are not exceedingly wide.
- Include the environment name or a relevant identifier in cache keys when building multiple targets
### Artifacts
- Name artifacts with enough context to be unambiguous (e.g., `firmware-${{ matrix.environment }}`)
- Avoid uploading artifacts that will never be consumed downstream
<!-- HUMAN_ONLY_END -->
---
## Security
Important: Several current workflows still violate parts of the baseline below - migration is in progress.
### Permissions — Least Privilege
Declare explicit `permissions:` blocks. The default token permissions are broad; scope them to the minimum required:
```yaml
permissions:
contents: read # for checkout
```
For jobs that publish releases or write to the repository:
```yaml
permissions:
contents: write # create/update releases
```
A common safe baseline for build-only jobs:
```yaml
permissions:
contents: read
```
### Supply Chain — Action Pinning
**Third-party actions** (anything outside the `actions/` and `github/` namespaces) should be pinned to a specific release tag. Branch pins (`@main`, `@master`) are **not allowed** — they can be updated by the action author at any time without notice:
```yaml
# ✅ Acceptable — specific version tag. SHA pinning recommended for more security, as @v2 is still a mutable tag.
uses: softprops/action-gh-release@v2
# ❌ Not acceptable — mutable branch reference
uses: andelf/nightly-release@main
```
SHA pinning (e.g., `uses: someorg/some-action@abc1234`) is the most secure option for third-party actions; it is recommended when auditing supply-chain risk is a priority. At minimum, always use a specific version tag.
**First-party actions** (`actions/checkout`, `actions/cache`, `actions/upload-artifact`, etc.) pinned to a major version tag (e.g., `@v4`) are acceptable because GitHub maintains and audits these.
When adding a new third-party action:
1. Check that the action's repository is actively maintained
2. Review the action's source before adding it
3. Prefer well-known, widely-used actions over obscure ones
### Credentials and Secrets
- Use `${{ secrets.GITHUB_TOKEN }}` for operations within the same repository — it is automatically scoped and rotated
- Never commit secrets, tokens, or passwords into workflow files or any tracked file
- Never print secrets in `run:` steps, even with `echo` — GitHub masks known secrets but derived values are not automatically masked
- Scope secrets to the narrowest step that needs them using `env:` at the step level, not at the workflow level:
```yaml
# ✅ Scoped to the step that needs it
- name: Create release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
# ❌ Unnecessarily broad
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
- Personal Access Tokens (PATs, stored as repository secrets) should have the minimum required scopes and should be rotated periodically
### Script Injection
`${{ }}` expressions are evaluated before the shell script runs. If an expression comes from untrusted input (PR titles, issue bodies, branch names from forks), it can inject arbitrary shell commands.
**Never** interpolate `github.event.*` values directly into a `run:` step:
```yaml
# ❌ Injection risk — PR title is attacker-controlled
# ✅ Safe — value passed through an environment variable
- env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "$PR_TITLE"
```
This rule applies to any value that originates outside the repository (issue bodies, labels, comments, commit messages from forks).
### Pull Request Workflows
- Workflows triggered by `pull_request` from a fork run with **read-only** token permissions and no access to repository secrets — this is intentional and correct
- Do not use `pull_request_target` unless you fully understand the security implications; it runs in the context of the base branch and *does* have secret access, making it a common attack surface
> contributor reference material. Do **not** use that content as actionable review
> criteria — treat it as background context only.
<!-- HUMAN_ONLY_START -->
<!-- hiding this reference, to avoid cyclic "include" loops -->
See also: [CONTRIBUTING.md](../CONTRIBUTING.md) for general style guidelines that apply to all contributors.
<!-- HUMAN_ONLY_END -->
## Formatting
- Indent with **2 spaces** (no tabs in C++ files)
- Opening braces on the same line is preferred (K&R style). Brace on a separate line (Allman style) is acceptable
- Single-statement `if` bodies may omit braces: `if (a == b) doStuff(a);`
- Space between keyword and parenthesis: `if (...)`, `for (...)`. No space between function name and parenthesis: `doStuff(a)`
- No enforced line-length limit; wrap when a line exceeds your editor width
## Naming
- **camelCase** for functions and variables: `setValuesFromMainSeg()`, `effectCurrent`
- **PascalCase** for classes and structs: `PinManagerClass`, `BusConfig`
- **PascalCase** for enum values: `PinOwner::BusDigital`
- **UPPER_CASE** for macros and constants: `WLED_MAX_USERMODS`, `DEFAULT_CLIENT_SSID`
## General
- Follow the existing style in the file you are editing
- If possible, use `static` for local (C-style) variables and functions (keeps the global namespace clean)
- Avoid unexplained "magic numbers". Prefer named constants (`constexpr`) or C-style `#define` constants for repeated numbers that have the same meaning
- Include `"wled.h"` as the primary project header where needed
<!-- HUMAN_ONLY_START -->
## Header Guards
Most headers use `#ifndef` / `#define` guards. Some newer headers add `#pragma once` before the guard:
```cpp
#ifndef WLED_EXAMPLE_H
#define WLED_EXAMPLE_H
// ...
#endif // WLED_EXAMPLE_H
```
<!-- HUMAN_ONLY_END -->
## Comments
-`//` for inline comments, `/* ... */` for block comments. Always put a space after `//`
- **AI attribution:** When a larger block of code is generated by an AI tool, mark it with an `// AI:` comment so reviewers know to scrutinize it:
```cpp
// AI: below section was generated by an AI
voidcalculateCRC(constuint8_t*data,size_tlen){
...
}
// AI: end
```
Single-line AI-assisted edits do not need the marker — use it when the AI produced a contiguous block that a human did not write line-by-line.
<!-- HUMAN_ONLY_START -->
<!-- hidden from AI for now, as it created too many "please add a description" review findings in my first tests -->
- **Function & feature comments:** Every non-trivial function should have a brief comment above it describing what it does. Include a note about each parameter when the names alone are not self-explanatory:
```cpp
/* *****
* Apply gamma correction to a single color channel.
* @param value raw 8-bit channel value (0–255)
* @param gamma gamma exponent (typically 2.8)
* @return corrected 8-bit value
***** */
uint8_tgammaCorrect(uint8_tvalue,floatgamma);
```
<!-- HUMAN_ONLY_END -->
Short accessor-style functions (getters/setters, one-liners) may skip this if their purpose is obvious from the name.
## Preprocessor & Feature Flags
- Prefer compile-time feature flags (`#ifdef` / `#ifndef`) over runtime checks where possible
- Platform differentiation: `ARDUINO_ARCH_ESP32` vs `ESP8266`
- PSRAM availability: `BOARD_HAS_PSRAM`
## Error Handling
-`DEBUG_PRINTF()` / `DEBUG_PRINTLN()` for developer diagnostics (compiled out unless `-D WLED_DEBUG`)
- Don't rely on C++ exceptions — use return codes (`-1` / `false` for errors) and global flags (e.g. `errorFlag = ERR_LOW_MEM`). Some builds don't support C++ exceptions.
## Strings
- Use `const char*` for temporary/parsed strings
- Avoid `String` (Arduino heap-allocated string) in hot paths; acceptable in config/setup code
- Use `F("string")` for string constants (major RAM win on ESP8266; mostly overload/type compatibility on ESP32)
- Store repeated strings as `static const char[] PROGMEM`
<!-- HUMAN_ONLY_START -->
On **ESP8266** this explicitly stores the string in flash (PROGMEM), saving precious RAM — every byte counts on that platform.
On **ESP32**, `PROGMEM` is a no-op and string literals already reside in flash/rodata, so `F()` yields little RAM benefit but remains harmless (it satisfies `__FlashStringHelper*` overloads that some APIs expect).
<!-- HUMAN_ONLY_END -->
```cpp
DEBUG_PRINTLN(F("WS client connected."));// string stays in flash, not RAM
DEBUG_PRINTF_P(PSTR("initE: Ignoring attempt for invalid ethernetType (%d)\n"),ethernetType);// format string stays in flash
```
## Memory
- **PSRAM-aware allocation**: use `d_malloc()` (prefer DRAM), `p_malloc()` (prefer PSRAM) from `fcn_declare.h`
- **Avoid Variable Length Arrays (VLAs)**: FreeRTOS task stacks are typically 2–8 KB. A runtime-sized VLA can silently exhaust the stack. Use fixed-size arrays or heap allocation (`d_malloc` / `p_malloc`). Any VLA must be explicitly justified in source or PR.
<!-- HUMAN_ONLY_START -->
GCC/Clang support VLAs as an extension (they are not part of the C++ standard), so they look like a legitimate feature — but they are allocated on the stack at runtime. On ESP32/ESP8266, a VLA whose size depends on a runtime parameter (segment dimensions, pixel counts, etc.) can silently exhaust the stack and cause the program to behave in unexpected ways or crash.
<!-- HUMAN_ONLY_END -->
- **Larger buffers** (LED data, JSON documents) should use PSRAM when available and technically feasible
- **Hot-path**: some data should stay in DRAM or IRAM for performance reasons
- Memory efficiency matters, but is less critical on boards with PSRAM
Heap fragmentation is a concern:
<!-- HUMAN_ONLY_START -->
- Fragmentation can lead to crashes, even when the overall amount of available heap is still good. The C++ runtime doesn't do any "garbage collection".
<!-- HUMAN_ONLY_END -->
- Avoid frequent `d_malloc` and `d_free` inside a function, especially for small sizes.
- Avoid frequent creation / destruction of objects.
- Allocate buffers early, and try to re-use them.
- Instead of incrementally appending to a `String`, reserve the expected max buffer upfront by using the `reserve()` method.
<!-- HUMAN_ONLY_START -->
```cpp
Stringresult;
result.reserve(65);// pre-allocate to avoid realloc fragmentation
```
```cpp
// prefer DRAM; falls back gracefully and enforces MIN_HEAP_SIZE guard
_mode.reserve(_modeCount);// allocate memory to prevent initial fragmentation - does not increase size()
_modeData.reserve(_modeCount);// allocate memory to prevent initial fragmentation - does not increase size()
```
<!-- HUMAN_ONLY_END -->
## `const` and `constexpr`
<!-- HUMAN_ONLY_START -->
`const` is a promise to the compiler that a value (or object) will not change - a function declared with a `const char* message` parameter is not allowed to modify the content of `message`.
This pattern enables optimizations and makes intent clear to reviewers.
`constexpr` allows to define constants that are *guaranteed* to be evaluated by the compiler (zero run-time costs).
<!-- HUMAN_ONLY_END -->
- For function parameters that are read-only, prefer `const &` or `const`.
### `const` locals
<!-- HUMAN_ONLY_START -->
* Adding `const` to a local variable that is only assigned once is optional, but *not* strictly necessary.
<!-- HUMAN_ONLY_END -->
* In hot-path code, `const` on cached locals may help the compiler keep values in registers.
```cpp
const uint_fast16_t cols = vWidth();
const uint_fast16_t rows = vHeight();
```
### `const` references to avoid copies
- Pass objects by `const &` (or `&`) instead of copying them implicitly.
- Use `const &` (or `&`) inside loops - This avoids constructing temporary objects on every access.
<!-- HUMAN_ONLY_START -->
```cpp
const auto &m = _mappings[i]; // reference, not a copy (bus_manager.cpp)
Segment& sourcesegment = strip.getSegment(sourceid); // alias — avoids creating a temporary Segment instance
```
For function parameters that are read-only, prefer `const &`:
- Class **Data Members:** Avoid reference data members (`T&` or `const T&`) in a class.
A reference member can outlive the object it refers to, causing **dangling reference** bugs that are hard to diagnose. Prefer value storage or use a pointer and document the expected lifetime.
<!-- HUMAN_ONLY_START -->
<!-- hidden from AI for now - codebase is not compliant to this rule (slowly migrating) -->
### `constexpr` over `#define`
- Prefer `constexpr` for compile-time constants. Unlike `#define`, `constexpr` respects scope and type safety, keeping the global namespace clean.
```cpp
// Prefer:
constexpr uint32_t TWO_CHANNEL_MASK = 0x00FF00FF;
constexpr int WLED_MAX_BUSSES = WLED_MAX_DIGITAL_CHANNELS + WLED_MAX_ANALOG_CHANNELS;
// Avoid (when possible):
#define TWO_CHANNEL_MASK 0x00FF00FF
```
<!-- HUMAN_ONLY_END -->
### `static_assert` over `#error`
- Use `static_assert` instead of the C-style `#if … #error … #endif` pattern when validating compile-time constants. It provides a clear message and works with `constexpr` values.
- `#define` and `#if ... #else ... #endif` is still needed for conditional-compilation guards and build-flag-overridable values.
<!-- HUMAN_ONLY_START -->
```cpp
// Prefer:
constexpr int WLED_MAX_BUSSES = WLED_MAX_DIGITAL_CHANNELS + WLED_MAX_ANALOG_CHANNELS;
static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
// Avoid:
#if (WLED_MAX_BUSSES > 32)
#error "WLED_MAX_BUSSES exceeds hard limit"
#endif
```
```cpp
// using static_assert() to validate enumerated types (zero cost at runtime)
"PinOwner::None must be zero, so default array initialization works as expected");
```
<!-- HUMAN_ONLY_END -->
### `static` and `const` class methods
#### `const` member functions
Marking a member function `const` tells the compiler that it does not modify the object's state:
```cpp
uint16_t length() const { return _len; }
bool isActive() const { return _active; }
```
<!-- HUMAN_ONLY_START -->
Benefits for GCC/Xtensa/RISC-V:
- The compiler knows the method cannot write to `this`, so it is free to **keep member values in registers** across the call and avoid reload barriers.
- `const` methods can be called on `const` objects and `const` references — essential when passing large objects as `const &` to avoid copying.
- `const` allows the compiler to **eliminate redundant loads**: if a caller already has a member value cached, the compiler can prove the `const` call cannot invalidate it.
<!-- HUMAN_ONLY_END -->
Declare getter, query, or inspection methods `const`. If you need to mark a member `mutable` to work around this (e.g. for a cache or counter), document the reason.
#### `static` member functions
<!-- HUMAN_ONLY_START -->
A `static` member function has no implicit `this` pointer. This has two distinct advantages:
1. **Smaller code, faster calls**: no `this` is passed in a register. On Xtensa and RISC-V, this removes one register argument from every call site and prevents the compiler from emitting `this`-preservation code around inlined blocks.
2. **Better inlining**: GCC can inline a `static` method with more certainty because it cannot be overridden by a derived class (no virtual dispatch ambiguity) and has no aliasing concern through `this`.
Use `static` for any method that does not need access to instance members:
`static` communicates intent clearly: a reviewer immediately knows the method is stateless and safe to call without a fully constructed object.
> **Rule of thumb**: if a method does not read or write any member variable, make it `static`. If it only reads member variables, make it `const`. Note: `static` methods cannot also be `const`-qualified because there is no implicit `this` pointer to be const — just use `static`. Both qualifiers reduce coupling and improve generated code on all ESP32 targets.
---
## Hot-Path Optimization
The hot path is the per-frame pixel pipeline: **Segment → Strip → BusManager → Bus(Digital,HUB75,Network) or PolyBus → LED driver, plus ``WS2812FX::show()`` and below**.
Speed is the priority here. The patterns below are taken from existing hot-path code (`FX_fcn.cpp`, `FX_2Dfcn.cpp`, `bus_manager.cpp`, `colors.cpp`) and should be followed when modifying these files.
Note: `FX.cpp` (effect functions) is written by many contributors and has diverse styles — that is acceptable.
### Function Attributes
Stack the appropriate attributes on hot-path functions. Defined in `const.h`:
| Attribute | Meaning | When to use |
|---|---|---|
| `__attribute__((hot))` | Branch-prediction hint | hot-path functions with complex logic |
| `IRAM_ATTR` | Place in fast IRAM (ESP32) | Critical per-pixel functions (e.g. `BusDigital::setPixelColor`) |
| `IRAM_ATTR_YN` | IRAM on ESP32, no-op on ESP8266 | Hot functions that ESP8266 can't fit in IRAM |
| `WLED_O2_ATTR` | Force `-O2` optimization | Most hot-path functions |
| `WLED_O3_ATTR` | Force `-O3,fast-math` | Innermost color math (e.g. `color_blend`) |
| `[[gnu::hot]] inline` | Modern C++ attribute + inline | Header-defined accessors (e.g. `progress()`, `currentBri()`) |
Note: `WLED_O3_ATTR` sometimes causes performance loss compared to `WLED_O2_ATTR`. Choose optimization levels based on test results.
Example signature:
```cpp
void IRAM_ATTR_YN WLED_O2_ATTR __attribute__((hot)) Segment::setPixelColor(unsigned i, uint32_t c)
```
<!-- HUMAN_ONLY_START -->
### Cache Members to Locals Before Loops
Copy class members and virtual-call results to local variables before entering a loop:
```cpp
uint_fast8_t count = numBusses; // avoid repeated member access
for (uint_fast8_t i = 0; i < count; i++) {
Bus* const b = busses[i]; // const pointer hints to compiler
uint_fast16_t bstart = b->getStart();
uint_fast16_t blen = b->getLength();
...
}
```
<!-- HUMAN_ONLY_END -->
### Unsigned Range Check
Replace two-comparison range tests with a single unsigned subtraction:
if ((uint_fast16_t)(pix - bstart) < blen) // also catches negative pix via unsigned underflow
```
### Early Returns
Guard every hot-path function with the cheapest necessary checks first:
```cpp
if (!isActive()) return; // inactive segment
if (unsigned(i) >= vLength()) return; // bounds check (catches negative i too)
```
### Avoid Nested Calls — Fast Path / Complex Path
Avoid calling non-inline functions or making complex decisions inside per-pixel hot-path code. When a function has both a common simple case and a rare complex case, split it into two variants and choose once per frame rather than per pixel.
General rules:
- Keep fast-path functions free of non-inline calls, multi-way branches, and complex switch-case decisions.
- Hoist per-frame decisions (e.g. simple vs. complex segment) out of the per-pixel loop.
- Code duplication between fast/slow variants is acceptable to keep the fast path lean.
### Function Pointers to Eliminate Repeated Decisions
When the same decision (e.g. "which drawing routine?") would be evaluated for every pixel, assign the chosen variant to a function pointer once and let the inner loop call through the pointer. This removes the branch entirely — the calling code (e.g. the GIF decoder loop) only ever invokes one function per frame, with no per-pixel decision.
<!-- HUMAN_ONLY_START -->
`image_loader.cpp` demonstrates the pattern: `calculateScaling()` picks the best drawing callback once per frame based on segment dimensions and GIF size, then passes it to the decoder via `setDrawPixelCallback()`:
Each callback is a small, single-purpose function with no internal branching — the decoder's per-pixel loop never re-evaluates which strategy to use.
<!-- HUMAN_ONLY_END -->
<!-- HUMAN_ONLY_START -->
### Template Specialization (Advanced)
Templates can eliminate runtime decisions by generating separate code paths at compile time. For example, a pixel setter could be templated on color order or channel count so the compiler removes dead branches and produces tight, specialized machine code:
if constexpr (hasWhite) out[3] = W(col); // compiled out when hasWhite==false
}
```
Use sparingly — each instantiation duplicates code in flash. On ESP8266 and small-flash ESP32 boards this can exhaust IRAM/flash. Prefer templates only when the hot path is measurably faster and the number of instantiations is small (2–4).
### RAII Lock-Free Synchronization (Advanced)
Where contention is rare and the critical section is short, consider replacing mutex-based locking with lock-free techniques using `std::atomic` and RAII scoped guards. A scoped guard sets a flag on construction and clears it on destruction, guaranteeing cleanup even on early return:
if (!guard) return; // another task is already sending
// ... do work — flag auto-clears when guard goes out of scope
```
This avoids FreeRTOS semaphore overhead and the risk of forgetting to return a semaphore. There are no current examples of this pattern in the codebase — consult with maintainers before introducing it in new code, to ensure it aligns with the project's synchronization conventions.
<!-- HUMAN_ONLY_END -->
### Pre-Compute Outside Loops
Move invariant calculations before the loop. Pre-compute reciprocals to replace division with multiplication.
### Bit Shifts Over Division (mainly for RISC-V boards)
ESP32 and ESP32-S3 (Xtensa core) have a fast "integer divide" instruction, so manual shifts rarely help.
On RISC-V targets (ESP32-C3/C6/P4) and ESP8266, prefer explicit bit-shifts for power-of-two arithmetic — the compiler does **not** always convert divisions to shifts.
Always use unsigned operands for right shifts; signed right-shift is implementation-defined.
<!-- HUMAN_ONLY_START -->
On RISC-V-based boards (ESP32-C3, ESP32-C6, ESP32-C5) explicit shifts can be beneficial.
```cpp
position >> 3 // instead of position / 8
(255U - rate) >> 1 // instead of (255 - rate) / 2
i & 0x0007 // instead of i % 8
```
**Important**: The bit-shifted expression should be unsigned. On some MCUs, "signed right-shift" is implemented by an "arithmetic shift right" that duplicates the sign bit: ``0b1010 >> 1 = 0b1101``.
<!-- HUMAN_ONLY_END -->
### Static Caching for Expensive Computations
Cache results in static locals when the input rarely changes between calls:
```cpp
static uint16_t lastKelvin = 0;
static byte correctionRGB[4] = {255,255,255,0};
if (lastKelvin != kelvin) {
colorKtoRGB(kelvin, correctionRGB); // expensive — only recalculate when input changes
lastKelvin = kelvin;
}
```
### Inlining Strategy
- Move frequently-called small functions to headers for inlining (e.g. `Segment::setPixelColorRaw` is in `FX.h`)
- Use `static inline` for file-local helpers
### Math & Trigonometric Functions
- WLED uses a custom `fastled_slim` library. The old FastLED trig aliases (`sin8`, `cos8`, `sin16`, `cos16`) **no longer exist and cause a compile error** — use `sin8_t()`, `cos8_t()`, `sin16_t()`, `cos16_t()` instead. For float approximations use `sin_approx()` / `cos_approx()` instead of `sinf()` / `cosf()`. Replace FastLED noise aliases (`inoise8`, `inoise16`) with `perlin8`, `perlin16`.
<!-- HUMAN_ONLY_START -->
| ❌ Do not use (compile error) | ✅ Use instead | Source |
| `sqrtf()` on floats | `sqrtf()` (acceptable) | — no WLED replacement |
<!-- HUMAN_ONLY_END -->
---
## `delay()` vs `yield()` in ESP32 Tasks
<!-- HUMAN_ONLY_START -->
* On ESP32, `delay(ms)` calls `vTaskDelay(ms / portTICK_PERIOD_MS)`, which **suspends only the calling task**. The FreeRTOS scheduler immediately runs all other ready tasks.
* The Arduino `loop()` function runs inside `loopTask`. Calling `delay()` there does *not* block the network stack, audio FFT, LED DMA, nor any other FreeRTOS task.
* This differs from ESP8266, where `delay()` stalls the entire system unless `yield()` was called inside.
<!-- HUMAN_ONLY_END -->
- On ESP32, `delay()` is generally allowed, as it helps to efficiently manage CPU usage of all tasks.
- On ESP8266, only use `delay()` and `yield()` in the main `loop()` context. If not sure, protect with `if (can_yield()) ...`.
- Do *not* use `delay()` in effects (FX.cpp) or in the hot pixel path.
- `delay()` on the bus-level is allowed, it might be needed to achieve exact timing in LED drivers.
### IDLE Watchdog and Custom Tasks on ESP32
- In arduino-esp32, `yield()` calls `vTaskDelay(0)`, which only switches to tasks at equal or higher priority — the IDLE task (priority 0) is never reached.
- **Do not use `yield()` to pace ESP32 tasks or assume it feeds any watchdog**.
- **Custom `xTaskCreate()` tasks must call `delay(1)` in their loop, not `yield()`.** Without a real blocking call, the IDLE task is starved. The IDLE watchdog panic is the first visible symptom — but the damage starts earlier: deleted task memory leaks, software timers stop firing, light sleep is disabled, and Wi-Fi/BT idle hooks don't run. Structure custom tasks like this:
```cpp
// WRONG — IDLE task is never scheduled; yield() does not feed the idle task watchdog.
void myTask(void*) {
for (;;) {
doWork();
yield();
}
}
// CORRECT — delay(1) suspends the task for ≥1 ms, IDLE task runs, IDLE watchdog is fed
void myTask(void*) {
for (;;) {
doWork();
delay(1); // DO NOT REMOVE — lets IDLE(0) run and feeds its watchdog
}
}
```
- Prefer blocking FreeRTOS primitives (`xQueueReceive`, `ulTaskNotifyTake`, `vTaskDelayUntil`) over `delay(1)` polling where precise timing or event-driven behaviour is needed.
- **Watchdog note.** WLED disables the Task Watchdog by default (`WLED_WATCHDOG_TIMEOUT 0` in `wled.h`). When enabled, `esp_task_wdt_reset()` is called at the end of each `loop()` iteration. Long blocking operations inside `loop()` — such as OTA downloads or slow file I/O — must call `esp_task_wdt_reset()` periodically, or be restructured so the main loop is not blocked for longer than the configured timeout.
## Caveats and Pitfalls
- **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard configurations, like WLED_MAX_SEGNAME_LEN = 64).
- **Float-to-unsigned conversion is undefined behavior when the value is out of range.** Converting a negative `float` directly to an unsigned integer type (`uint8_t`, `uint16_t`, …) is UB per the C++ standard — the Xtensa (ESP32) toolchain may silently wrap, but RISC-V (ESP32-C3/C5/C6/P4) can produce different results due to clamping. Cast through a signed integer first:
WLED runs on the Arduino-ESP32 framework, which wraps ESP-IDF. Understanding the ESP-IDF layer is essential when writing chip-specific code, managing peripherals, or preparing for the IDF v5.x migration. This guide documents patterns already used in the codebase and best practices derived from Espressif's official examples.
> **Scope**: This file is an optional review guideline. It applies when touching chip-specific code, peripheral drivers, memory allocation, or platform conditionals.
> **Note for AI review tools**: sections enclosed in
> contributor reference material. Do **not** use that content as actionable review
> criteria — treat it as background context only.
---
<!-- HUMAN_ONLY_START -->
## Identifying the Build Target: `CONFIG_IDF_TARGET_*`
Use `CONFIG_IDF_TARGET_*` macros to gate chip-specific code at compile time. These are set by the build system and are mutually exclusive — exactly one is defined per build.
WLED validates at compile time that exactly one target is defined and that it is a supported chip (`wled.cpp` lines 39–61). Follow this pattern when adding new chip-specific branches:
- **Always test on the actual chip** before claiming support. Simulators and cross-compilation can hide peripheral differences.
- **Prefer `#elif` chains** over nested `#ifdef` for readability.
- **Do not use `CONFIG_IDF_TARGET_*` for feature detection.** Use `SOC_*` capability macros instead (see next section). For example, use `SOC_I2S_SUPPORTS_ADC` instead of `CONFIG_IDF_TARGET_ESP32` to check for I2S ADC support.
- When a feature must be disabled on certain chips, use explicit `static_assert()` or `#warning` directives so the build clearly reports what is missing.
---
## Hardware Capability Detection: `SOC_*` Macros
`SOC_*` macros (from `soc/soc_caps.h`) describe what the current chip supports. They are the correct way to check for peripheral features — they stay accurate when new chips are added, unlike `CONFIG_IDF_TARGET_*` checks.
<!-- HUMAN_ONLY_START -->
### Important `SOC_*` macros used in WLED
| Macro | Type | Used in | Purpose |
|---|---|---|---|
| `SOC_I2S_NUM` | `int` | `audio_source.h` | Number of I2S peripherals (1 or 2) |
// happens to be correct today, but breaks when a new chip adds PDM support
#endif
```
<!-- HUMAN_ONLY_START -->
### PSRAM capability macros
For PSRAM presence, mode, and DMA access patterns:
| Macro | Meaning |
|---|---|
| `CONFIG_SPIRAM` / `BOARD_HAS_PSRAM` | PSRAM is present in the build configuration |
| `CONFIG_SPIRAM_MODE_QUAD` | Quad-SPI PSRAM (standard, used on ESP32 classic and some S2/S3 boards) |
| `CONFIG_SPIRAM_MODE_OCT` | Octal-SPI PSRAM — 8 data lines, DTR mode. Used on ESP32-S3 with octal PSRAM (e.g. N8R8 / N16R8 modules). Reserves GPIO 33–37 for the PSRAM bus — **do not allocate these pins** when this macro is defined. `wled.cpp` uses this to gate GPIO reservation. |
| `CONFIG_SPIRAM_MODE_HEX` | Hex-SPI (16-line) PSRAM — future interface on ESP32-P4 running at up to 200 MHz. Used in `json.cpp` to report the PSRAM mode. |
| `CONFIG_SOC_PSRAM_DMA_CAPABLE` | PSRAM buffers can be used with DMA (ESP32-S3 with octal PSRAM) |
| `CONFIG_SOC_MEMSPI_FLASH_PSRAM_INDEPENDENT` | SPI flash and PSRAM on separate buses (no speed contention) |
<!-- HUMAN_ONLY_END -->
#### Detecting octal/hex flash
On ESP32-S3 modules with OPI flash (e.g. N8R8 modules where the SPI flash itself runs in Octal-PI mode), the build system sets:
| Macro | Meaning |
|---|---|
| `CONFIG_ESPTOOLPY_FLASHMODE_OPI` | Octal-PI flash mode. On S3, implies GPIO 33–37 are used by the flash/PSRAM interface — the same GPIO block as octal PSRAM. `wled.cpp` uses `CONFIG_ESPTOOLPY_FLASHMODE_OPI \|\| (CONFIG_SPIRAM_MODE_OCT && BOARD_HAS_PSRAM)` to decide whether to reserve these GPIOs. `json.cpp` uses this to report the flash mode string as `"🚀OPI"`. |
| `CONFIG_ESPTOOLPY_FLASHMODE_HEX` | Hex flash mode (ESP32-P4). Reported as `"🚀🚀HEX"` in `json.cpp`. |
**Pattern used in WLED** (from `wled.cpp`) to reserve the octal-bus GPIOs on S3:
The jump from IDF v4.4 (arduino-esp32 v2.x) to IDF v5.x (arduino-esp32 v3.x) is the largest API break in ESP-IDF history. This section documents the critical changes and recommended migration patterns based on the upstream WLED `V5-C6` branch (`https://github.com/wled/WLED/tree/V5-C6`). Note: WLED has not yet migrated to IDF v5 — these patterns prepare for the future migration.
<!-- HUMAN_ONLY_START -->
### Compiler changes
IDF v5.x ships a much newer GCC toolchain. Key versions:
| Stricter `-Werror=enum-conversion` | Implicit int-to-enum casts now error | Use explicit `static_cast<>` or typed enums |
| C++20/23 features available | `consteval`, `concepts`, `std::span`, `std::expected` | Use judiciously — ESP8266 builds still require GCC 10.x with C++17 |
| `-Wdeprecated-declarations` enforced | Deprecated API calls become warnings/errors | Migrate to new APIs (see below) |
| `-Wdangling-reference` (GCC 13+) | Warns when a reference binds to a temporary that will be destroyed | Fix the lifetime issue; do not suppress the warning |
| `-fno-common` default (GCC 12+) | Duplicate tentative definitions across translation units cause linker errors | Use `extern` declarations in headers, define in exactly one `.cpp` |
| RISC-V codegen improvements | C3/C6/P4 benefit from better register allocation | No action needed — automatic |
### C++ language features: GCC 8 → GCC 14
The jump from GCC 8.4 to GCC 14.2 spans six major compiler releases. This section lists features that become available and patterns that need updating.
#### Features safe to use after migration
These work in GCC 13+/14+ but **not** in GCC 8.4. Guard with `#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)` if the code must compile on both IDF v4 and v5.
| Feature | Standard | Example | Benefit |
|---|---|---|---|
| Designated initializers (C++20) | C++20 | `gpio_config_t cfg = { .mode = GPIO_MODE_OUTPUT };` | Already used as a GNU extension in GCC 8; becomes standard and portable in C++20 |
| `[[likely]]` / `[[unlikely]]` | C++20 | `if (err != ESP_OK) [[unlikely]] { ... }` | Hints for branch prediction; useful in hot paths |
| `int x; enum E e = x;` | Warning (often ignored) | Error with `-Werror=enum-conversion` | `E e = static_cast<E>(x);` |
| `int g;` in two `.cpp` files | Both compile, linker merges (tentative definition) | Error: multiple definitions (`-fno-common`) | `extern int g;` in header, `int g;` in one `.cpp` |
| `const char* ref = std::string(...).c_str();` | Silent dangling pointer | Warning (`-Wdangling-reference`) | Extend lifetime: store the `std::string` in a local variable |
| `register int x;` | Accepted (ignored) | Warning or error (`register` removed in C++17) | Remove `register` keyword |
| Narrowing in aggregate init | Warning | Error | Use explicit cast or wider type |
| Implicit `this` capture in lambdas | Accepted in `[=]` | Deprecated warning; error in C++20 mode | Use `[=, this]` or `[&]` |
<!-- HUMAN_ONLY_END -->
#### Recommendations
- **Do not raise the minimum C++ standard yet.** WLED must still build on IDF v4.4 (GCC 8.4, C++17). Use `#if __cplusplus > 201703L` to gate C++20 features.
- **Mark intentional fallthrough** with `[[fallthrough]]` — GCC 14 warns on unmarked fallthrough by default.
<!-- HUMAN_ONLY_START -->
- **Prefer `std::optional` over sentinel values** (e.g., `-1` for "no pin") in new code — it works on both compilers.
- **Use `std::string_view`** for read-only string parameters instead of `const char*` or `const String&` — zero-copy and works on GCC 8+.
- **Avoid raw `union` type punning** — prefer `memcpy` (GCC 8) or `std::bit_cast` (GCC 13+) for strict-aliasing safety.
<!-- HUMAN_ONLY_END -->
### Deprecated and removed APIs
#### RMT (Remote Control Transceiver)
The legacy `rmt_*` functions are removed in IDF v5. Do not introduce new legacy RMT calls.
<!-- HUMAN_ONLY_START -->
The new API is channel-based:
| IDF v4 (legacy) | IDF v5 (new) | Notes |
|---|---|---|
| `rmt_config()` + `rmt_driver_install()` | `rmt_new_tx_channel()` / `rmt_new_rx_channel()` | Channels are now objects |
| `rmt_write_items()` | `rmt_transmit()` with encoder | Requires `rmt_encoder_t` |
| `rmt_set_idle_level()` | Configure in channel config | Set at creation time |
| `rmt_item32_t` | `rmt_symbol_word_t` | Different struct layout |
<!-- HUMAN_ONLY_END -->
**WLED impact**: NeoPixelBus LED output and IR receiver both use legacy RMT. The upstream `V5-C6` branch adds `-D WLED_USE_SHARED_RMT` and disables IR until the library is ported.
#### I2S (Inter-IC Sound)
Legacy `i2s_driver_install()` + `i2s_read()` API is deprecated. When touching audio source code, wrap legacy I2S init and reading in `#if ESP_IDF_VERSION_MAJOR < 5` / `#else`.
<!-- HUMAN_ONLY_START -->
The new API uses channel handles:
| IDF v4 (legacy) | IDF v5 (new) | Notes |
|---|---|---|
| `i2s_driver_install()` | `i2s_channel_init_std_mode()` | Separate STD/PDM/TDM modes |
| `i2s_set_pin()` | Pin config in `i2s_std_gpio_config_t` | Set at init time |
**WLED impact**: The audioreactive usermod (`audio_source.h`) heavily uses legacy I2S. Migration requires rewriting the `I2SSource` class for channel-based API.
<!-- HUMAN_ONLY_START -->
#### ADC (Analog-to-Digital Converter)
Legacy `adc1_get_raw()` and `esp_adc_cal_*` are deprecated:
| RTC RAM | `MALLOC_CAP_RTCRAM` | Moderate | No | 8 KB | Data surviving deep sleep; small persistent buffers |
<!-- HUMAN_ONLY_END -->
### WLED allocation wrappers
WLED provides convenience wrappers with automatic fallback. **Always prefer these over raw `heap_caps_*` calls**:
| Function | Allocation preference | Use case |
|---|---|---|
| `d_malloc(size)` | RTC → DRAM → PSRAM | General-purpose; prefers fast memory |
| `d_calloc(n, size)` | Same as `d_malloc`, zero-initialized | Arrays, structs |
| `p_malloc(size)` | PSRAM → DRAM | Large buffers; prefers abundant memory |
| `p_calloc(n, size)` | Same as `p_malloc`, zero-initialized | Large arrays |
| `d_malloc_only(size)` | RTC → DRAM (no PSRAM fallback) | DMA buffers, time-critical data |
### PSRAM guidelines
- **Check availability**: always test `psramFound()` before assuming PSRAM is present.
- **DMA compatibility**: on ESP32 (classic), PSRAM buffers are **not DMA-capable** — use `d_malloc_only()` to allocate DMA buffers in DRAM only. On ESP32-S3 with octal PSRAM (`CONFIG_SPIRAM_MODE_OCT`), PSRAM buffers *can* be used with DMA when `CONFIG_SOC_PSRAM_DMA_CAPABLE` is defined.
- **JSON documents**: use the `PSRAMDynamicJsonDocument` allocator (defined in `wled.h`) to put large JSON documents in PSRAM:
```cpp
PSRAMDynamicJsonDocument doc(16384); // allocated in PSRAM if available
```
- **Fragmentation**: PSRAM allocations fragment less than DRAM because the region is larger. But avoid mixing small and large allocations in PSRAM — small allocations waste the MMU page granularity.
- **Heap validation**: use `d_measureHeap()` and `d_measureContiguousFreeHeap()` to monitor remaining DRAM. Allocations that would drop free DRAM below `MIN_HEAP_SIZE` should go to PSRAM instead.
- **Performance**: Keep hot-path data in DRAM. Prefer PSRAM for capacity-oriented buffers and monitor contiguous DRAM headroom.
<!-- HUMAN_ONLY_START -->
PSRAM access is up to 15× slower than DRAM on ESP32, 3–10× slower than DRAM on ESP32-S3/-S2 with quad-SPI bus. On ESP32-S3 with octal PSRAM (`CONFIG_SPIRAM_MODE_OCT`), the penalty is smaller (~2×) because the 8-line DTR bus can transfer 8 bits in parallel at 80 MHz (120 MHz is possible with CONFIG_SPIRAM_SPEED_120M, which requires enabling experimental ESP-IDF features). On ESP32-P4 with hex PSRAM (`CONFIG_SPIRAM_MODE_HEX`), the 16-line bus runs at 200 MHz which brings it on-par with DRAM. Keep hot-path data in DRAM regardless, but consider that ESP32 often crashes when the largest DRAM chunk gets below 10 KB.
<!-- HUMAN_ONLY_END -->
<!-- HUMAN_ONLY_START -->
### Pattern: preference-based allocation
When you need a buffer that works on boards with or without PSRAM:
```cpp
// Prefer PSRAM for large buffers, fall back to DRAM
- Not supported on ESP32-C3 (`SOC_I2S_SUPPORTS_PDM_RX` not defined).
- ESP32-S3 PDM has known issues: sample rate at 50% of expected, very low amplitude.
- **16-bit data width**: Espressif's IDF documentation states that in PDM mode the data unit width is always 16 bits, regardless of the configured `bits_per_sample`.
- See [espressif/esp-idf#8660](https://github.com/espressif/esp-idf/issues/8660) for the upstream issue.
- **Flag `bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT` in PDM mode** — this causes the S3 low-amplitude symptom.
- No clock pin (`I2S_CKPIN = -1`) triggers PDM mode in WLED.
---
## HUB75 LED Matrix: Best Practices
WLED uses the `ESP32-HUB75-MatrixPanel-I2S-DMA` library for HUB75 matrix output.
| larger | 3-bit (9-bit color) | Minimal color range |
### Resource conflicts
- **APLL**: HUB75 I2S DMA uses the APLL. Disable APLL in the audio I2S driver when HUB75 is active.
- **I2S peripheral**: HUB75 uses `I2S_NUM_1` (or `I2S_NUM_0` on single-I2S chips). Audio must use the other port.
- **Pin count**: HUB75 requires 13–14 GPIO pins. On ESP32-S2 this severely limits remaining GPIO.
- **Reboot required**: on ESP32-S3, changing HUB75 driver options requires a full reboot — the I2S DMA cannot be reconfigured at runtime.
---
<!-- HUMAN_ONLY_START -->
## GPIO Best Practices
### Prefer `gpio_config()` over individual calls
```cpp
// Preferred: single struct-based configuration
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << pin),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
// Avoid: multiple separate calls (more error-prone, deprecated in IDF v5)
gpio_set_direction(pin, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(pin, GPIO_FLOATING);
```
<!-- HUMAN_ONLY_END -->
### Pin manager integration
Always allocate pins through WLED's `pinManager` before using GPIO APIs:
```cpp
if (!pinManager.allocatePin(myPin, true, PinOwner::UM_MyUsermod)) {
return; // pin in use by another module
}
// Now safe to configure
```
---
## Timer Best Practices
### Microsecond timing
For high-resolution timing, prefer `esp_timer_get_time()` (microsecond resolution, 64-bit) over `millis()` or `micros()`.
<!-- HUMAN_ONLY_START -->
```cpp
#include <esp_timer.h>
int64_t now_us = esp_timer_get_time(); // monotonic, not affected by NTP
```
> **Note**: In arduino-esp32, both `millis()` and `micros()` are thin wrappers around `esp_timer_get_time()` — they share the same monotonic clock source. Prefer the direct call when you need the full 64-bit value or ISR-safe access without truncation:
For periodic tasks with sub-millisecond precision, use `esp_timer`:
```cpp
esp_timer_handle_t timer;
esp_timer_create_args_t args = {
.callback = myCallback,
.arg = nullptr,
.dispatch_method = ESP_TIMER_TASK, // run in timer task (not ISR)
.name = "my_timer",
};
esp_timer_create(&args, &timer);
esp_timer_start_periodic(timer, 1000); // 1 ms period
```
<!-- HUMAN_ONLY_END -->
Always prefer `ESP_TIMER_TASK` dispatch over `ESP_TIMER_ISR` unless you need ISR-level latency — ISR callbacks have severe restrictions (no logging, no heap allocation, no FreeRTOS API calls).
### Precision waiting: coarse delay then spin-poll
When waiting for a precise future deadline (e.g., FPS limiting, protocol timing), avoid spinning the entire duration — that wastes CPU and starves other tasks. Instead, yield to FreeRTOS while time allows, then spin only for the final window.
<!-- HUMAN_ONLY_START -->
```cpp
// Wait until 'target_us' (a micros() / esp_timer_get_time() timestamp)
long time_to_wait = (long)(target_us - micros());
// Coarse phase: yield to FreeRTOS while we have more than ~2 ms remaining.
// vTaskDelay(1) suspends the task for one RTOS tick, letting other task run freely.
while (time_to_wait > 2000) {
vTaskDelay(1);
time_to_wait = (long)(target_us - micros());
}
// Fine phase: busy-poll the last ≤2 ms for microsecond accuracy.
// micros() wraps esp_timer_get_time() so this is low-overhead.
> The threshold (2000 µs as an example) should be at least one RTOS tick (default 1 ms on ESP32) plus some margin. A value of 1500–3000 µs works well in practice.
---
## ADC Best Practices
<!-- HUMAN_ONLY_START -->
### Version-aware ADC code
ADC is one of the most fragmented APIs across IDF versions:
Not all chips have 12-bit ADC. `SOC_ADC_MAX_BITWIDTH` reports the maximum resolution (12 or 13 bits). Note that in IDF v5, this macro was renamed to `CONFIG_SOC_ADC_RTC_MAX_BITWIDTH`. Write version-aware guards:
For situations between these two extremes — where you want the `ESP_ERROR_CHECK` formatted log message (file, line, error name) but must not abort — use `ESP_ERROR_CHECK_WITHOUT_ABORT()`.
<!-- HUMAN_ONLY_START -->
```cpp
// Logs in the same format as ESP_ERROR_CHECK, but returns the error code instead of aborting.
// Useful for non-fatal driver calls where you want visibility without crashing.
WLED uses its own logging macros — **not** `ESP_LOGx()`. For application-level code, always use the WLED macros defined in `wled.h`:
| Macro family | Defined in | Controlled by | Use for |
|---|---|---|---|
| `DEBUG_PRINT` / `DEBUG_PRINTLN` / `DEBUG_PRINTF` | `wled.h` | `WLED_DEBUG` build flag | Development/diagnostic output; compiled out in release builds |
All of these wrap `Serial` output through the `DEBUGOUT` / `DEBUGOUTLN` / `DEBUGOUTF` macros.
**Exception — low-level driver code**: When writing code that interacts directly with ESP-IDF APIs (e.g., I2S initialization, RMT setup), use `ESP_LOGx()` macros instead. They support tag-based filtering and compile-time log level control:
<!-- HUMAN_ONLY_START -->
```cpp
static const char* TAG = "my_module";
ESP_LOGI(TAG, "Initialized with %d buffers", count);
ESP_LOGW(TAG, "PSRAM not available, falling back to DRAM");
ESP_LOGE(TAG, "Failed to allocate %u bytes", size);
```
<!-- HUMAN_ONLY_END -->
### Task creation and pinning
<!-- HUMAN_ONLY_START -->
On dual-core chips (ESP32, S3, P4), pin latency-sensitive tasks to a specific core:
```cpp
xTaskCreatePinnedToCore(
audioTask, // function
"audio", // name
4096, // stack size
nullptr, // parameter
5, // priority (higher = more important)
&audioTaskHandle, // handle
0 // core ID (0 = protocol core, 1 = app core)
);
```
<!-- HUMAN_ONLY_END -->
Guidelines:
- Pin network/protocol tasks to core 0 (where Wi-Fi runs).
- Pin real-time tasks (audio, LED output) to core 1.
- On single-core chips (S2, C3, C5, C6), only core 0 exists — pinning to core 1 will fail. Use `SOC_CPU_CORES_NUM > 1` guards or `tskNO_AFFINITY`.
- Use `SOC_CPU_CORES_NUM` to conditionally pin tasks:
**Tip: use xTaskCreateUniversal()** - from arduino-esp32 - to avoid the conditional on `SOC_CPU_CORES_NUM`. This function has the same signature as ``xTaskCreatePinnedToCore()``, but automatically falls back to ``xTaskCreate()`` on single-core MCUs.
### `delay()`, `yield()`, and the IDLE task
FreeRTOS on ESP32 is **preemptive** — all tasks are scheduled by priority regardless of `yield()` calls. This is fundamentally different from ESP8266 cooperative multitasking.
<!-- HUMAN_ONLY_START -->
| Call | What it does | Reaches IDLE (priority 0)? |
|---|---|---|
| `delay(ms)` / `vTaskDelay(ticks)` | Suspends calling task; scheduler runs all other ready tasks | ✅ Yes |
| `yield()` / `vTaskDelay(0)` | Hint to switch to tasks at **equal or higher** priority only | ❌ No |
| `taskYIELD()` | Same as `vTaskDelay(0)` | ❌ No |
| Blocking API (`xQueueReceive`, `ulTaskNotifyTake`, `vTaskDelayUntil`) | Suspends task until event or timeout; IDLE runs freely | ✅ Yes |
<!-- HUMAN_ONLY_END -->
**`delay()` in `loopTask` is safe.** Arduino's `loop()` runs inside `loopTask`. Calling `delay()` suspends only `loopTask` — all other FreeRTOS tasks (Wi-Fi stack, audio FFT, LED DMA) continue uninterrupted on either core.
**`yield()` does not yield to IDLE.** Any task that loops with only `yield()` calls will starve the IDLE task, causing the IDLE watchdog to fire. Always use `delay(1)` (or a blocking FreeRTOS call) in tight task loops. Note: WLED redefines `yield()` as an empty macro on ESP32 WLEDMM_FASTPATH builds.
#### Why the IDLE task is not optional
<!-- HUMAN_ONLY_START -->
The FreeRTOS IDLE task (one per core on dual-core ESP32 and ESP32-S3; single instance on single-core chips) is not idle in the casual sense — it performs essential system housekeeping:
- **Frees deleted task memory**: when a task calls `vTaskDelete()`, the IDLE task reclaims its TCB and stack. Without IDLE running, deleted tasks leak memory permanently.
- **Runs the idle hook**: when `configUSE_IDLE_HOOK = 1`, the IDLE task calls `vApplicationIdleHook()` on every iteration — some ESP-IDF components register low-priority background work here.
- **Implements tickless idle / light sleep**: on battery-powered devices, IDLE is the entry point for low-power sleep. A permanently starved IDLE task disables light sleep entirely.
- **Runs registered idle hooks**: ESP-IDF components register callbacks via `esp_register_freertos_idle_hook()` (e.g., Wi-Fi background maintenance, Bluetooth housekeeping). These only fire when IDLE runs.
<!-- HUMAN_ONLY_END -->
In short: **starving IDLE corrupts memory cleanup, breaks background activities, disables low-power sleep, and prevents Wi-Fi/BT maintenance.** The IDLE watchdog panic is a symptom — the real damage happens before the watchdog fires.
### Watchdog management
Long-running operations may trigger the task watchdog. Feed it explicitly:
```cpp
#include <esp_task_wdt.h>
esp_task_wdt_reset(); // feed the watchdog in long loops
```
For tasks that intentionally block for extended periods, consider subscribing/unsubscribing from the TWDT:
```cpp
esp_task_wdt_delete(NULL); // remove current task from TWDT (IDF v4.4)
// ... long blocking operation ...
esp_task_wdt_add(NULL); // re-register
```
> **IDF v5 note**: In IDF v5, `esp_task_wdt_add()` and `esp_task_wdt_delete()` require an explicit `TaskHandle_t`. Use `xTaskGetCurrentTaskHandle()` instead of `NULL`.
// Waveform generator can create tones, PWM, and servos
typedefstruct{
uint32_tnextPeriodCcy;// ESP clock cycle when a period begins.
uint32_tendDutyCcy;// ESP clock cycle when going from duty to off
int32_tdutyCcys;// Set next off cycle at low->high to maintain phase
int32_tadjDutyCcys;// Temporary correction for next period
int32_tperiodCcys;// Set next phase cycle at low->high to maintain phase
uint32_texpiryCcy;// For time-limited waveform, the CPU clock cycle when this waveform must stop. If WaveformMode::UPDATE, temporarily holds relative ccy count
WaveformModemode;
boolautoPwm;// perform PWM duty to idle cycle ratio correction under high load at the expense of precise timings
}Waveform;
namespace{
staticstruct{
Waveformpins[17];// State of all possible pins
uint32_tstates=0;// Is the pin high or low, updated in NMI so no access outside the NMI code
uint32_tenabled=0;// Is it actively running, updated in NMI so no access outside the NMI code
// Enable lock-free by only allowing updates to waveform.states and waveform.enabled from IRQ service routine
int32_ttoSetBits=0;// Message to the NMI handler to start/modify exactly one waveform
int32_ttoDisableBits=0;// Message to the NMI handler to disable exactly one pin from waveform generation
// toSetBits temporaries
// cheaper than packing them in every Waveform, since we permit only one use at a time
# Check if Node.js is installed and present in PATH if it failed, abort the build
ifnode_exisNone:
print('\x1b[0;31;43m'+'Node.js is not installed or missing from PATH html css js will not be processed check https://kno.wled.ge/advanced/compiling-wled/'+'\x1b[0m')
exitCode=env.Execute("null")
exit(exitCode)
else:
# Install the necessary node packages for the pre-build asset bundling script
board_build.partitions=${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
# additional build flags for audioreactive - must be applied globally
AR_build_flags=;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
AR_lib_deps=;; for pre-usermod-library platformio_override compatibility
[esp32_idf_V4]
;; build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
;; *** important: build flags from esp32_idf_V4 are inherited by _all_ esp32-based MCUs: esp32, esp32s2, esp32s3, esp32c3
;;
;; please note that you can NOT update existing ESP32 installs with a "V4" build. Also updating by OTA will not work properly.
;; You need to completely erase your device (esptool erase_flash) first, then install the "V4" build from VSCode+platformio.
platform=https://github.com/tasmota/platform-espressif32/releases/download/2024.06.00/platform-espressif32.zip ;; Tasmota Arduino Core 2.0.18 with IPv6 support, based on IDF 4.4.8
platform_packages=
build_unflags=${common.build_unflags}
build_flags=-g
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
-DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 !
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
lib_deps=
${env.lib_deps}
makuna/NeoPixelBus @ 2.6.7
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${esp32_idf_V4.lib_deps}
board_build.partitions=${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
lib_deps=
${esp32_idf_V4.lib_deps}
board_build.partitions=${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT
${esp32_idf_V4.build_flags}
lib_deps=
${esp32_idf_V4.lib_deps}
board_build.partitions=${esp32.large_partitions} ;; default partioning for 8MB flash - can be overridden in build envs
-D SR_DMTYPE=-1 -D AUDIOPIN=-1 -D I2S_SDPIN=-1 -D I2S_WSPIN=-1 -D I2S_CKPIN=-1 -D MCLK_PIN=-1 ;; force AR to not allocate any PINs at startup
-D DATA_PINS=4 ;; default led pin = 16 conflicts with pins used for ethernet
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only => uncomment if your board uses ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
board_build.partitions=${esp32.default_partitions} ;; if you get errors about "out of program space", change this to ${esp32.extended_partitions} or even ${esp32.big_partitions}
build_flags=${common.build_flags} ${esp8266.build_flags} -D WLED_USE_SHOJO_PCB ;; NB: WLED_USE_SHOJO_PCB is not used anywhere in the source code. Not sure why its needed.
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!
A fast and feature-rich implementation of an ESP32 and ESP8266 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!
Originally created by [Aircoookie](https://github.com/Aircoookie)
## ⚙️ Features
- WS2812FX library integrated for over 100 special effects
- WS2812FX library with more than 100 special effects
- FastLED noise effects and 50 palettes
- Modern UI with color, effect and segment controls
- Segments to set different effects and colors to parts of the LEDs
- Settings page - configuration over network
- Segments to set different effects and colors to user defined parts of the LED string
- Settings page - configuration via the network
- Access Point and station mode - automatic failsafe AP
- Up to 10 LED outputs per instance
-[Up to 10 LED outputs](https://kno.wled.ge/features/multi-strip/#esp32) per instance
- Support for RGBW strips
- Up to 250 user presets to save and load colors/effects easily, supports cycling through them.
- Presets can be used to automatically execute API calls
- Nightlight function (gradually dims down)
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
- Configurable analog clock + support for the Cronixie kit by Diamex
- Configurable Auto Brightness limit for safer operation
- Full OTA software updateability (HTTP + ArduinoOTA), password protectable
- Configurable analog clock (Cronixie, 7-segment and EleksTube IPS clock support via usermods)
- Configurable Auto Brightness limit for safe operation
- Filesystem-based config for easier backup of presets and settings
## 💡 Supported light control interfaces
- WLED app for [Android](https://play.google.com/store/apps/details?id=com.aircoookie.WLED) and [iOS](https://apps.apple.com/us/app/wled/id1475695033)
- WLED app for [Android](https://play.google.com/store/apps/details?id=ca.cgagnier.wlednativeandroid) and [iOS](https://apps.apple.com/gb/app/wled-native/id6446207239)
- JSON and HTTP request APIs
- MQTT
- Blynk IoT
- MQTT
- E1.31, Art-Net, DDP and TPM2.net
- [diyHue](https://github.com/diyhue/diyHue) (Wled is supported by diyHue, including Hue Sync Entertainment under udp. Thanks to [Gregory Mallios](https://github.com/gmallios))
@@ -51,52 +52,36 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
See the [documentation on our official site](https://kno.wled.ge)!
[On this page](https://github.com/Aircoookie/WLED/wiki/Learning-the-ropes) you can find excellent tutorials made by the community and helpful tools to help you get your new lamp up and running!
[On this page](https://kno.wled.ge/basics/tutorials/) you can find excellent tutorials and tools to help you get your new project up and running!
Analog/non-addressable | any | Requires additional circuitry
## 🧊 Compatible PC RGB Fans and ARGB accessories
Brand | Model | Comments
|---|---|---|
Corsair | HD120 Fan | Uses WS2812B, data-in only
PCCOOLER | Moonlight 5-pack Fans | Uses WS2812B, includes Data-out connector to keep each fan uniquely addressable if wired in series like traditional LED strips
Any | 5v 3-pin ARGB for PC | Any PC RGB device that supports the 5v 3-pin ARGB motherboard header should work fine with WLED. All the major motherboard vendors support the Corsair HD120 and PCCOOLER fans listed, so we can safely assume any device that supports motherboard ARGB 5V 3-Pin standard will work with WLED.
## 💾 Compatible hardware
See [here](https://kno.wled.ge/basics/compatible-hardware)!
Check out the WLED [Discourse forum](https://wled.discourse.group)!
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com), but please only do so if you want to talk to me privately.
If WLED really brightens up your every day, you can [](https://paypal.me/aircoookie)
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com), but please, only do so if you want to talk to me privately.
If WLED really brightens up your day, you can [](https://paypal.me/aircoookie)
*Disclaimer:*
If you are sensitive to photosensitive epilepsy it is not recommended that you use this software.
In case you still want to try, don't use strobe, lighting or noise modes or high effect speed settings.
As per the MIT license, I assume no liability for any damage to you or any other person or equipment.
If you are prone to photosensitive epilepsy, we recommended you do **not** use this software.
If you still want to try, don't use strobe, lighting or noise modes or high effect speed settings.
As per the EUPL license, I assume no liability for any damage to you or any other person or equipment.
// We can avoid reporting if the change is insignificant. The threshold chosen is below the level of accuracy, but way above 0.01 which is the precision of the value provided.
// The AHT10/15/20 has an accuracy of 0.3C in the temperature readings
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
JsonObjecttop=root[FPSTR(_name)];
if(top.isNull()){
DEBUG_PRINT(F(_name));
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
Hello! I have written a v2 usermod for the BME280/BMP280 sensor based on the [existing v1 usermod](https://github.com/Aircoookie/WLED/blob/master/usermods/Wemos_D1_mini%2BWemos32_mini_shield/usermod_bme280.cpp). It is not just a refactor, there are many changes which I made to fit my use case, and I hope they will fit the use cases of others as well! Most notably, this usermod is *just* for the BME280 and does not control a display like in the v1 usermod designed for the WeMos shield.
# Usermod BME280
This Usermod is designed to read a `BME280` or `BMP280` sensor and output the following:
- Temperature
- Humidity (`BME280` only)
- Pressure
- Heat Index (`BME280` only)
- Dew Point (`BME280` only)
- Requires libraries `BME280@~3.0.0` (by [finitespace](https://github.com/finitespace/BME280)) and `Wire`. Please add these under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
-Data is published over MQTT so make sure you've enabled the MQTT sync interface.
- This usermod also writes to serial (GPIO1 on ESP8266). Please make sure nothing else listening on the serial TX pin of your board will get confused by log messages!
Configuration is performed via the Usermod menu. There are no parameters to set in code! The following settings can be configured in the Usermod Menu:
-The i2c address in decimal. Set it to either 118 (0x76, the default) or 119 (0x77).
- Temperature Decimals (number of decimal places to output)
- Humidity Decimals
- Pressure Decimals
- Temperature Interval (how many seconds between temperature and humidity measurements)
- Pressure Interval
- Publish Always (turn off to only publish changes, on to publish whether or not value changed)
- Use Celsius (turn off to use Fahrenheit)
- Home Assistant Discovery (turn on to sent MQTT Discovery entries for Home Assistant)
- SCL/SDA GPIO Pins
To enable, compile with `USERMOD_BME280` defined (i.e. `platformio_override.ini`)
- Data is published over MQTT - make sure you've enabled the MQTT sync interface.
- This usermod also writes to serial (GPIO1 on ESP8266). Please make sure nothing else is listening to the serial TX pin or your board will get confused by log messages!
In addition to outputting via MQTT, you can read the values from the Info Screen on the dashboard page of the device's web interface.
Methods also exist to read the read/calculated values from other WLED modules through code.
-`getTemperatureC()`
-`getTemperatureF()`
-`getHumidity()`
-`getPressure()`
-`getDewPointC()`
-`getDewPointF()`
-`getHeatIndexC()`
-`getHeatIndexF()`
# Compiling
To enable, add `BME280_v2` to your `custom_usermods` (e.g. in `platformio_override.ini`)
- Temperature and pressure have separate intervals due to pressure not frequently changing at any constant altitude
- Adjustment of number of decimal places in published sensor values
- Separate adjustment for temperature, humidity and pressure values
- Values are rounded to the specified number of decimal places
- Pressure measured in units of hPa instead of Pa
- Calculation of heat index (apparent temperature) and dew point
- These, along with humidity measurements, are disabled if the sensor is a BMP280
- 16x oversampling of sensor during measurement
- Values are only published if they are different from the previous value
- Values are published on startup (continually until the MQTT broker acknowledges a successful publication)
Adjustments are made through preprocessor definitions at the start of the class definition.
MQTT topics are as follows:
# MQTT
MQTT topics are as follows (`<deviceTopic>` is set in MQTT section of Sync Setup menu):
Measurement type | MQTT topic
--- | ---
Temperature | `<deviceTopic>/temperature`
Humidity | `<deviceTopic>/humidity`
Pressure | `<deviceTopic>/pressure`
Heat index | `<deviceTopic>/heat_index`
Dew point | `<deviceTopic>/dew_point`
Dew point | `<deviceTopic>/dew_point`
If you are using Home Assistant, and `Home Assistant Discovery` is turned on, Home Assistant should automatically detect a new device, provided you have the MQTT integration installed. The device is separate from the main WLED device and will contain sensors for Pressure, Humidity, Temperature, Dew Point and Heat Index.
# Revision History
Jul 2022
- Added Home Assistant Discovery
- Added API interface to output data
- Removed compile-time variables
- Added usermod menu interface
- Added value outputs to info screen
- Updated `readme.md`
- Registered usermod
- Implemented PinManager for usermod
- Implemented reallocation of pins without reboot
Apr 2021
- Added `Publish Always` option
Dec 2020
- Ported to V2 Usermod format
- Customizable `measure intervals`
- Customizable number of `decimal places` in published sensor values
- Pressure measured in units of hPa instead of Pa
- Calculation of heat index (apparent temperature) and dew point
-`16x oversampling` of sensor during measurement
- Values only published if they are different from the previous value
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.