Compare commits

..

233 Commits

Author SHA1 Message Date
Frank Möhle 1795797e0e Merge branch 'main' into remove-v1-usermod 2026-05-29 15:01:16 +02:00
Copilot 58bf4c83e9 add secure coding guides for AI reviews (#5572)
Added security review guidelines and a short checklist covering critical security areas including buffer safety, input validation, authentication, secure defaults, and protection against common vulnerabilities. Refined rule wording and priorities to better fit WLED’s technical constraints and realistic deployment model.

The lists are based on the OWASP "top 10" from https://github.com/github/awesome-copilot/blob/main/instructions/security-and-owasp.instructions.md, and on lessons learned from past reviews.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-05-29 13:59:35 +02:00
Frank 69c2b2d5c2 human-readable wifi events (WLED_DEBUG)
added some missing event names.
2026-05-27 23:55:23 +02:00
Frank 830f5df465 extra debug info for wifi disconnect / teardown / setTxPower
should help with debugging connection problems.
2026-05-27 23:25:43 +02:00
Frank ce249aef64 small addition to anti-slop rules
AI tools often delete code, remove comments, revert recent changes, or modify files that are out-of-scope w.r.t. the PR objectives.
2026-05-27 20:37:34 +02:00
Will Miles ff97ad5fe0 Merge pull request #5644 from DedeHai/overridesample_fixes
change -D USERMOD_x to custom_usermods = xxx
2026-05-26 16:13:51 -04:00
Frank 68b61f0831 adding coderabbit checks for typical AI slop 2026-05-25 22:17:08 +02:00
Frank 6cdf650535 update usermod guidelines, update example with "be nice but not too nice" pattern 2026-05-25 21:38:03 +02:00
Frank 0a0800d98d move some generic AI rules from copilot-instructions.md to AGENTS.md 2026-05-25 21:37:18 +02:00
Frank Möhle 0f34973ee5 Remove 'V5_C6' from the list of base branches
the V5-C6 branch will be merged back into V5 soon.
2026-05-23 23:39:56 +02:00
Will Tatam 72aee0680c Fix revert button #5574 2026-05-23 19:34:16 +01:00
Will Miles 86db5010f8 Merge pull request #5638 from willmmiles/devcontainer-completeness
Update devcontainer spec
2026-05-23 14:28:53 -04:00
Frank Möhle 584f9aba16 Document branch and release structure in AGENTS.md
Added branch and release structure information to AGENTS.md.
2026-05-23 15:00:25 +02:00
Frank Möhle 5aa41c49bd clarify scope of agents.md
Introduction added
2026-05-23 14:49:47 +02:00
Damian Schneider cc26179e56 change -D USERMOD_x to custom_usermods = 2026-05-23 09:30:56 +02:00
Damian Schneider 6ae22c9eb4 Merge pull request #5635 from DedeHai/twinkleFX_fixes
Make twinkle FX look more like it was in the past
2026-05-22 07:53:28 +02:00
Damian Schneider 33e6aee880 add inverse gamma for original looks 2026-05-22 07:52:05 +02:00
Frank Möhle 67f654e99c Update AGENTS.md with ESP32 task synchronization guidelines
* Added guidelines for ESP32 task synchronization
* Clarified that PRs must not create file listed in `.gitignore`
2026-05-21 21:55:28 +02:00
Will Miles decfad483a Update devcontainer spec 2026-05-20 21:40:06 +00:00
Frank 1ec2579f0d coding guides: clatify how to check for PSRAM
psramFound() alone is not definite -> nust also check that PSRAM size > 0 to be sure

https://github.com/wled/WLED/issues/5629#issuecomment-4497230168
2026-05-20 12:38:03 +02:00
Damian Schneider 2d3c8c9920 Merge pull request #5631 from DedeHai/PSRAM_fallback
use DRAM as fallback if PSRAM fails
2026-05-20 08:36:29 +02:00
Damian Schneider 1046de21a9 Make twinkle FX look more like it was in the past 2026-05-20 08:35:11 +02:00
Damian Schneider b7f9f71568 use DRAM as fallback if PSRAM fails 2026-05-19 17:24:09 +02:00
Frank f68f91d2c9 fix esp32s3_4M_none buildenv
tasmota core does not support "dio" mode on S3
2026-05-19 12:43:48 +02:00
Frank Möhle 59898a9b8f Add esp32s3dev_8MB_none to platformio_release.ini.template 2026-05-19 12:20:08 +02:00
Frank Möhle 3d864b178d Add new environments for ESP32-S3 without PSRAM
esp32s3_8MB_none, esp32s3_4M_none
2026-05-19 12:07:34 +02:00
Frank Möhle 6186e32814 Add PSRAM guidelines to AGENTS.md
Added PSRAM guidelines including availability checks, DMA compatibility, fragmentation considerations, and performance recommendations.
2026-05-19 01:23:38 +02:00
Frank Möhle 372577cb3d Update PSRAM guidelines in esp-idf instructions
Clarify PSRAM availability check instructions and usage.
2026-05-19 01:07:03 +02:00
Frank Möhle 0a190271e5 Revise bug report template instructions
Updated bug report template to discourage AI-generated error analyses.
2026-05-16 21:15:27 +02:00
Logan Davis d337c8a313 Fix KIT-VE PHY address from 0 to 1 (#5618) 2026-05-16 07:33:37 +02:00
Frank Möhle 91bcfc14ad Audioreactive bugfix: auto-suspend in all realtime modes, but stay active when "Use main segment only" (#5599)
* fixes a minor problem with newer realtime modes (DDP, TPM2NET and DMX) not causing auto-suspend of sound processing.
* ensure that AR audio stays active when "Use main segment only" (other segments are still controlled locally)
* small update for better compatibility with V5 builds
2026-05-15 20:59:44 +02:00
Will Miles 42f4bcb8a9 Merge pull request #5573 from smitty078/boot-preset-handling
Apply boot preset in setup() so it's guaranteed to be active before the first frame is rendered.
2026-05-14 21:43:09 -04:00
smitty078 8e501d9c91 Do not reassign callMode, revert whitespace error 2026-05-13 16:20:51 -04:00
Damian Schneider 0f30c54ca6 less restrictive DDP header acceptance, add safety checks to all protocols (#5547)
* less restrictive DDP header acceptance, add safety checks to all protocols

* another check for malformed packet

* clamp dmxChannels to MAX_CHANNELS_PER_UNIVERSE

* bugfix in data length calculation

* bugfix in parsePacket(): accept short artned packets
2026-05-13 19:19:05 +02:00
smitty078 741037a242 Fix missing semi-colon and another error. Thanks coderabbit 2026-05-12 23:21:10 -04:00
smitty078 f5ef3f91ce Final conflict resolution 2026-05-12 23:05:52 -04:00
redpandadev a1a22ec7b1 Merge branch 'wled:main' into boot-preset-handling-new 2026-05-12 22:50:54 -04:00
smitty078 6641724616 Consistency check to eliminate unneccesary conflicts 2026-05-12 22:47:56 -04:00
smitty078 722d6e8cdc Numerous changes based on conversation 2026-05-12 22:46:41 -04:00
Frank Möhle 8e94cf5bc4 Merge pull request #5608 from wled/softhack007-patch-1
Add sanity checks for ethernet config table and WLED_ETH_DEFAULT
2026-05-12 13:56:38 +02:00
Frank Möhle e6458922e1 Add sanity checks for ethernet config table and WLED_ETH_DEFAULT
Small helper for integrators by compile-time sanity checks:
* WLED_NUM_ETH_TYPES is aligned with the boards table
* WLED_ETH_DEFAULT is aligned with the boards table

-> can be merged into 17.0.0, 16.0.0, and 0.15.x branch
2026-05-12 13:43:47 +02:00
Joeboyc2 4ba60a606f fix(Fix_unreachable_netservices_v2): v16 compatibility fixes (#5590)
Two issues prevented this usermod from building under v16:

1. library.json is missing "build": {"libArchive": false}, causing the
   build system to reject it with an error before compilation begins.

2. serializeConfig() no longer has a no-argument overload in v16; the
   working replacement is serializeConfigToFS() which creates the JSON
   document internally and writes to the filesystem.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 11:29:01 +02:00
recliq f58187e579 Fixed top-LED update logic in grav* audioreactive effects (#5602)
Fix topLED fallrate not responding to "Rate of fall" slider.
2026-05-11 19:44:39 +02:00
smitty078 8793db356f revert whitespace correction to avoid conflicts with other PRs 2026-05-11 12:56:38 -04:00
redpandadev b185a0216d Merge branch 'wled:main' into boot-preset-handling 2026-05-10 22:16:16 -04:00
Frank Möhle 560eb3763a Update accessibility section in web instructions
Clarify target browser/platform combinations for WLED web UI.
2026-05-10 19:38:19 +02:00
Frank Möhle 6531a0804d Add accessibility guidelines for WLED web UI
Added section on accessibility and interaction for the WLED web UI.
2026-05-10 19:02:28 +02:00
Frank Möhle d5eb95028e coderabbit: Add base branches to auto_review configuration 2026-05-10 14:45:49 +02:00
Will Tatam 37623edfc1 docs: clarify when usermod IDs are required
Add explicit guidance explaining that a unique USERMOD_ID_* is only
needed when a usermod uses inter-mod communication, pin ownership via
pinManager, or needs to be identifiable in JSON info output. Updates
both AGENTS.md and the const.h comment block to reflect this.
2026-05-09 10:26:10 +01:00
Will Tatam 34a35d02a5 Remove usermods from release 2026-05-09 10:26:10 +01:00
smitty078 cfe7bad45d call releaseJSONBufferLock() before returning so that the JSON buffer doesn't get accidentally locked during setup 2026-05-09 00:01:29 -04:00
smitty078 0cd709723a Changes to implementation based on discussion. 2026-05-08 23:02:16 -04:00
Frank Möhle aa6e719129 Disable favicon test case temporarily
Comment out the favicon test case due to failures and potential regression.
2026-05-08 18:47:56 +02:00
Frank 979c724c91 repair CI test jdata.js
* fix two wrong target files for changes
* slightly increase wait times (for slower FS writes on windows)
* added a new testcase for changes to common.js
2026-05-08 18:34:50 +02:00
Will Tatam 665d66f45e Merge pull request #5577 from wled/copilot/esp02-confirm-smallest-bin
Add esp8266_2m_min: minimal ESP02 build for OTA recovery
2026-05-07 20:35:24 +01:00
Will Tatam 367d64f41f no need to build esp8266_2m_min for PRs 2026-05-07 20:32:20 +01:00
copilot-swe-agent[bot] 59c5991d2d Add esp8266_2m_min minimal build env for ESP02 OTA recovery
Agent-Logs-Url: https://github.com/wled/WLED/sessions/9d593605-e26a-4bea-b5dd-913d174d5942

Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2026-05-07 17:13:37 +00:00
copilot-swe-agent[bot] 8935997228 Initial plan 2026-05-07 17:08:32 +00:00
redpandadev c8f50e6f5a Add TODO for boot preset and playlist scenarios
Add TODO comments for handling boot presets and playlists.
2026-05-07 10:24:24 -04:00
redpandadev 83065c15ae Initial implementation to apply the same improvements to boot playlist
TODO:

set up logic handling inside handlePresets() and anywhere else required to implement behavior that is described in comments here.
2026-05-07 10:18:22 -04:00
redpandadev 88994e95be Merge branch 'wled:main' into boot-preset-handling 2026-05-07 02:37:15 -04:00
smitty078 f0e182bd29 Fix boot preset live data override handling 2026-05-07 02:33:12 -04:00
Will Tatam c05097351d Merge pull request #5561 from netmindz/auto-ota
Automatically download the right bin for the latest release and install
2026-05-05 17:55:35 +01:00
Will Tatam 57cca612db Change 'Latest release' to 'Latest version' in update.htm 2026-05-05 17:49:07 +01:00
Frank Möhle 8204e1bafe Add guideline for providing verifiable citations
Anti-hallucination rule: Emphasize the importance of providing verifiable citations in analyses or recommendations.
2026-05-05 14:48:55 +02:00
Will Tatam 8039b71b76 Improve update page UX and rename OTA button for consistency
- Release name on update page links directly to the matching bin on download.wled.me
- Badge links to GitHub releases page as 'View latest'
- Auto-update button renamed to 'Auto update'
- Manual upload section gets its own subheading; submit button renamed to 'Upload'
- 'Manual OTA Update' button in security settings renamed to 'Update WLED' to match info menu wording
2026-05-04 12:15:36 +01:00
Will Tatam 1edfc81259 Automatically download the right bin for the latest release and install 2026-05-04 11:21:09 +01:00
Will Tatam e321514e4f Update changelog generator to use tag v16.0.0 2026-05-03 22:56:54 +01:00
BobLoeffler68 b0b9fc58da Fixes issue in Dissolve when a palette has same color pixel as the current background color when Complete is enabled (#5453)
* Fixes issue in Dissolve when a palette has same color pixel as the current background color when Complete mode is enabled

---------

Co-authored-by: Damian Schneider <daedae@gmx.ch>
2026-05-03 21:27:53 +02:00
Will Tatam 360333c022 Merge pull request #5557 from DedeHai/settings_maxwidth
Add max-width to settings overview page
2026-05-03 18:57:57 +01:00
Will Tatam 0b7f77b2f7 Merge pull request #5553 from intermittech/add-quinled-v4-ethernet-profiles
Add Ethernet profiles for QuinLED Dig-Uno/Quad v4 and Dig-Octa 32-8L v4
2026-05-03 18:54:30 +01:00
Will Tatam 05959f94a8 Fix formatting of WLED_ETH_QUINLED_V4 defines 2026-05-03 18:45:13 +01:00
Will Tatam 3e085024a0 Merge pull request #5558 from netmindz/hub75-release
ci: build HUB75 envs in release workflow
2026-05-03 18:42:56 +01:00
Will Tatam bef897f679 Merge pull request #5548 from DedeHai/custom_and_AR_palettefix
Adding usermod palettes and fix UI palette display
2026-05-03 18:42:16 +01:00
Will Tatam dba7fcaaff Merge pull request #5550 from willmmiles/fw-validation-gzip
Validate gzipped firmware (on ESP8266)
2026-05-03 18:40:37 +01:00
Will Tatam 8aa5501571 Fix AudioReactive palette names to avoid duplication with usermod prefix
Since the display format is now "UMName: palName", shorten the palette
names to just "Ratio", "Hue", and "Spectrum" — rendering as
"AudioReactive: Ratio" etc. rather than "AudioReactive: Audio Responsive Ratio".
2026-05-03 14:27:08 +01:00
Will Tatam 41fd877adb Use usermod name prefix for usermod-supplied palette names
Palette display names now follow the format "UMName: palName" (e.g.
"AudioReactive: Audio Responsive Hue") when a usermod supplies a
specific palName, keeping the usermod name as a consistent prefix.
Fallback when palName is nullptr remains "UMName index".

Update AudioReactive palette names to the full descriptive names from
the original WLED-MM port: "Audio Responsive Ratio", "Audio Responsive
Hue", and "Audio Responsive Spectrum".
2026-05-03 14:24:27 +01:00
Will Tatam d66258f53b Merge pull request #5514 from wled/ar-network-only
Fix incomplete support for Audio Source - Network only - 8266 Audio Reactive
2026-05-03 14:04:30 +01:00
Will Tatam aaf76cc4d6 Merge branch 'main' into ar-network-only 2026-05-03 13:48:20 +01:00
Will Tatam 7872c633f3 Add name to usermod palette 2026-05-03 13:40:31 +01:00
Will Tatam ccd40e1f27 move platformio_release.ini.template to .github/ for cleaner project root 2026-05-03 13:02:30 +01:00
Will Tatam d466cab664 Skip GPIO validation for HUB75 types in pin checks and clarify slot usage in getNumberOfPins logic 2026-05-03 12:50:38 +01:00
Will Tatam c74b988c90 Update platformio configurations for 16MB ESP32-S3 MoonHub (HUB75) board 2026-05-03 12:48:31 +01:00
Will Tatam fe14c3104b Add support for HD-WF2 ESP32-S3 (HUB75 without PSRAM) 2026-05-03 12:47:23 +01:00
Dag Liodden 47af19519f Update and improve INA226 usermod (#5483)
* Make INA226 usermod configurable with build args

Update INA226 default check interval to 1 second

Initialize all INA226 bit fields in constructor

_settingEnabled was uninitialized, defaulting to false for static
objects, which silently disabled the usermod. Default it to true
and explicitly initialize all other bit fields.

Add more serial debug output to INA226 usermod

Log configuration parameters and operating mode on init, and
print each measurement reading to serial when WLED_DEBUG is enabled.

Show shunt voltage drop in mV instead of V

With low-value shunt resistors the voltage drop rounds to 0.00V.
Read in mV, rename label to "Shunt Voltage Drop", and update the
MQTT topic and HA discovery accordingly.

Add units to INA226 config UI and support decimal mΩ shunt values

Add appendConfigData() to show units (seconds, mΩ, mA, μs, etc.)
next to each config field. Store ShuntResistor as float milliohms
so values like 4.8 mΩ can be entered directly. Old integer configs
remain backward compatible.

USe uint32_t for checkIntervalMs to avoid overflow

Add basic config validation for INA226

Shift conversion time into 12-bit field. This _actually_ doesn't matter
as we always init the struct later.

Make INA226 enabled by default be a build flag

Revert to backwards compatible MQTT topic

Increae check frequency to 1/s

* Make check interval default configurable with build flag

* Fix old typo in MQTT guard

* Exmplicit floats

* Remove legacy usermod flag

* Replace magic number and repeated code with a lambda
2026-05-03 08:17:39 +02:00
Will Tatam aea18fa87b fix(ui): derive hasPSRAM from psrSz capability, not free bytes
Free PSRAM (info.psram) can be transiently 0 on PSRAM-capable boards,
which would wrongly reject multi-panel HUB75 setups in the LED settings
validation. Prefer info.psrSz (total PSRAM size) and fall back to
info.psram only if psrSz is unavailable.

Suggested in PR #5558 review.
2026-05-02 15:10:24 +01:00
Will Tatam e0b0b2a475 Relax panel limit for devices with PSRAM 2026-05-02 14:59:56 +01:00
Will Tatam 93e3e2ed02 ci: build HUB75 envs in release workflow
Move the four HUB75 envs from platformio_override.sample.ini into
platformio.ini (refactored with a shared [hub75] section and extends=
to deduplicate), and gate them behind a release-only config template
so nightly/PR CI keep building only the standard env matrix.

The release workflow now copies platformio_release.ini.template into
place, which extends default_envs with the HUB75 envs.
2026-05-02 14:00:13 +01:00
Will Tatam d00dbacca6 Merge pull request #5544 from netmindz/platformio-de-duplication
refactor platformio.ini to eliminate copy-paste duplication
2026-05-02 13:23:48 +01:00
Will Tatam 988254bb9f Move ESP8266 platform definitions from [common] to [esp8266]
Per review feedback: platform_wled_default, platform_packages, and the
arduino_core_* aliases are ESP8266-specific and don't belong in [common].
Note: this is a breaking change for custom platformio_override.ini files
that reference ${common.platform_wled_default} or ${common.platform_packages};
those should be updated to use the ${esp8266.*} prefix.
2026-05-02 13:16:23 +01:00
Will Tatam dd397fe673 Merge pull request #5546 from netmindz/node24
ci: opt into Node.js 24 for GitHub Actions runners
2026-05-02 13:08:08 +01:00
Will Tatam 7c57de901d Merge pull request #5545 from netmindz/pr-asset-naming
Name CI artifacts by WLED_RELEASE_NAME instead of PlatformIO env
2026-05-02 13:04:42 +01:00
Damian Schneider a4359fa57f align settings overview page width with rest of config pages 2026-05-02 08:05:38 +02:00
Intermittent Technology / QuinLED.info 0c3ff97e16 Merge branch 'main' into add-quinled-v4-ethernet-profiles 2026-05-01 22:39:50 +02:00
intermittech a871f110f5 On branch add-quinled-v4-ethernet-profiles
Changes to be committed:
	modified:   wled00/data/settings_wifi.htm
	modified:   wled00/network.cpp
2026-05-01 22:36:15 +02:00
Damian Schneider 49f653c621 auto-migration for sunrise/sunset legacy config (#5555)
* add auto-migration for sunris/sunset legacy config
2026-05-01 14:43:15 +02:00
Damian Schneider 64d57f51d5 bump VERSION 2026-05-01 13:58:32 +02:00
Intermittent Technology / QuinLED.info eaffac61c9 Update wled00/const.h
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-05-01 02:05:55 +02:00
intermittech 0466daa552 Add Ethernet profiles for QuinLED Dig-Uno/Quad v4 and Dig-Octa 32-8L v4 2026-04-30 22:38:15 +02:00
Frank Möhle 88032d5e4b Fix typo
Corrected a typo in the word 'architecture'.
2026-04-29 21:15:13 +02:00
Frank Möhle 9161672b43 Update documentation on docs/ folder usage
Clarified purpose of the `docs/` folder for developer information.
2026-04-29 21:13:55 +02:00
Will Miles 45cdfde61a Validate gzipped firmware on ESP8266
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 22:02:06 -04:00
Damian Schneider 120da32d69 remove unneeded check 2026-04-26 22:42:07 +02:00
Damian Schneider eb60ff91e4 fix typo 2026-04-26 22:35:12 +02:00
Damian Schneider 449069a344 rename removeUsermodPalettes 2026-04-26 22:32:18 +02:00
Damian Schneider d7d4e7dfb4 apply default pal before bounds check 2026-04-26 22:25:47 +02:00
Damian Schneider f16ca9c8ae rename and bugfixes 2026-04-26 22:22:04 +02:00
Will Tatam 5f219e60b8 ci: opt into Node.js 24 for GitHub Actions runners
Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true across all affected workflows
to avoid deprecation warnings ahead of the June 2026 forced migration.
2026-04-26 10:33:06 +01:00
Will Tatam 18a9986d1d Relax artifact name regex to support forks with different project names 2026-04-26 10:30:18 +01:00
Will Tatam 7a71efe916 Name CI artifacts by WLED_RELEASE_NAME instead of PlatformIO env
PR build artifact zips are now named firmware-<RELEASE_NAME> (e.g.
firmware-ESP32.zip) rather than firmware-<pio_env> (e.g.
firmware-esp32dev.zip), making it easier for users to identify the
correct build when testing PRs.
2026-04-26 10:26:53 +01:00
Will Tatam a535c56b4d Fix the build time estimate 2026-04-26 10:17:06 +01:00
Will Tatam e37707d520 refactor platformio.ini to eliminate copy-paste duplication
Centralise platform, platform_packages, build_unflags, lib_deps and
monitor_filters into the per-chipset abstract sections ([esp8266],
[esp32], [esp32s2], [esp32c3], [esp32s3]) and have concrete envs
inherit via extends rather than repeating the same values.

- [esp8266]: add platform, platform_packages, monitor_filters
- [esp32]: add monitor_filters
- [esp32s2]: add monitor_filters
- [esp32c3]: add monitor_filters
- [esp32s3]: add upload_speed, monitor_filters
- esp8266 envs (nodemcuv2, esp8266_2m, esp01_1m_full): extends = esp8266
- esp32dev: extends = esp32
- esp32dev_8M, esp32dev_16M: extends = env:esp32dev
- esp32_eth, usermods: extends = esp32 / env:esp32dev
- esp32_wrover: drop redundant build_unflags, lib_deps (already extends esp32_idf_V4)
- esp32c3dev: drop redundant platform, platform_packages, framework,
  build_unflags, lib_deps, board_build.partitions (already extends esp32c3)
- esp32s3 envs: extends = esp32s3
- lolin_s2_mini: extends = esp32s2

No functional changes. Verified with pio run across all five chipset
families (ESP8266, ESP32, C3, S3, S2).
2026-04-26 10:11:33 +01:00
Damian Schneider fd6f568023 add usermod palettes to fix AR palette indexing 2026-04-26 11:11:14 +02:00
Damian Schneider 02e593da0b move pixelforge json list and cpt city palettes to wled repo (#5541)
also removed commented code
2026-04-26 10:41:06 +02:00
Damian Schneider e8d481720a fix refresh of custom palettes 2026-04-26 09:29:10 +02:00
Damian Schneider f4f4978eeb add placeholder to keep custom palette ID's consistent (#5537) 2026-04-25 20:15:27 +02:00
Damian Schneider 49a63fc15e cleanup of PR #5503: remove unnecessary changes (#5536) 2026-04-25 20:08:37 +02:00
Will Tatam 1bc71f2352 Merge pull request #5503 from RobertoD91/main
fix for serial port on esp32 (#5501)
2026-04-25 17:12:39 +01:00
Will Tatam 70b0aeac95 Merge pull request #5473 from DedeHai/pin_dropdowns
Use drop-downs for pins
2026-04-25 17:08:22 +01:00
Damian Schneider d20dbeb204 fix indentation 2026-04-22 09:56:57 +02:00
Brandon502 69d494ad40 GoL missing return. (#5523) 2026-04-22 06:11:59 +02:00
copilot-swe-agent[bot] 8aa4beeaea Refactor AR init debug logging for network-only sentinel
Agent-Logs-Url: https://github.com/wled/WLED/sessions/85b2a158-f6ba-45cf-88af-0d51b9202cab

Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2026-04-21 07:55:17 +00:00
copilot-swe-agent[bot] 012fbdd6e9 Fix network-only dmType handling and debug diagnostics
Agent-Logs-Url: https://github.com/wled/WLED/sessions/85b2a158-f6ba-45cf-88af-0d51b9202cab

Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2026-04-21 07:50:57 +00:00
Damian Schneider 01328a65c1 Fix blending style options list filter for iOS (#5513)
* fix blending style options list filter for iOS
* fix default fallback
2026-04-20 19:06:33 +02:00
Damian Schneider a2d970e155 better packet queuing & pacing for custom palette live preview (#5515)
* better packet queuing / pacing for custom palette live preview
* fix leak
* remove window prefix from variables
2026-04-20 18:58:09 +02:00
Frank Möhle cb666cedc5 Highlight target branch for pull requests
Emphasize the importance of targeting the main branch for PRs.
2026-04-20 15:23:06 +02:00
Frank Möhle 5e0a0a7561 Update rules for PR descriptions and change logs
Added a guideline to prevent agents from overwriting PR descriptions (see https://github.com/orgs/community/discussions/187027).
2026-04-20 14:19:21 +02:00
Frank Möhle 3af2ae5f2f Merge pull request #5516 from kilrah/fix_dmx_ident
Add identifier string for DMX realtime mode
2026-04-19 18:36:25 +02:00
Kilrah 259bf3c0f8 Add identifier string for DMX realtime mode
(cherry picked from commit b4ae421fc3)
2026-04-18 16:47:06 +02:00
Will Tatam 2481aab860 Clean up redundant preprocessor directive in audio_reactive.cpp 2026-04-18 08:55:01 +01:00
Will Tatam ac96ee7568 Add audioreactive custom_usermod to multiple ESP8266 environments in platformio.ini now that we support network only option for 8266 2026-04-18 08:31:36 +01:00
Will Tatam 2b32918db0 Enhance audio reactive logic with improved input validation and new "network receive only" option. 2026-04-18 08:30:50 +01:00
Damian Schneider 5e49a1cffb bugfixes in PS effects
- fix PS Sparkler for large setups: need 32bit random position, 16bit is not enough
- fix PS Fireworks 1D: need to `break` if no particles are available or it can lead to stalls on large setups
- do not use collisions by default PS Fuzzy Noise: its very slow on larger setups
2026-04-17 15:26:57 +02:00
Damian Schneider 910caae463 use fast path in blendSegment to bump up FPS (#5464)
* use fast path in blendSegment to bump up FPS
2026-04-16 07:45:00 +02:00
Will Miles 35ce05a73b Merge pull request #5502 from willmmiles/dynarray-fixes
Dynarray fixes - fixes usermods on C3s
2026-04-15 20:18:07 -04:00
Frank Möhle ba377d7c29 Disable docstrings and unit tests in .coderabbit.yaml
Disable docstring generation and unit tests in CodeRabbit configuration.
2026-04-13 23:12:01 +02:00
Roberto 1cce33e0d3 fix for serial port on esp32 (#5501) 2026-04-13 18:47:18 +02:00
Will Miles 6d7c1d0bbd Improve usermod validation warnings 2026-04-13 01:38:30 -04:00
Damian Schneider 96510614a3 mask out flag bits in DDP type for compatibility 2026-04-12 19:49:45 +02:00
Damian Schneider 1185886eab add search icon back(#5500) 2026-04-12 19:07:16 +02:00
Will Miles a94a3f7003 Fix up usermod validation again
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 11:38:23 -04:00
Will Miles 144f1f13a8 dynarray: Support ESP-IDF 2026-04-12 11:38:23 -04:00
Will Miles 5a7aa8d8a8 validate_modules: Improve performance
Use readelf instead of nm for great speed.
2026-04-12 11:38:23 -04:00
Will Miles 42b91f2122 Fix usermod count for LTO 2026-04-12 11:38:23 -04:00
Will Miles a966c41bc2 dynarray: Directly apply linker fix
Rather than append a linker file, we edit the upstream supplied ones to
add our section to the binaries.  Works better on all platforms.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-12 11:38:23 -04:00
Will Tatam 36ebcb50f7 Merge pull request #5493 from LordMike/patch-2
Refactor wled-tools discover_devices for deduplication and clarity
2026-04-12 08:15:24 +01:00
Frank Möhle 3149a80dcf Refine early return guard clause in error handling
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.
2026-04-12 00:21:48 +02:00
Frank Möhle bab31833f0 Update naming conventions in cpp.instructions.md
Add PascalCase convention for enum values.
2026-04-12 00:09:22 +02:00
Frank Möhle 48b0ba0643 Update AI markers and string storage recommendations
Clarified usage of AI markers and added advice on string storage for ESP platforms.
2026-04-11 23:58:30 +02:00
Frank Möhle 0198a614b9 Fix formatting of AI attribution instructions
markdown was wrong
2026-04-11 23:52:19 +02:00
Frank Möhle 14f2ca4223 Use same AI: comment as suggested in other agent instructions
Exact comment text
2026-04-11 23:50:53 +02:00
Will Tatam 7932a249e0 Add AGENTS.md 2026-04-11 11:35:20 +01:00
Will Miles 474e1fe2e5 Serialize fxdata without ArduinoJSON (#5461)
* Serialize fxdata without ArduinoJSON

Eliminates size limit.  Fixes #5458

* Fix off-by-one in fxdata serializer

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Remove declaration of removed function

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Factor out streaming JSON primitives

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 12:26:48 +02:00
Will Tatam 7aec31f039 Upload then add notes 2026-04-11 09:19:50 +01:00
Will Tatam e2dd6303ea Merge pull request #5465 from netmindz/usage-extended
New extended data for usage report
2026-04-11 08:20:09 +01:00
Will Tatam 7242e9d842 remove i2c and spi 2026-04-11 08:19:36 +01:00
Will Tatam ab0cde110f apply code review feedback 2026-04-11 08:16:10 +01:00
Frank Möhle c735feb90a Merge branch 'main' into usage-extended 2026-04-11 08:52:16 +02:00
Frank Möhle a6faf942f1 Revise AI transparency guidelines in CONTRIBUTING.md
Updated transparency guideline for AI-generated code comments.
2026-04-10 21:52:33 +02:00
Will Tatam 370e4c8e2f Merge pull request #5489 from wled/copilot/fix-wled-discovery-issues
Fix Alexa/Hue discovery by correcting SSDP response to match UPnP spec
2026-04-10 18:25:31 +01:00
Frank 8e90242e95 coderabbit tinkering
* disable poem
* disable docstring tool (confusing for users)
* don't review if title contains "WIP"
* auto-assign labels to the PR
2026-04-10 16:55:28 +02:00
Michael Bisbjerg 97dacb6a04 Undo space removals 2026-04-10 16:20:51 +02:00
Frank 061920bb9c adding an (exhaustive) reference guide for esp-idf
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.
2026-04-10 13:56:26 +02:00
Michael Bisbjerg 97704e08de Refactor discover_devices for deduplication and clarity
Refactor discover_devices function to deduplicate device entries and improve readability.
2026-04-10 12:08:42 +02:00
Frank Möhle a51aec6f19 Fix typo in pull request expectations section 2026-04-10 02:49:28 +02:00
Frank Möhle c21ed0714f Fix formatting of platformio.ini modification requirement 2026-04-10 02:44:15 +02:00
Frank Möhle a2dce56809 Update pull request expectations: approval needed to modify platformio.ini
Clarify approval requirement for modifications to platformio.ini
2026-04-10 02:43:40 +02:00
Frank Möhle 036f5199e5 Clean up PR review instructions in .coderabbit.yaml
Removed not working instructions for PR review practices.
2026-04-10 02:32:38 +02:00
Frank Möhle 1914e4ee3b Add reminder for clear pull request descriptions
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).
2026-04-09 18:46:30 +02:00
copilot-swe-agent[bot] 9c072ec921 fix: restore lost inline comments on CACHE-CONTROL and USN lines
Agent-Logs-Url: https://github.com/wled/WLED/sessions/545fc8ab-87c8-4cf5-aa9d-f99915b68beb

Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com>
2026-04-09 15:10:40 +00:00
Frank Möhle cf4dfe958e Update build instructions with comment preservation reminder
Added a reminder to preserve or update comments after modifying source code files.
2026-04-09 12:27:57 +02:00
copilot-swe-agent[bot] 2cccbd175c docs: improve EUI-64 bridge ID comment per code review
Agent-Logs-Url: https://github.com/wled/WLED/sessions/c3fb311b-1349-48b1-abfd-6a4aca8c7a77

Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
2026-04-09 05:57:45 +00:00
copilot-swe-agent[bot] cb61c4fe7d fix: improve Alexa/Hue discovery SSDP response compatibility
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>
2026-04-09 05:54:20 +00:00
copilot-swe-agent[bot] 4a0a4c632b Initial plan 2026-04-09 05:47:55 +00:00
Frank Möhle 5b2ae15d8d Update ESP32 options in bug issue template 2026-04-09 01:38:30 +02:00
Frank Möhle 44ddc21530 Update bug issue template with new options 2026-04-09 01:34:48 +02:00
Frank Möhle 063592c845 Refine PR review guidelines in .coderabbit.yaml
clarify "limit to top5"
a few typos fixed
2026-04-09 00:53:46 +02:00
Frank Möhle 4955af0a11 Limit suggested improvements to 'Top 5' in instructions
Updated the instructions to limit suggested improvements to 'Top 5' in multiple sections.
2026-04-09 00:43:19 +02:00
Frank Möhle 9df5d056b9 Remove redundancy in feedback guideline
the "summarize good practices" is now moved in .coderabbit.yaml. Removing it here to prevent "logic looping" and distraction.
2026-04-09 00:35:16 +02:00
Frank Möhle 3486e3bcbb Enhance PR review instructions in .coderabbit.yaml
Extend guidelines for PR reviews : including summarizing good practices and prioritizing improvements.
2026-04-09 00:25:09 +02:00
Frank Möhle 91eb69643d Enhance PR review guidelines in .coderabbit.yaml
Added guidelines for PR reviews and improvement suggestions.
2026-04-09 00:08:41 +02:00
Copilot 48b27d12ac docs: add canonical feature-flag list to copilot-instructions to catch misspellings (#5487)
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>
2026-04-08 23:05:12 +02:00
Frank Möhle 78c1051cbb hiding reference to contributing.md from AI
contributing.md makes reference out to this file again
2026-04-08 21:28:29 +02:00
Frank Möhle 2302863386 copilot-instructions rework, new C++ coding guide for AI reviews (#5480)
* 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>
2026-04-08 21:06:48 +02:00
Damian Schneider 7560811480 bugfix in pixelforge (no blur by default), fix glitch in animated gifs for C3 2026-04-07 23:29:31 +02:00
Frank Möhle 12f6fbc005 robustness: Rewind file pointer before writing initial data
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)
2026-04-05 22:11:00 +02:00
Will Miles c819814904 Merge pull request #5476 from willmmiles/ipv6-filter-oops
Fix leak in blockRouterAdvertisements
2026-04-04 21:10:55 -04:00
Will Miles 0ef5ee74d4 Fix leak in blockRouterAdvertisements 2026-04-04 15:50:22 -04:00
Damian Schneider 875711d38e allow "unused" as pin option 2026-04-04 18:16:01 +02:00
Damian Schneider 9b9474282d add note for clarification 2026-04-04 18:07:38 +02:00
Damian Schneider 1284aba5d0 add pin dropdowns for DMX input 2026-04-04 17:58:31 +02:00
Damian Schneider fa6fc4f0b6 cosmetics 2026-04-04 16:37:32 +02:00
Damian Schneider f7d9461d1c bugfixes 2026-04-04 16:20:54 +02:00
Frank Möhle 51862e3572 Update guidelines for AI-generated code and PR expectations
Based on new instructions in wled-mm. More to come in a separate  PR :-)
2026-04-04 10:23:22 +02:00
Damian Schneider 7153fd8fe4 remove default R/O, add comments 2026-04-03 16:51:07 +02:00
Will Tatam 35c1f415c3 Merge branch 'main' into usage-extended 2026-04-03 15:35:08 +01:00
Will Tatam cf03f1a16e Refactor hardware data mapping with structured arrays for LED features, peripherals, and integrations 2026-04-03 15:16:49 +01:00
Damian Schneider 5be517b519 use new common.js pin dropdown functions on UM page 2026-04-03 14:34:34 +02:00
Damian Schneider aaf51927a6 bugfix: do not restrict segment inputs to allow trailing strips 2026-04-03 14:21:50 +02:00
Damian Schneider 630533d125 fix pin checks for LED bus 2026-04-03 11:40:07 +02:00
Damian Schneider a78d39ff1e move pin fetching to common.js, fixes 2026-04-03 10:00:29 +02:00
Damian Schneider 7722faf9d7 revert all changes to usermod page 2026-04-03 09:41:57 +02:00
Damian Schneider 72a43c6431 hotfix: critical bug in candle FX, integer issue in flow FX 2026-04-02 18:44:19 +02:00
Frank Möhle 7c6828d443 Clarified links in the contribution guidelines to indicate they are part of AI instructions.
Clarified links in the contribution guidelines to indicate they are part of AI instructions.
2026-04-01 19:27:09 +02:00
Frank Möhle f8f46736ec Clarify IDE support in contributing guidelines
Updated contributing guidelines to specify that Arduino IDE is no longer supported and recommended using VSCode with PlatformIO.
2026-04-01 19:16:40 +02:00
Frank Möhle e4f8534cf0 Enhance CONTRIBUTING.md with developer resources
Added important developer information and links to CONTRIBUTING.md to assist contributors.
2026-04-01 19:12:18 +02:00
Frank Möhle 79ecffe0f3 own heading for usermods
Updated instructions for adding a new usermod.
2026-04-01 19:04:00 +02:00
Frank Möhle 1fb636d8ea Update section title for development workflow
small clarification (AI prompt micro-tuning)
2026-04-01 18:57:18 +02:00
Frank Möhle e04c855e6c grammar correction 2026-04-01 18:51:53 +02:00
Frank Möhle 6a627a86b7 Update usermod instructions in copilot documentation
Added instructions for adding new usermods and activating them.
2026-04-01 18:48:28 +02:00
Frank Möhle 746df24011 tiny edit 2026-04-01 18:33:19 +02:00
Frank Möhle da64f71ce2 repository structure clarifications 2026-04-01 18:32:10 +02:00
Frank Möhle 8972b6bfe2 Update repository structure
adding more details: wled00/src, lib/, usermods/
2026-04-01 18:22:04 +02:00
Will Tatam 8241468fe2 Merge pull request #5451 from wled/dependabot/pip/requests-2.33.0
Bump requests from 2.32.4 to 2.33.0
2026-04-01 08:43:55 +01:00
Will Tatam e9b740a915 Merge pull request #5454 from wled/dependabot/npm_and_yarn/brace-expansion-5.0.5
Bump brace-expansion from 5.0.3 to 5.0.5
2026-04-01 07:43:39 +01:00
Will Tatam 548bb6ffd5 Merge pull request #5449 from wled/dependabot/npm_and_yarn/picomatch-2.3.2
Bump picomatch from 2.3.1 to 2.3.2
2026-04-01 07:42:59 +01:00
Damian Schneider 964c8cee66 move pin info naming to common.js, update dropdown construction (WIP) 2026-03-31 19:35:06 +02:00
Damian Schneider 9d1f36c553 improvements, still not fully working 2026-03-31 19:03:22 +02:00
Damian Schneider ad921f031f initial implementation 2026-03-31 10:23:50 +02:00
Will Tatam 3d2fac0ad4 New extended data for usage report 2026-03-30 20:18:42 +01:00
Frank a5f28d0fcb fix for HUB75 builds
replaces the last remaining FastLED.h with fstled_slim.h
2026-03-30 11:40:58 +02:00
Frank Möhle fb8f8f0b08 Clarify 16_x branch description
Updated description of the 16_x branch for clarity.
We are not at "feature-freeze" yet
2026-03-30 02:34:43 +02:00
Frank Möhle 53fdf9a89c Update version numbers in copilot instructions 2026-03-30 01:39:44 +02:00
Frank Möhle a1316034c1 Fix typo in version tag comment 2026-03-30 01:38:20 +02:00
Frank Möhle 75df4affa8 moving stuff around 2026-03-30 01:35:59 +02:00
Frank Möhle 820c841376 add tag scheme information for old/historical versions 2026-03-30 01:28:18 +02:00
Frank Möhle 34d50710b3 Update copilot-instructions with branch structure overview
Added basic project branch and release structure section to AI information
2026-03-30 01:18:19 +02:00
Frank Möhle d0d62d9493 Clarify instructions to always use the correct source code branch
Updated instructions for providing references in analysis results.
2026-03-30 00:16:05 +02:00
Will Tatam 89b2bc2992 17.0.0-dev 2026-03-29 22:38:13 +01:00
dependabot[bot] e019d36221 Bump brace-expansion from 5.0.3 to 5.0.5
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.3 to 5.0.5.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.3...v5.0.5)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 5.0.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 00:59:09 +00:00
dependabot[bot] 3bcb0c902e Bump requests from 2.32.4 to 2.33.0
Bumps [requests](https://github.com/psf/requests) from 2.32.4 to 2.33.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.4...v2.33.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.33.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 16:33:00 +00:00
dependabot[bot] 75b679814b Bump picomatch from 2.3.1 to 2.3.2
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 22:25:54 +00:00
Will Tatam 0a21869362 Remove V1 usermod 2025-08-09 15:22:41 +01:00
54 changed files with 733 additions and 974 deletions
+2 -9
View File
@@ -33,13 +33,6 @@ reviews:
- V5
ignore_title_keywords:
- WIP
tools:
fbinfer:
enabled: false # Arduino.h not available on Linux analysis host
cppcheck:
enabled: true # cppcheck works fine without Arduino headers
clang:
enabled: true # clang tidy likewise works
path_instructions:
- path: "**/*.{cpp,h,hpp,ino}"
@@ -55,11 +48,11 @@ reviews:
NOT to effect functions in FX.cpp, which have diverse contributor styles.
When reviewing PRs labeled "AI" or when source code appears to be AI-generated, perform these additional checks:
1. VERIFY all referenced preprocessor macros, constants and flags exist by searching the codebase - do not trust the AI's claims about what exists.
1. VERIFY all referenced constants, flags, and functions exist by searching the codebase - do not trust the AI's claims about what exists.
2. CHECK for reinvention: search for existing functions/patterns that already solve the same problem.
3. CHECK for singleton data (defined but never used) and for dead/disabled code, and suggest to remove them.
4. VERIFY comments match code behavior - AI frequently generates plausible but incorrect comments.
5. VERIFY numerical stability / accuracy of arithmetic expressions. AI is often wrong when it comes to math and numbers.
5. VERIFY numerical stability / accuracy of fixed-point arithmetic.
6. CHECK for implied but weakly justified assumptions - like usermod loop() call frequency - and ask for clarification.
7. FLAG changes that appear unrelated: deleted comments, unnecessary re-formatting or re-factoring, and modifications in files that seem unrelated to the PR description.
+14
View File
@@ -0,0 +1,14 @@
{
"features": {
"ghcr.io/ar90n/devcontainer-features/platformio:1": {
"version": "1.0.2",
"resolved": "ghcr.io/ar90n/devcontainer-features/platformio@sha256:4a28f8c147d81ff996afebe6f43e453355b6373dd4022960351090b532ac9dd3",
"integrity": "sha256:4a28f8c147d81ff996afebe6f43e453355b6373dd4022960351090b532ac9dd3"
},
"ghcr.io/devcontainers/features/node:2": {
"version": "2.0.0",
"resolved": "ghcr.io/devcontainers/features/node@sha256:fedd4c11f7adfb64283b578dddc7da906728daa25fa293351c9d913231acf12f",
"integrity": "sha256:fedd4c11f7adfb64283b578dddc7da906728daa25fa293351c9d913231acf12f"
}
}
}
+9 -9
View File
@@ -1,11 +1,10 @@
{
"name": "Python 3",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9
"VARIANT": "3"
"name": "WLED-dev",
"image": "mcr.microsoft.com/devcontainers/python:3",
"features": {
"ghcr.io/ar90n/devcontainer-features/platformio:1": {},
"ghcr.io/devcontainers/features/node:2": {
"version": "v20.18.3"
}
},
@@ -43,7 +42,8 @@
},
"extensions": [
"ms-python.python",
"platformio.platformio-ide"
"platformio.platformio-ide",
"ms-vscode.cpptools-extension-pack"
]
}
},
@@ -52,7 +52,7 @@
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "bash -i -c 'nvm install && npm ci'",
"postCreateCommand": "",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
+7 -4
View File
@@ -5,7 +5,9 @@ body:
- type: markdown
attributes:
value: |
Please quickly search existing issues first before submitting a bug.
Please quickly search existing issues first before submitting a bug.
Please don't submit long error analyses created by an AI agent, these are often totally wrong.
Just describe the problem in your own words.
- type: textarea
id: what-happened
attributes:
@@ -59,12 +61,13 @@ body:
options:
- ESP8266
- ESP32
- ESP32-S3
- ESP32 with ethernet
- ESP32-S2
- ESP32-S3
- ESP32-C3
- Other
- ESP32-C6 (experimental)
- ESP32-C5 (experimental)
- ESP32-C6 (experimental)
- ESP32-P4 (experimental)
validations:
required: true
- type: textarea
+4 -4
View File
@@ -48,8 +48,9 @@ For detailed build timeouts, development workflows, troubleshooting, and validat
```text
main # Main development trunk (daily/nightly) 17.0.0-dev
├── V5 # special branch: code rework for esp-idf 5.5.x and new MCU types: esp32-c5, esp32-c6, esp32-p4 (unstable)
16_x # maintenance for release 16.x.y
├── 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)
@@ -58,8 +59,7 @@ main # Main development trunk (daily/nightly) 17.0.0-dev
<!-- HUMAN_ONLY_END -->
- ``main``: development trunk (daily/nightly)
- ``V5`` : code rework for esp-idf 5.5.x (unstable) - branched from ``main``.
- ``16_x``: maintenance for release 16.x.y
- ``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
### Repository Structure
-1
View File
@@ -43,4 +43,3 @@ default_envs = nodemcuv2
adafruit_matrixportal_esp32s3
esp32s3dev_16MB_opi_hub75 ;; MoonHub
esp32s3dev_4MB_qspi_hub75 ;; HD-WF2
waveshare_esp32s3_32MB_hub75
+2 -2
View File
@@ -29,12 +29,12 @@ jobs:
uses: janheinrichmerker/action-github-changelog-generator@v2.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
sinceTag: v0.15.0
sinceTag: v16.0.0
output: CHANGELOG_NIGHTLY.md
# Exclude issues that were closed without resolution from changelog
excludeLabels: 'stale,wontfix,duplicate,invalid,external,question,use-as-is,not_planned'
- name: Update Nightly Release
uses: andelf/nightly-release@5834076edc55cc05975561c9722043f072ac5c26
uses: andelf/nightly-release@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+14 -16
View File
@@ -17,8 +17,8 @@ Always reference these instructions - including coding guidelines in `docs/` - f
| `npm run build` | Build web UI into `wled00/html_*.h` / `wled00/js_*.h` | 30s |
| `npm test` | Run test suite (Node.js built-in `node --test`) | 2 min |
| `npm run dev` | Watch mode — auto-rebuilds web UI on changes | continuous |
| `pio run -e esp32dev` | Build firmware (ESP32, most common target) | 30 min |
| `pio run -e nodemcuv2` | Build firmware (ESP8266) | 30 min |
| `pio run -e esp32dev` | Build firmware (ESP32, most common target) | 5 min |
| `pio run -e nodemcuv2` | Build firmware (ESP8266) | 5 min |
**Always run `npm ci && npm run build` before `pio run`.** The web UI build generates
required C headers for firmware compilation.
@@ -68,7 +68,8 @@ docs/ # Coding convention docs
```text
main # Main development trunk (daily/nightly) 17.0.0-dev. Target branch for PRs.
├── V5 # special branch: code rework for esp-idf 5.5.x and new MCU types: esp32-c5, esp32-c6, esp32-p4 (unstable)
├── 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 # maintenance for release 16.0.x
0_15_x # maintenance (bugfixes only) for previous release 0.15.x
(tag) v0.14.4 # old version 0.14.4 (no maintenance)
@@ -162,7 +163,7 @@ Background Info:
- Use FreeRTOS mutexes, semaphores or queues when true concurrent access from multiple FreeRTOS tasks is possible, and race-conditions can lead to unexpected behaviour.
- **Avoid `portENTER_CRITICAL()` / `portEXIT_CRITICAL()`**, as these functions stall the complete system and may cause LEDs flickering. Prefer FreeRTOS mutexes, semaphores or queues.
- **Important**: Not every shared resource needs a mutex. Some synchronization is guaranteed by the overall control flow, for example when function calls are sequenced within the same loop iteration.
- Consider using `std::atomic` or RAII scoped guards as alternatives to mutexes, semaphores or queues.
- Consider RAII as an alternative to mutexes or semaphores.
## Web UI Code Style (wled00/data/)
@@ -197,10 +198,10 @@ REGISTER_USERMOD(myUsermod);
refer to detailed examples in `usermods/EXAMPLE/`, `usermods/user_fx/` and [in the user documentation for custom features](https://kno.wled.ge/advanced/custom-features/).
- Activate via `custom_usermods = ` in platformio build config. The `usermod_v2_` prefix or `_v2` suffix can be omitted.
- Base new usermods on `usermods/EXAMPLE/` (never edit the example directly)
- Store repeated strings as `static const char[] PROGMEM`
- Add usermod IDs to `wled00/const.h` **only when a unique ID is required** (see below)
### Usermod `loop()`
- Called once per main loop iteration. Usermods should simply `return` when `!enabled`.
- Frequency of calls varies with system load - up to 2000 times/sec with few LEDs and little background activity, down to 1-3 times/sec during FS activity or during high workload from effects and other usermods.
### Usermod IDs
@@ -212,13 +213,10 @@ A unique ID (registered in `wled00/const.h` and overriding `getId()`) is **only
If none of the above apply, the usermod may omit `getId()` (or return the default `USERMOD_ID_UNSPECIFIED`) and does **not** need an entry in `const.h`.
### Usermod `loop()`
- Called once per main loop iteration. Usermods should simply `return` when `!enabled`.
- Frequency of calls varies with system load:
* up to 2000 times/sec with few LEDs and little background activity,
* between 20 and 300 times/second during high workload from effects and other usermods,
* (worst case) down to 1-3 times/sec during FS activity or when serving lots of network API requests.
- Add usermod IDs to `wled00/const.h` **only when a unique ID is required** (see above)
- Activate via `custom_usermods` in platformio build config
- Base new usermods on `usermods/EXAMPLE/` (never edit the example directly)
- Store repeated strings as `static const char[] PROGMEM`
## CI/CD
@@ -232,7 +230,7 @@ No automated linting is configured. Match existing code style in files you edit.
## General Rules
- Important: Repository language is **English**. This applies to source code (including comments), commit messages and any kind of documentation for developer or users.
- Repository language is English.
- The `docs/` folder is for developer/contributor information (coding conventions, architecture, etc.). User documentation is maintained in the [wled/WLED-Docs](https://github.com/wled/WLED-Docs) repository.
- Never edit or commit auto-generated `wled00/html_*.h` / `wled00/js_*.h`.
- When updating an existing PR, retain the original description. Only modify it to ensure technical accuracy. Add change logs after the existing description.
+4 -2
View File
@@ -10,8 +10,8 @@ We'll work with you to refine your contribution, but we'll also push back if som
Here are a few suggestions to make it easier for you to contribute:
### Important Developer Infos
* [Project Structure, Files and Directories](AGENTS.md#project-structure) (in our AI instructions)
* [Instructions for creating usermods](AGENTS.md#usermod-pattern) (in our AI instructions)
* [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.
@@ -141,6 +141,8 @@ Sometimes you might hit merge conflicts with `main` that are harder to solve. He
### 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).
-2
View File
@@ -515,8 +515,6 @@ void myTask(void*) {
- **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).
- In C/C++, additive operators (`+`, `-`) have HIGHER precedence than shift operators (`<<`, `>>`). Therefore `x - edge0 << 8` correctly parses as `(x - edge0) << 8`. Do NOT flag this pattern as a precedence bug. When reviewing WLED fixed-point code or any C/C++ shift expressions, verify against cppreference before claiming precedence issues with mixed `-`/`+` and `<<`/`>>` expressions.
- **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:
```cpp
// Undefined behavior — avoid:
+4 -4
View File
@@ -193,7 +193,7 @@ On ESP32-S3 modules with OPI flash (e.g. N8R8 modules where the SPI flash itself
## Migrating from ESP-IDF v4.4.x to v5.x
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` branch (`https://github.com/wled/WLED/tree/V5`). Note: WLED has not yet migrated to IDF v5 — these patterns prepare for the future migration.
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
@@ -295,7 +295,7 @@ The new API is channel-based:
| `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` branch adds `-D WLED_USE_SHARED_RMT` and disables IR until the library is ported.
**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)
@@ -363,7 +363,7 @@ WLED already has a compatibility shim in `ota_update.cpp` that maps old names to
### Features disabled in IDF v5 builds
The upstream `V5` branch explicitly disables features with incompatible library dependencies:
The upstream `V5-C6` branch explicitly disables features with incompatible library dependencies:
```ini
# platformio.ini [esp32_idf_V5]
@@ -699,7 +699,7 @@ RMT drives NeoPixel LED output (via NeoPixelBus) and IR receiver input. Both use
### Migration notes
- The upstream `V5` branch uses `-D WLED_USE_SHARED_RMT` to switch to the new RMT driver for NeoPixel output.
- The upstream `V5-C6` branch uses `-D WLED_USE_SHARED_RMT` to switch to the new RMT driver for NeoPixel output.
- IR is disabled on IDF v5 until the IR library is ported.
- New chips (C6, P4) have different RMT channel counts — use `SOC_RMT_TX_CANDIDATES_PER_GROUP` to check availability.
- The new RMT API requires an "encoder" object (`rmt_encoder_t`) to translate data formats — this is more flexible but requires more setup code.
+1 -1
View File
@@ -68,6 +68,7 @@ De-prioritize unless explicitly introduced by a PR:
- Prefer bounded alternatives for string operations (`strnlen`, `strncmp`, `strncpy`, `strlcpy`, `snprintf`).
- Treat a finding against FW1 as **suggestion** only when the operation is provably bounded
and both the destination capacity and copied/compared length are known safe.
and both the destination capacity and copied/compared length are known safe.
### FW2: Format-string injection
- **Severity**: CRITICAL
@@ -86,7 +87,6 @@ De-prioritize unless explicitly introduced by a PR:
### FW5: Missing auth checks on state-changing endpoints (where auth is feasible)
- **Severity**: CRITICAL
- HTTP/JSON and other control paths that support auth must enforce configured auth policy.
- Do not flag the HTTP endpoint `/reset` as state-changing. This endpoint triggers a reboot, causing a short interruption without loss of user data.
- Do not flag standards-based UDP multicast/broadcast paths solely for lacking authentication when authentication is not defined in the protocol specification.
### FW6: Fail-open behavior after parse or allocation errors
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "wled",
"version": "16.0.1-dev",
"version": "17.0.0-dev",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wled",
"version": "16.0.1-dev",
"version": "17.0.0-dev",
"license": "ISC",
"dependencies": {
"clean-css": "^5.3.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wled",
"version": "16.0.1-dev",
"version": "17.0.0-dev",
"description": "Tools for WLED project",
"main": "tools/cdata.js",
"directories": {
+8 -2
View File
@@ -2,6 +2,7 @@
# This is implemented as a pio post-script to ensure that we can
# place our linker script at the correct point in the command arguments.
Import("env")
import shutil
from pathlib import Path
# Linker script fragment injected into the rodata output section of whichever
@@ -18,7 +19,13 @@ DYNARRAY_INJECTION = (
def inject_before_marker(path, marker):
"""Patch a linker script file in-place, inserting DYNARRAY_INJECTION before marker."""
original = path.read_text()
path.write_text(original.replace(marker, DYNARRAY_INJECTION + marker, 1))
marker_pos = original.find(marker)
if marker_pos < 0:
raise RuntimeError(
f"DYNARRAY injection marker not found in linker script: path={path}, marker={marker!r}"
)
patched = original[:marker_pos] + DYNARRAY_INJECTION + original[marker_pos:]
path.write_text(patched)
if env.get("PIOPLATFORM") == "espressif32":
@@ -38,7 +45,6 @@ if env.get("PIOPLATFORM") == "espressif32":
# leaves the ASSERTs satisfied.
build_dir = Path(env.subst("$BUILD_DIR"))
patched_path = build_dir / "dynarray_sections.ld"
import shutil
shutil.copy(sections_ld_path, patched_path)
inject_before_marker(patched_path, "_rodata_end = ABSOLUTE(.);")
+12 -5
View File
@@ -37,14 +37,14 @@ def check_elf_modules(elf_path: Path, env, module_lib_builders) -> set[str]:
Returns the set of build_dir basenames for confirmed modules.
"""
readelf_path = _get_readelf_path(env)
secho(f"INFO: Checking for usermod compilation units...")
try:
result = subprocess.run(
[readelf_path, "--debug-dump=info", "--dwarf-depth=1", str(elf_path)],
capture_output=True, text=True, errors="ignore", timeout=120,
)
output = result.stdout
if result.returncode != 0 or result.stderr.strip():
secho(f"WARNING: readelf exited {result.returncode}: {result.stderr.strip()}", fg="yellow", err=True)
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
secho(f"WARNING: readelf failed ({e}); skipping per-module validation", fg="yellow", err=True)
return {Path(b.build_dir).name for b in module_lib_builders} # conservative pass
@@ -143,20 +143,27 @@ def validate_map_file(source, target, env):
Exit(1)
# Identify the WLED module builders, set by load_usermods.py
module_lib_builders = env['WLED_MODULES']
module_lib_builders = env.get('WLED_MODULES')
if module_lib_builders is None:
secho("ERROR: WLED_MODULES not set — ensure load_usermods.py is run as a pre: script", fg="red", err=True)
Exit(1)
# Extract the values we care about
modules = {Path(builder.build_dir).name: builder.name for builder in module_lib_builders}
secho(f"INFO: {len(modules)} libraries linked as WLED optional/user modules")
secho(f"INFO: {len(modules)} libraries included as WLED optional/user modules")
# Now parse the map file
map_file_contents = read_lines(map_file_path)
usermod_object_count = count_usermod_objects(map_file_contents)
secho(f"INFO: {usermod_object_count} usermod object entries")
secho(f"INFO: {usermod_object_count} usermod object entries found")
elf_path = build_dir / env.subst("${PROGNAME}.elf")
confirmed_modules = check_elf_modules(elf_path, env, module_lib_builders)
if confirmed_modules:
secho(f"INFO: Code from usermod libraries found in binary: {', '.join(confirmed_modules)}")
# else - if there's no usermods found, don't generate a message. If we're legitimately missing all entries, the error report on the
# next line will trip; and if the usermod set is expected to be empty, then there's no need for yet another null message.
missing_modules = [modname for mdir, modname in modules.items() if mdir not in confirmed_modules]
if missing_modules:
+60 -159
View File
@@ -42,40 +42,6 @@ extra_configs =
platformio_release.ini
[common]
# ------------------------------------------------------------------------------
# PLATFORM:
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
#
# arduino core 2.6.3 = platformIO 2.3.2
# arduino core 2.7.0 = platformIO 2.5.0
# ------------------------------------------------------------------------------
arduino_core_2_6_3 = espressif8266@2.3.3
arduino_core_2_7_4 = espressif8266@2.6.2
arduino_core_3_0_0 = espressif8266@3.0.0
arduino_core_3_0_2 = espressif8266@3.2.0
arduino_core_3_1_0 = espressif8266@4.1.0
arduino_core_3_1_2 = espressif8266@4.2.1
# Development platforms
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
# Platform to use for ESP8266
platform_wled_default = ${common.arduino_core_3_1_2}
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
platform_packages = platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platformio/tool-esptool #@ ~1.413.0
platformio/tool-esptoolpy #@ ~1.30000.0
## previous platform for 8266, in case of problems with the new one
## you'll need makuna/NeoPixelBus@ 2.6.9 for arduino_core_3_0_2, which does not support Ucs890x
;; platform_wled_default = ${common.arduino_core_3_0_2}
;; platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
;; platformio/toolchain-xtensa @ ~2.40802.200502
;; platformio/tool-esptool @ ~1.413.0
;; platformio/tool-esptoolpy @ ~1.30000.0
# ------------------------------------------------------------------------------
# FLAGS: DEBUG
# esp8266 : see https://docs.platformio.org/en/latest/platforms/espressif8266.html#debug-level
@@ -164,7 +130,7 @@ upload_speed = 115200
lib_compat_mode = strict
lib_deps =
IRremoteESP8266 @ 2.8.2
https://github.com/Makuna/NeoPixelBus.git#1d7ff38f14d04a976f9c6e365c83a232bcba04fc
https://github.com/Makuna/NeoPixelBus.git#a0919d1c10696614625978dd6fb750a1317a14ce
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.2
marvinroger/AsyncMqttClient @ 0.9.0
# for I2C interface
@@ -194,8 +160,42 @@ lib_deps =
extra_scripts = ${scripts_defaults.extra_scripts}
[esp8266]
# ------------------------------------------------------------------------------
# PLATFORM:
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
#
# arduino core 2.6.3 = platformIO 2.3.2
# arduino core 2.7.0 = platformIO 2.5.0
# ------------------------------------------------------------------------------
arduino_core_2_6_3 = espressif8266@2.3.3
arduino_core_2_7_4 = espressif8266@2.6.2
arduino_core_3_0_0 = espressif8266@3.0.0
arduino_core_3_0_2 = espressif8266@3.2.0
arduino_core_3_1_0 = espressif8266@4.1.0
arduino_core_3_1_2 = espressif8266@4.2.1
# Development platforms
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
# Platform to use for ESP8266
platform_wled_default = ${esp8266.arduino_core_3_1_2}
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
platform_packages = platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platformio/tool-esptool #@ ~1.413.0
platformio/tool-esptoolpy #@ ~1.30000.0
## previous platform for 8266, in case of problems with the new one
## you'll need makuna/NeoPixelBus@ 2.6.9 for arduino_core_3_0_2, which does not support Ucs890x
;; platform_wled_default = ${esp8266.arduino_core_3_0_2}
;; platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
;; platformio/toolchain-xtensa @ ~2.40802.200502
;; platformio/tool-esptool @ ~1.413.0
;; platformio/tool-esptoolpy @ ~1.30000.0
platform = ${esp8266.platform_wled_default}
build_unflags = ${common.build_unflags}
custom_usermods =
build_flags =
-DESP8266
-DFP_IN_IROM
@@ -227,6 +227,8 @@ lib_deps =
https://github.com/tignioj/ArduinoUZlib.git#20aff95cd80c141f80bdbf66895409a0046d2c2f
${env.lib_deps}
monitor_filters = esp8266_exception_decoder
;; compatibilty flags - same as 0.14.0 which seems to work better on some 8266 boards. Not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
build_flags_compat =
-DESP8266
@@ -274,6 +276,7 @@ platform_packages =
build_unflags = ${common.build_unflags}
build_flags = ${esp32_idf_V4.build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
@@ -295,18 +298,8 @@ AR_lib_deps = ;; for pre-usermod-library platformio_override compatibility
;; 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.
;; tasmota platform (default)
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 =
;; espressif platform (optional - needs 300KB extra flash)
;;; arduino-esp32 2.0.17 + esp-idf 4.4.7
;; platform = espressif32@ ~6.13.0
;; platform_packages =
;;; arduino-esp32 2.0.14 + esp-idf 4.4.6
;; platform = espressif32@ ~6.6.0
;; platform_packages = platformio/framework-arduinoespressif32 @ 3.20014.231204
build_unflags = ${common.build_unflags}
build_flags = -g
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
@@ -336,6 +329,7 @@ build_flags = -g
lib_deps =
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
monitor_filters = esp32_exception_decoder
[esp32c3]
;; generic definitions for all ESP32-C3 boards
@@ -355,6 +349,7 @@ lib_deps =
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[esp32s3]
;; generic definitions for all ESP32-S3 boards
@@ -374,6 +369,8 @@ build_flags = -g
lib_deps =
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.large_partitions} ;; default partioning for 8MB flash - can be overridden in build envs
upload_speed = 921600
monitor_filters = esp32_exception_decoder
# ------------------------------------------------------------------------------
@@ -381,15 +378,11 @@ board_build.partitions = ${esp32.large_partitions} ;; default partioning for 8
# ------------------------------------------------------------------------------
[env:nodemcuv2]
extends = esp8266
board = nodemcuv2
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
custom_usermods = audioreactive
[env:nodemcuv2_compat]
@@ -410,15 +403,12 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
custom_usermods = audioreactive
[env:esp8266_2m]
extends = esp8266
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02\"
-D WLED_DISABLE_PARTICLESYSTEM2D
-D WLED_DISABLE_PARTICLESYSTEM1D
lib_deps = ${esp8266.lib_deps}
custom_usermods = audioreactive
[env:esp8266_2m_compat]
@@ -443,7 +433,7 @@ custom_usermods = audioreactive
;; Minimal-feature build for ESP02 (2MB flash).
;; Use this to recover from a failed OTA: flash via serial, then OTA-upload the regular esp8266_2m binary.
;; OTA is intentionally kept enabled. All other optional features are stripped to minimise binary size.
extends = env:esp8266_2m
extends = esp8266
board = esp_wroom_02
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02_min\"
@@ -462,17 +452,14 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
-D WLED_DISABLE_IMPROV_WIFISCAN
[env:esp01_1m_full]
extends = esp8266
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP01\" -D WLED_DISABLE_OTA
; -D WLED_USE_REAL_MATH ;; may fix wrong sunset/sunrise times, at the cost of 7064 bytes FLASH and 975 bytes RAM
-D WLED_DISABLE_PARTICLESYSTEM1D
-D WLED_DISABLE_PARTICLESYSTEM2D
-D WLED_DISABLE_PIXELFORGE
lib_deps = ${esp8266.lib_deps}
[env:esp01_1m_full_compat]
extends = env:esp01_1m_full
@@ -492,18 +479,14 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
-D WLED_DISABLE_PARTICLESYSTEM1D
-D WLED_DISABLE_PARTICLESYSTEM2D
-D WLED_DISABLE_PIXELFORGE
;; custom_usermods = audioreactive ;; pushed program flash size over the limits
custom_usermods = audioreactive
[env:esp32dev]
extends = esp32
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
custom_usermods = audioreactive
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio
@@ -515,50 +498,33 @@ build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags}
-D WLED_RELEASE_NAME=\"ESP32_DEBUG\"
[env:esp32dev_8M]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
extends = env:esp32dev
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.large_partitions}
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
; board_build.f_flash = 80000000L
board_build.flash_mode = dio
[env:esp32dev_16M]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
extends = env:esp32dev
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_build.f_flash = 80000000L
board_build.flash_mode = dio
[env:esp32_eth]
extends = esp32
board = esp32-poe
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
-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
lib_deps = ${esp32.lib_deps}
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio
@@ -569,20 +535,14 @@ board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = ${esp32.extended_partitions}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; Older ESP32 (rev.<3) need a PSRAM fix (increases static RAM used) https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html
-D DATA_PINS=25
lib_deps = ${esp32_idf_V4.lib_deps}
[env:esp32c3dev]
extends = esp32c3
platform = ${esp32c3.platform}
platform_packages = ${esp32c3.platform_packages}
framework = arduino
board = esp32-c3-devkitm-1
board_build.partitions = ${esp32.default_partitions}
custom_usermods = audioreactive
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C3\"
-D WLED_WATCHDOG_TIMEOUT=0
@@ -590,8 +550,6 @@ build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
;-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
upload_speed = 460800
build_unflags = ${common.build_unflags}
lib_deps = ${esp32c3.lib_deps}
board_build.flash_mode = dio ; safe default, required for OTA updates to 0.16 from older version which used dio (must match the bootloader!)
[env:esp32c3dev_qio]
@@ -601,45 +559,34 @@ board_build.flash_mode = qio ; qio is faster and works on almost all boards (som
[env:esp32s3dev_16MB_opi]
;; ESP32-S3 development board, with 16MB FLASH and >= 8MB PSRAM (memory_type: qio_opi)
extends = esp32s3
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_16MB_opi\"
-D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:esp32s3dev_8MB_opi]
;; ESP32-S3 development board, with 8MB FLASH and >= 8MB PSRAM (memory_type: qio_opi)
extends = esp32s3
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_8MB_opi\"
-D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = ${esp32.large_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:esp32s3dev_8MB_qspi]
;; generic ESP32-S3 board with 8MB FLASH and PSRAM (memory_type: qio_qspi). Try this one if esp32s3dev_8MB_opi does not work on your board
@@ -652,7 +599,6 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
;; -DLOLIN_WIFI_FIX ;; uncomment if you have WiFi connectivity problems
monitor_filters = esp32_exception_decoder
[env:esp32s3dev_8MB_none]
;; ESP32-S3 development board, 8MB FLASH, no PSRAM
@@ -670,13 +616,10 @@ board_build.flash_mode = qio
[env:esp32S3_wroom2]
;; For ESP32-S3 WROOM-2, a.k.a. ESP32-S3 DevKitC-1 v1.1
;; with >= 16MB FLASH and >= 8MB PSRAM (memory_type: opi_opi)
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
extends = esp32s3
board = esp32s3camlcd ;; this is the only standard board with "opi_opi"
board_build.arduino.memory_type = opi_opi
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_WROOM-2\"
-D WLED_WATCHDOG_TIMEOUT=0
-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
@@ -686,12 +629,9 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
-D BTNPIN=0 -D RLYPIN=16 -D IRPIN=17 -D AUDIOPIN=-1
;;-D WLED_DEBUG
-D SR_DMTYPE=1 -D I2S_SDPIN=13 -D I2S_CKPIN=14 -D I2S_WSPIN=15 -D MCLK_PIN=4 ;; I2S mic
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = ${esp32.extreme_partitions}
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
monitor_filters = esp32_exception_decoder
[env:esp32S3_wroom2_32MB]
;; For ESP32-S3 WROOM-2 with 32MB Flash, and >= 8MB PSRAM (memory_type: opi_opi)
@@ -708,26 +648,20 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
board_build.partitions = tools/WLED_ESP32_32MB.csv
board_upload.flash_size = 32MB
board_upload.maximum_size = 33554432
monitor_filters = esp32_exception_decoder
[env:esp32s3_4M_qspi]
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
extends = esp32s3
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_4M_qspi\"
-DARDUINO_USB_CDC_ON_BOOT=1 ;; -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
-DLOLIN_WIFI_FIX ; seems to work much better with this
-D WLED_WATCHDOG_TIMEOUT=0
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:esp32s3_4M_none]
;; ESP32-S3 with 4MB FLASH, no PSRAM
@@ -745,14 +679,11 @@ board_build.flash_mode = qio
[env:lolin_s2_mini]
platform = ${esp32s2.platform}
platform_packages = ${esp32s2.platform_packages}
extends = esp32s2
board = lolin_s2_mini
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = qio
board_build.f_flash = 80000000L
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S2\"
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MSC_ON_BOOT=0
@@ -767,19 +698,12 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=
-D HW_PIN_DATASPI=11
-D HW_PIN_MISOSPI=9
; -D STATUSLED=15
lib_deps = ${esp32s2.lib_deps}
[env:usermods]
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
extends = env:esp32dev
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_USERMODS\"
-DTOUCH_CS=9
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.flash_mode = dio
custom_usermods = * ; Expands to all usermods in usermods folder
board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat
@@ -796,7 +720,6 @@ board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigge
;; Core HUB75 flags - common to every HUB75 build
build_flags =
-D WLED_ENABLE_HUB75MATRIX -D NO_GFX
-D NO_CIE1931 ;; disable driver-internal gamma correction
-D WLED_DEBUG_BUS
-D LED_TYPES=TYPE_HUB75MATRIX_HS
; -D WLED_DEBUG
@@ -856,28 +779,6 @@ lib_deps = ${esp32s3.lib_deps}
${hub75.lib_deps}
;; board_build.partitions = tools/partitions-8MB_spiffs-tinyuf2.csv ;; supports adafruit UF2 bootloader
[env:waveshare_esp32s3_32MB_hub75]
;; Waveshare ESP32-S3-RGB-Matrix (memory_type: opi_opi); see https://docs.waveshare.com/ESP32-S3-RGB-Matrix
extends = env:esp32S3_wroom2_32MB
monitor_filters = esp32_exception_decoder
build_unflags = ${env:esp32S3_wroom2_32MB.build_unflags}
-D WLED_RELEASE_NAME=\"ESP32-S3_WROOM-2_32MB\" ;; need to un-set the relese name before setting a new one
custom_usermods =
Internal_Temperature
audioreactive = https://github.com/MoonModules/WLED-AudioReactive-Usermod#171c0bbc2bc47e2c11ae203dd00beed82865df2b ;; broadcast
build_flags = ${common.build_flags} ${esp32s3.build_flags} ${hub75.build_flags} ${hub75.s3_build_flags}
-D WLED_RELEASE_NAME=\"ESP32-S3_Waveshare_HUB75\"
-D WAVESHARE_S3_PINOUT
-D BTNPIN=0
-D I2CSDAPIN=47 -D I2CSCLPIN=48
-D SR_DMTYPE=9 -D I2S_SDPIN=39 -D I2S_CKPIN=43 -D I2S_WSPIN=38 -D MCLK_PIN=12 ; Waveshare ES8311 Codec pins
-D UM_SD_SELECT=14 -D UM_SD_CLOCK=1 -D UM_SD_POCI=17 -D UM_SD_PICO=44 ; Waveshare SD Card pins ** Requires updated sd_card from this PR https://github.com/wled/WLED/pull/5679 **
-D WLED_USE_SD_SPI
-D SD_PRINT_HOME_DIR
; -D WLED_DEBUG
lib_deps = ${esp32s3.lib_deps}
${hub75.lib_deps}
[env:esp32s3dev_16MB_opi_hub75]
;; MOONHUB HUB75 adapter board (lilygo T7-S3 with 16MB flash and octal PSRAM)
extends = env:esp32s3dev_8MB_opi
+94 -103
View File
@@ -5,7 +5,7 @@
# Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = WLED_generic8266_1M, esp32dev_dio80 # put the name(s) of your own build environment here. You can define as many as you need
default_envs = WLED_generic8266_1M, esp32dev_V4_dio80 # put the name(s) of your own build environment here. You can define as many as you need
#----------
# SAMPLE
@@ -13,8 +13,8 @@ default_envs = WLED_generic8266_1M, esp32dev_dio80 # put the name(s) of your ow
[env:WLED_generic8266_1M]
extends = env:esp01_1m_full # when you want to extend the existing environment (define only updated options)
; board = esp01_1m # uncomment when ou need different board
; platform = ${common.platform_wled_default} # uncomment and change when you want particular platform
; platform_packages = ${common.platform_packages}
; platform = ${esp8266.platform_wled_default} # uncomment and change when you want particular platform
; platform_packages = ${esp8266.platform_packages}
; board_build.ldscript = ${common.ldscript_1m128k}
; upload_speed = 921600 # fast upload speed (remove ';' if your board supports fast upload speed)
# Sample libraries used for various usermods. Uncomment when using particular usermod.
@@ -30,13 +30,15 @@ lib_deps = ${esp8266.lib_deps}
; https://github.com/blazoncek/QuickESPNow.git#optional-debug ;; exludes debug library
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_generic_1M\"
-D WLED_DISABLE_PARTICLESYSTEM1D -D WLED_DISABLE_PARTICLESYSTEM2D
-D WLED_DISABLE_PIXELFORGE
-D WLED_DISABLE_OTA -D WLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
;
; *** To use the below defines/overrides, copy and paste each onto its own line just below build_flags in the section above.
;
; *** Note: on adding custom usermods
; custom_usermods entries are a separate key in the env section (not inside build_flags). Place them on their own line in the env.
; Multiple usermods are separated by a space, the names can be found in the library.json file of the usermod.
; Example: use the default usermods from the esp32dev env and add the Temperature and four_line_display_ALT usermods
; custom_usermods = ${env:esp32dev.custom_usermods} Temperature four_line_display_ALT
;
; Set a release name that may be used to distinguish required binary for flashing
; -D WLED_RELEASE_NAME=\"ESP32_MULTI_USREMODS\"
;
@@ -101,17 +103,17 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
; -D WLED_DEBUG_PORT=7868
;
; Use Autosave usermod and set it to do save after 90s
; -D USERMOD_AUTO_SAVE
; custom_usermods = ${env:esp32dev.custom_usermods} auto_save
; -D AUTOSAVE_AFTER_SEC=90
;
; Use AHT10/AHT15/AHT20 usermod
; -D USERMOD_AHT10
; custom_usermods = ${env:esp32dev.custom_usermods} AHT10_v2
;
; Use INA226 usermod
; -D USERMOD_INA226
; custom_usermods = ${env:esp32dev.custom_usermods} INA226_v2
;
; Use 4 Line Display usermod with SPI display
; -D USERMOD_FOUR_LINE_DISPLAY
; custom_usermods = ${env:esp32dev.custom_usermods} four_line_display_ALT
; -DFLD_SPI_DEFAULT
; -D FLD_TYPE=SSD1306_SPI64
; -D FLD_PIN_CLOCKSPI=14
@@ -121,22 +123,22 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
; -D FLD_PIN_RESET=27
;
; Use Rotary encoder usermod (in conjunction with 4LD)
; -D USERMOD_ROTARY_ENCODER_UI
; custom_usermods = ${env:esp32dev.custom_usermods} rotary_encoder_ui_ALT
; -D ENCODER_DT_PIN=5
; -D ENCODER_CLK_PIN=18
; -D ENCODER_SW_PIN=19
;
; Use Dallas DS18B20 temperature sensor usermod and configure it to use GPIO13
; -D USERMOD_DALLASTEMPERATURE
; custom_usermods = ${env:esp32dev.custom_usermods} Temperature
; -D TEMPERATURE_PIN=13
;
; Use Multi Relay usermod and configure it to use 6 relays and appropriate GPIO
; -D USERMOD_MULTI_RELAY
; custom_usermods = ${env:esp32dev.custom_usermods} multi_relay
; -D MULTI_RELAY_MAX_RELAYS=6
; -D MULTI_RELAY_PINS=12,23,22,21,24,25
;
; Use PIR sensor usermod and configure it to use GPIO4 and timer of 60s
; -D USERMOD_PIRSWITCH
; custom_usermods = ${env:esp32dev.custom_usermods} PIR_sensor_switch
; -D PIR_SENSOR_PIN=4 # use -1 to disable usermod
; -D PIR_SENSOR_OFF_SEC=60
; -D PIR_SENSOR_MAX_SENSORS=2 # max allowable sensors (uses OR logic for triggering)
@@ -149,12 +151,12 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
; -D I2S_CKPIN=19
;
; Use PWM fan usermod
; -D USERMOD_PWM_FAN
; custom_usermods = ${env:esp32dev.custom_usermods} PWM_fan
; -D TACHO_PIN=33
; -D PWM_PIN=32
;
; Use POV Display usermod
; -D USERMOD_POV_DISPLAY
; custom_usermods = ${env:esp32dev.custom_usermods} pov_display
; Use built-in or custom LED as a status indicator (assumes LED is connected to GPIO16)
; -D STATUSLED=16
;
@@ -187,7 +189,6 @@ build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=
; configure I2C and SPI interface (for various hardware)
; -D I2CSDAPIN=33 # initialise interface
; -D I2CSCLPIN=35 # initialise interface
; # HW_PIN_* informs the WebUI about default pins - don't initialise interface
; -D HW_PIN_SCL=35
; -D HW_PIN_SDA=33
; -D HW_PIN_CLOCKSPI=7
@@ -219,60 +220,63 @@ build_flags =
[env:esp07]
board = esp07
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_ESP07\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:d1_mini]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
upload_speed = 921600
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_D1MINI\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
[env:heltec_wifi_kit_8]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_HT_D1MINI\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:h803wf]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=1 -D WLED_DISABLE_INFRARED -D WLED_RELEASE_NAME=\"ESP8266_HT803WF\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:esp32dev_qio80]
extends = env:esp32dev # we want to extend the existing esp32dev environment (and define only updated options)
board = esp32dev
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_qio80\" #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32_idf_V4.lib_deps}
build_flags = ${common.build_flags} ${esp32.build_flags} #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.f_flash = 80000000L
board_build.flash_mode = qio
[env:esp32dev_dio80]
extends = env:esp32dev_qio80 # we want to extend the previous environment, to change flash speed
build_unflags = ${env:esp32dev_qio80.build_unflags} -D WLED_RELEASE_NAME=\"ESP32_qio80\" # need to remove the previous WLED_RELEASE_NAME
build_flags = ${env:esp32dev_qio80.build_flags} -D WLED_RELEASE_NAME=\"ESP32_dio80\" # ... and then we can set a new one
board_build.flash_mode = dio # change flash mode to "dio", for boards that cannot not start with "qio" mode
[env:esp32dev_V4_dio80]
;; experimental ESP32 env using ESP-IDF V4.4.x
;; Warning: this build environment is not stable!!
;; please erase your device before installing.
extends = esp32_idf_V4 # based on newer "esp-idf V4" platform environment
board = esp32dev
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
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}
board_build.f_flash = 80000000L
board_build.flash_mode = dio
[env:esp32s2_saola]
extends = esp32s2
@@ -282,51 +286,53 @@ platform_packages = ${esp32s2.platform_packages}
framework = arduino
board_build.flash_mode = qio
upload_speed = 460800
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S2_saola\"
build_flags = ${common.build_flags} ${esp32s2.build_flags}
;-DLOLIN_WIFI_FIX ;; try this in case Wifi does not work
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps = ${esp32s2.lib_deps}
[env:esp32s3dev_8MB_PSRAM_qspi]
;; ESP32-TinyS3 development board, with 8MB FLASH and PSRAM (memory_type: qio_qspi)
extends = env:esp32s3dev_8MB_PSRAM_opi
;board = um_tinys3 ; -> needs workaround from https://github.com/wled-dev/WLED/pull/2905#issuecomment-1328049860
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_qspi ;; use with PSRAM: 2MB or 4MB
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA -D WLED_RELEASE_NAME=\"ESP8285_4CH_MagicHome\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
[env:esp8285_H801]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA -D WLED_RELEASE_NAME=\"ESP8285_H801\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_5CH_Shojo_PCB]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
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.
-D WLED_RELEASE_NAME=\"ESP8266_5CH_Shojo_PCB\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_debug]
board = d1_mini
build_type = debug
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} ${common.debug_flags} -D WLED_RELEASE_NAME=\"ESP8266_D1MINI_DEBUG\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags} ${common.debug_flags}
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_ota]
@@ -334,23 +340,20 @@ board = d1_mini
upload_protocol = espota
# exchange for your WLED IP
upload_port = "10.10.1.27"
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_D1MINI_OTA\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:anavi_miracle_controller]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=12 -D IRPIN=-1 -D RLYPIN=2
-D WLED_RELEASE_NAME=\"ESP8266_ANAVI_MIRACLE\" #-DWLED_DISABLE_2D
-D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:esp32c3dev_2MB]
@@ -361,7 +364,6 @@ platform = ${esp32c3.platform}
platform_packages = ${esp32c3.platform_packages}
board = esp32-c3-devkitm-1
build_flags = ${common.build_flags} ${esp32c3.build_flags}
-D WLED_RELEASE_NAME=\"ESP32-C3_2MB\"
-D WLED_WATCHDOG_TIMEOUT=0
-D WLED_DISABLE_OTA
; -DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
@@ -378,6 +380,7 @@ board_upload.maximum_size = 2097152
extends = esp32 ;; use default esp32 platform
board = esp32dev
upload_speed = 460800
custom_usermods = ${env:esp32dev.custom_usermods} Temperature four_line_display_ALT
build_flags = ${common.build_flags} ${esp32.build_flags}
-D WLED_RELEASE_NAME=\"ESP32_wemos_shield\"
-D DATA_PINS=16
@@ -385,12 +388,8 @@ build_flags = ${common.build_flags} ${esp32.build_flags}
-D BTNPIN=17
-D IRPIN=18
-UWLED_USE_MY_CONFIG
-D USERMOD_DALLASTEMPERATURE
-D USERMOD_FOUR_LINE_DISPLAY
-D TEMPERATURE_PIN=23
lib_deps = ${esp32.lib_deps}
OneWire@~2.3.5 ;; needed for USERMOD_DALLASTEMPERATURE
olikraus/U8g2 @ ^2.28.8 ;; needed for USERMOD_FOUR_LINE_DISPLAY
board_build.partitions = ${esp32.default_partitions}
[env:esp32_pico-D4]
@@ -413,84 +412,76 @@ board_build.f_flash = 80000000L
[env:m5atom]
extends = env:esp32dev # we want to extend the existing esp32dev environment (and define only updated options)
build_flags = ${common.build_flags} ${esp32.build_flags} -D DATA_PINS=27 -D BTNPIN=39
-D WLED_RELEASE_NAME=\"ESP32_m5atom\"
[env:sp501e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform = ${esp8266.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=3 -D BTNPIN=1
-D WLED_RELEASE_NAME=\"ESP8266_sp501e\" -D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:sp511e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform = ${esp8266.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3
-D WLED_RELEASE_NAME=\"ESP8266_sp511e\" -D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:Athom_RGBCW] ;7w and 5w(GU10) bulbs
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,13,5
-D LED_TYPES=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0
-D WLED_RELEASE_NAME=\"ESP8285_Athom_RGBCW\" -D WLED_DISABLE_PARTICLESYSTEM2D
-D LED_TYPES=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0
lib_deps = ${esp8266.lib_deps}
[env:Athom_15w_RGBCW] ;15w bulb
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,5,13
-D LED_TYPES=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 -D WLED_USE_IC_CCT
-D WLED_RELEASE_NAME=\"ESP8285_Athom_15W_RGBCW\" -D WLED_DISABLE_PARTICLESYSTEM2D
-D LED_TYPES=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 -D WLED_USE_IC_CCT
lib_deps = ${esp8266.lib_deps}
[env:Athom_3Pin_Controller] ;small controller with only data
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
-D WLED_RELEASE_NAME=\"ESP8285_Athom_3Pin\" -D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:Athom_4Pin_Controller] ; With clock and data interface
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=12 -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
-D WLED_RELEASE_NAME=\"ESP8285_Athom_4Pin\" -D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:Athom_5Pin_Controller] ;Analog light strip controller
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 DATA_PINS=4,12,14,13 -D WLED_DISABLE_INFRARED
-D WLED_RELEASE_NAME=\"ESP8285_Athom_5Pin\" -D WLED_DISABLE_PARTICLESYSTEM2D
lib_deps = ${esp8266.lib_deps}
[env:MY9291]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
custom_usermods = ${env:esp01_1m_full.custom_usermods} MY9291
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA -D WLED_RELEASE_NAME=\"ESP8266_MY9291\" -D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
@@ -500,20 +491,20 @@ lib_deps = ${esp8266.lib_deps}
[env:codm-controller-0_6]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_CODM06_2MB\" -D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:codm-controller-0_6-rev2]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
platform = ${esp8266.platform_wled_default}
platform_packages = ${esp8266.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_CODM06R2_4MB\" -D WLED_DISABLE_PARTICLESYSTEM2D
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
+47 -63
View File
@@ -7,97 +7,81 @@
<a href="https://kno.wled.ge"><img src="https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square"></a>
<a href="https://github.com/Aircoookie/WLED-App"><img src="https://img.shields.io/badge/app-wled-blue.svg?style=flat-square"></a>
<a href="https://gitpod.io/#https://github.com/wled-dev/WLED"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?style=flat-square&logo=gitpod"></a>
</p>
</p>
# Welcome to WLED! ✨
A fast and feature-rich firmware for ESP32 microcontrollers to control addressable LEDs — from simple strips to large 2D matrices and HUB75 panels.
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), now maintained by a community of contributors.
Originally created by [Aircoookie](https://github.com/Aircoookie)
## ⚙️ Features
- 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 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](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 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
### Effects & Visuals
- [**200+ built-in effects**](https://kno.wled.ge/features/effects/) including classic animations, audio-reactive, and 2D/matrix effects
- [50+ color palettes](https://kno.wled.ge/features/palettes/) plus a built-in **custom palette editor** (PixelForge)
- [**2D LED matrix support**](https://kno.wled.ge/advanced/mapping/) with dedicated 2D effects and flexible panel mapping
- [**HUB75 RGB matrix panel support**](https://kno.wled.ge/advanced/HUB75/) (ESP32)
- [**AudioReactive**](https://kno.wled.ge/advanced/audio-reactive/) effects — included by default, responding to sound via microphone, line-in, or network audio source
- Effect blending for smooth transitions between animations
- Antialiased drawing functions for smooth graphics
### Segments & Control
- [**Segments**](https://kno.wled.ge/features/segments/) — apply different effects, colors and palettes to independent parts of your LED setup simultaneously
- Up to **250 presets** to save and recall colors, effects and segment configurations — supports [playlists](https://kno.wled.ge/features/presets/) for automated cycling
- Nightlight function with configurable dimming curve
- Configurable **Auto Brightness Limiter** (per output) for safe operation
### Hardware Support
- **ESP32** (all variants: original, S2, S3, C3)
- [**Up to 17 LED outputs**](https://kno.wled.ge/features/multi-strip/) on ESP32 using parallel I2S + RMT
- [Addressable LED support](https://kno.wled.ge/basics/compatible-led-strips/): WS2812B, WS2811, WS2815, SK6812, WS2805, TM1914, APA102, WS2801, LPD8806, and many more
- RGBW, [RGB+CCT](https://kno.wled.ge/features/cct/) and white-only strips
- PWM outputs for analog LEDs and dimmers
- [**Ethernet** support](https://kno.wled.ge/features/ethernet-lan/) for a wide range of boards (QuinLED, LILYGO, Olimex, and more)
- Filesystem-based config for easy backup and restore of presets and settings
- Full OTA firmware updates (HTTP + ArduinoOTA), password-protectable
### Connectivity & Integrations
- **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](https://kno.wled.ge/interfaces/json-api/) and [HTTP request](https://kno.wled.ge/interfaces/http-api/) APIs
- **Multi-WiFi** — connect to up to 3 networks with automatic AP fallback
- **ESP-NOW** wireless sync between devices (no WiFi router required)
- [**MQTT**](https://kno.wled.ge/interfaces/mqtt/) with Home Assistant discovery
- [**E1.31, Art-Net**](https://kno.wled.ge/interfaces/e1.31-dmx/), [DDP](https://kno.wled.ge/interfaces/ddp/) and [TPM2.net](https://kno.wled.ge/interfaces/udp-realtime/) for DMX/professional lighting control
- [UDP realtime sync](https://kno.wled.ge/interfaces/udp-notifier/) across multiple WLED devices
- Alexa voice control (on/off, brightness, color)
- [Philips Hue sync](https://kno.wled.ge/interfaces/philips-hue/)
- [diyHue](https://github.com/diyhue/diyHue) and [Hyperion](https://github.com/hyperion-project/hyperion.ng) integration
- [Adalight / TPM2](https://kno.wled.ge/interfaces/serial/) (PC ambilight via serial)
- [Infrared remote control](https://kno.wled.ge/interfaces/infrared/) (24-key RGB, receiver required)
- Timers and schedules (NTP time sync, full timezone and DST support)
### Developer-Friendly
- **Usermod system** — extend WLED with community or custom modules without modifying core code
- Large and active [usermod library](https://kno.wled.ge/advanced/community-usermods/) including AudioReactive, temperature sensors, rotary encoders, displays, and much more
- Well-documented [JSON API](https://kno.wled.ge/interfaces/json-api/)
- Licensed under the **EUPL v1.2**
## 💡 Supported light control interfaces
- 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
- 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))
- [Hyperion](https://github.com/hyperion-project/hyperion.ng)
- UDP realtime
- Alexa voice control (including dimming and color)
- Sync to Philips hue lights
- Adalight (PC ambilight via serial) and TPM2
- Sync color of multiple WLED devices (UDP notifier)
- Infrared remotes (24-key RGB, receiver required)
- Simple timers/schedules (time from NTP, timezones/DST supported)
## 📲 Quick start guide and documentation
See the [documentation at kno.wled.ge](https://kno.wled.ge)!
See the [documentation on our official site](https://kno.wled.ge)!
[Tutorials and getting-started guides](https://kno.wled.ge/basics/tutorials/) to help you get your project running quickly.
[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!
## 🖼️ User interface
<img src="/images/macbook-pro-space-gray-on-the-wooden-table.jpg" width="50%"><img src="/images/walking-with-iphone-x.jpg" width="50%">
## 💾 Compatible hardware
See the [compatible hardware list](https://kno.wled.ge/basics/compatible-hardware) on the wiki.
See [here](https://kno.wled.ge/basics/compatible-hardware)!
## ✌️ Other
Licensed under the [EUPL v1.2](https://raw.githubusercontent.com/wled-dev/WLED/main/LICENSE).
Credits to all [contributors](https://kno.wled.ge/about/contributors/)!
CORS proxy by [Corsfix](https://corsfix.com/).
Licensed under the EUPL v1.2 license
Credits [here](https://kno.wled.ge/about/contributors/)!
CORS proxy by [Corsfix](https://corsfix.com/)
Join the Discord server to discuss everything about WLED!
<a href="https://discord.gg/QAh7wJHrRM"><img src="https://discordapp.com/api/guilds/473448917040758787/widget.png?style=banner2" width="25%"></a>
Check out the WLED [Discourse forum](https://wled.discourse.group)!
Check out the WLED [Discourse forum](https://wled.discourse.group)!
If you'd like to reach the original creator privately: [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
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 brightens up your day, you can [send a gift to Aircoookie via PayPal](https://paypal.me/aircoookie).
If WLED really brightens up your day, you can [![](https://img.shields.io/badge/send%20me%20a%20small%20gift-paypal-blue.svg?style=flat-square)](https://paypal.me/aircoookie)
---
*Disclaimer:*
*Disclaimer:*
If you are prone to photosensitive epilepsy, we recommend you do **not** use this software.
If you still want to try, avoid strobe, lightning or noise modes and high effect speed settings.
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.
As per the EUPL license, no liability is assumed for any damage to you or any other person or equipment.
+12 -6
View File
@@ -119,7 +119,7 @@ describe('Script', () => {
async function checkIfFileWasNewlyCreated(file) {
const modifiedTime = fs.statSync(file).mtimeMs;
assert(Date.now() - modifiedTime < 500, file + ' was not modified');
assert(Date.now() - modifiedTime < 850, file + ' was not modified');
}
async function testFileModification(sourceFilePath, resultFile) {
@@ -129,7 +129,7 @@ describe('Script', () => {
// modify file
fs.appendFileSync(sourceFilePath, ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
await new Promise(resolve => setTimeout(resolve, 1400));
// run script cdata.js again and wait for it to finish
await execPromise('node tools/cdata.js');
@@ -175,13 +175,19 @@ describe('Script', () => {
});
it('a settings file changes', async () => {
await testFileModification(path.join(dataPath, 'settings_leds.htm'), 'html_ui.h');
await testFileModification(path.join(dataPath, 'settings_leds.htm'), 'html_settings.h');
});
it('the favicon changes', async () => {
await testFileModification(path.join(dataPath, 'favicon.ico'), 'html_ui.h');
it('common.js changes', async () => {
await testFileModification(path.join(dataPath, 'common.js'), 'html_settings.h');
});
// this testcase currently fails - might be due to npm updates (maybe "faking" a favicon.ico change is harder now), or a real regression
// see https://github.com/wled/WLED/issues/5581
// it('the favicon changes', async () => {
// await testFileModification(path.join(dataPath, 'favicon.ico'), 'html_other.h');
// });
it('cdata.js changes', async () => {
await testFileModification('tools/cdata.js', 'html_ui.h');
});
@@ -209,4 +215,4 @@ describe('Script', () => {
assert(secondRunTime < firstRunTime / 2, 'html_*.h files were rebuilt');
});
});
});
});
+10 -2
View File
@@ -141,8 +141,16 @@ discover_devices() {
exit 1
fi
# Map avahi responses to strings seperated by 0x1F (unit separator)
mapfile -t raw_devices < <(avahi-browse _wled._tcp --terminate -r -p | awk -F';' '/^=/ {print $7"\x1F"$8"\x1F"$9}')
# Map avahi responses to strings separated by 0x1F (unit separator), deduplicated
mapfile -t raw_devices < <(
avahi-browse _wled._tcp --terminate -r -p |
awk -F';' '
/^=/ {
key = $7 "\x1F" $8 "\x1F" $9
if (!seen[key]++) print key
}
'
)
local devices_array=()
for device in "${raw_devices[@]}"; do
+2 -2
View File
@@ -1,5 +1,5 @@
#include "wled.h"
#if defined(USERMOD_DHT_MQTT) && defined(WLED_DISABLE_MQTT)
#ifdef WLED_DISABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
@@ -246,4 +246,4 @@ class UsermodDHT : public Usermod {
static UsermodDHT dht;
REGISTER_USERMOD(dht);
REGISTER_USERMOD(dht);
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name:": "EleksTube_IPS",
"name": "EleksTube_IPS",
"build": { "libArchive": false },
"dependencies": {
"TFT_eSPI" : "2.5.33"
+114 -35
View File
@@ -1,14 +1,38 @@
#include "wled.h"
#include <INA226_WE.h>
#ifndef INA226_ADDRESS
#define INA226_ADDRESS 0x40 // Default I2C address for INA226
#endif
#define DEFAULT_CHECKINTERVAL 60000
#ifndef INA226_CHECK_INTERVAL_MS
#define INA226_CHECK_INTERVAL_MS 60000 // Default check interval in milliseconds
#endif
#define DEFAULT_CHECKINTERVAL INA226_CHECK_INTERVAL_MS
#define DEFAULT_INASAMPLES 128
#define DEFAULT_INASAMPLESENUM AVERAGE_128
#define DEFAULT_INACONVERSIONTIME 1100
#define DEFAULT_INACONVERSIONTIMEENUM CONV_TIME_1100
// Compile-time defaults for shunt resistor (micro-ohms), current range (mA), and current offset (mA)
// These can be overridden via -D flags in platformio.ini / platformio_override.ini
#ifndef INA226_SHUNT_MICRO_OHMS
#define INA226_SHUNT_MICRO_OHMS 1000000 // 1 Ohm = 1,000,000 μΩ
#endif
#ifndef INA226_DEFAULT_CURRENT_RANGE
#define INA226_DEFAULT_CURRENT_RANGE 1000 // 1000 mA = 1 A
#endif
#ifndef INA226_CURRENT_OFFSET_MA
#define INA226_CURRENT_OFFSET_MA 0 // No offset by default
#endif
#ifndef INA226_ENABLED_DEFAULT
#define INA226_ENABLED_DEFAULT false
#endif
// A packed version of all INA settings enums and their human friendly counterparts packed into a 32 bit structure
// Some values are shifted and need to be preprocessed before usage
struct InaSettingLookup
@@ -81,10 +105,11 @@ private:
uint16_t _settingInaSamples : 11; // Number of samples for averaging, max 1024
uint8_t _i2cAddress;
uint16_t _checkInterval; // milliseconds, user settings is in seconds
float _decimalFactor; // a power of 10 factor. 1 would be no change, 10 is one decimal, 100 is two etc. User sees a power of 10 (0, 1, 2, ..)
uint16_t _shuntResistor; // Shunt resistor value in milliohms
uint16_t _currentRange; // Expected maximum current in milliamps
uint32_t _checkIntervalMs; // milliseconds, user settings is in seconds
float _decimalFactor; // a power of 10 factor. 1 would be no change, 10 is one decimal, 100 is two etc. User sees a power of 10 (0, 1, 2, ..)
uint32_t _shuntResistorUOhm; // Shunt resistor value in micro-ohms (μΩ)
uint16_t _currentRangeMa; // Expected maximum current in milliamps
int16_t _currentOffsetMa; // Current offset in milliamps, subtracted from readings
uint8_t _lastStatus = 0;
float _lastCurrent = 0;
@@ -93,7 +118,7 @@ private:
float _lastShuntVoltage = 0;
bool _lastOverflow = false;
#ifndef WLED_MQTT_DISABLE
#ifndef WLED_DISABLE_MQTT
float _lastCurrentSent = 0;
float _lastVoltageSent = 0;
float _lastPowerSent = 0;
@@ -118,9 +143,11 @@ private:
_ina226 = new INA226_WE(_i2cAddress);
if (!_ina226->init())
{
DEBUG_PRINTLN(F("INA226 initialization failed!"));
DEBUG_PRINTLN(F("INA226: init failed!"));
return;
}
DEBUG_PRINTF_P(PSTR("INA226: addr=0x%02X shunt=%luμΩ range=%umA offset=%dmA\n"),
_i2cAddress, _shuntResistorUOhm, _currentRangeMa, _currentOffsetMa);
_ina226->setCorrectionFactor(1.0);
uint16_t tmpShort = _settingInaSamples;
@@ -129,7 +156,7 @@ private:
tmpShort = _settingInaConversionTimeUs << 2;
_ina226->setConversionTime(getConversionTimeEnum(tmpShort));
if (_checkInterval >= 20000)
if (_checkIntervalMs >= 20000)
{
_isTriggeredOperationMode = true;
_ina226->setMeasureMode(TRIGGERED);
@@ -140,7 +167,11 @@ private:
_ina226->setMeasureMode(CONTINUOUS);
}
_ina226->setResistorRange(static_cast<float>(_shuntResistor) / 1000.0, static_cast<float>(_currentRange) / 1000.0);
_ina226->setResistorRange(static_cast<float>(_shuntResistorUOhm) / 1000000.0f, static_cast<float>(_currentRangeMa) / 1000.0f);
DEBUG_PRINTF_P(PSTR("INA226: mode=%s interval=%lums samples=%u convTime=%uμs\n"),
_isTriggeredOperationMode ? "triggered" : "continuous",
_checkIntervalMs, _settingInaSamples, _settingInaConversionTimeUs << 2);
}
void fetchAndPushValues()
@@ -150,17 +181,19 @@ private:
if (_lastStatus != 0)
return;
float current = truncateDecimals(_ina226->getCurrent_mA() / 1000.0);
float current = truncateDecimals((_ina226->getCurrent_mA() - _currentOffsetMa) / 1000.0f);
float voltage = truncateDecimals(_ina226->getBusVoltage_V());
float power = truncateDecimals(_ina226->getBusPower() / 1000.0);
float shuntVoltage = truncateDecimals(_ina226->getShuntVoltage_V());
float power = truncateDecimals(_ina226->getBusPower() / 1000.0f);
float shuntVoltage = truncateDecimals(_ina226->getShuntVoltage_mV());
bool overflow = _ina226->overflow;
#ifndef WLED_DISABLE_MQTT
mqttPublishIfChanged(F("current"), _lastCurrentSent, current, 0.01f);
mqttPublishIfChanged(F("voltage"), _lastVoltageSent, voltage, 0.01f);
mqttPublishIfChanged(F("power"), _lastPowerSent, power, 0.1f);
mqttPublishIfChanged(F("shunt_voltage"), _lastShuntVoltageSent, shuntVoltage, 0.01f);
// Publish in V for backward compatibility
float shuntVoltageV = shuntVoltage / 1000.0f;
mqttPublishIfChanged(F("shunt_voltage"), _lastShuntVoltageSent, shuntVoltageV, 0.01f);
mqttPublishIfChanged(F("overflow"), _lastOverflowSent, overflow);
#endif
@@ -169,6 +202,9 @@ private:
_lastPower = power;
_lastShuntVoltage = shuntVoltage;
_lastOverflow = overflow;
DEBUG_PRINTF_P(PSTR("INA226: %.3fA %.2fV %.2fW shunt=%.2fmV%s\n"),
current, voltage, power, shuntVoltage, overflow ? " OVF" : "");
}
void handleTriggeredMode(unsigned long currentTime)
@@ -188,7 +224,7 @@ private:
}
else
{
if (currentTime - _lastLoopCheck >= _checkInterval)
if (currentTime - _lastLoopCheck >= _checkIntervalMs)
{
// Start a measurement and use isBusy() later to determine when it is done
_ina226->startSingleMeasurementNoWait();
@@ -201,7 +237,7 @@ private:
void handleContinuousMode(unsigned long currentTime)
{
if (currentTime - _lastLoopCheck >= _checkInterval)
if (currentTime - _lastLoopCheck >= _checkIntervalMs)
{
_lastLoopCheck = currentTime;
fetchAndPushValues();
@@ -215,19 +251,23 @@ private:
return;
char topic[128];
snprintf_P(topic, 127, "%s/current", mqttDeviceTopic);
auto buildTopic = [&](const char *suffix) {
snprintf_P(topic, sizeof(topic), PSTR("%s/%s"), mqttDeviceTopic, suffix);
};
buildTopic("current");
mqttCreateHassSensor(F("Current"), topic, F("current"), F("A"));
snprintf_P(topic, 127, "%s/voltage", mqttDeviceTopic);
buildTopic("voltage");
mqttCreateHassSensor(F("Voltage"), topic, F("voltage"), F("V"));
snprintf_P(topic, 127, "%s/power", mqttDeviceTopic);
buildTopic("power");
mqttCreateHassSensor(F("Power"), topic, F("power"), F("W"));
snprintf_P(topic, 127, "%s/shunt_voltage", mqttDeviceTopic);
buildTopic("shunt_voltage");
mqttCreateHassSensor(F("Shunt Voltage"), topic, F("voltage"), F("V"));
snprintf_P(topic, 127, "%s/overflow", mqttDeviceTopic);
buildTopic("overflow");
mqttCreateHassBinarySensor(F("Overflow"), topic);
}
@@ -315,14 +355,23 @@ public:
UsermodINA226()
{
// Default values
_settingEnabled = INA226_ENABLED_DEFAULT;
_settingInaSamples = DEFAULT_INASAMPLES;
_settingInaConversionTimeUs = DEFAULT_INACONVERSIONTIME;
_settingInaConversionTimeUs = DEFAULT_INACONVERSIONTIME >> 2; // stored shifted to fit 12-bit field
_i2cAddress = INA226_ADDRESS;
_checkInterval = DEFAULT_CHECKINTERVAL;
_checkIntervalMs = DEFAULT_CHECKINTERVAL;
_decimalFactor = 100;
_shuntResistor = 1000;
_currentRange = 1000;
_shuntResistorUOhm = INA226_SHUNT_MICRO_OHMS;
_currentRangeMa = INA226_DEFAULT_CURRENT_RANGE;
_currentOffsetMa = INA226_CURRENT_OFFSET_MA;
_mqttPublish = false;
_mqttPublishAlways = false;
_mqttHomeAssistant = false;
_initDone = false;
_isTriggeredOperationMode = false;
_measurementTriggered = false;
}
void setup()
@@ -399,7 +448,7 @@ public:
JsonArray jsonCurrent = user.createNestedArray(F("Current"));
JsonArray jsonVoltage = user.createNestedArray(F("Voltage"));
JsonArray jsonPower = user.createNestedArray(F("Power"));
JsonArray jsonShuntVoltage = user.createNestedArray(F("Shunt Voltage"));
JsonArray jsonShuntVoltage = user.createNestedArray(F("Shunt Voltage Drop"));
JsonArray jsonOverflow = user.createNestedArray(F("Overflow"));
if (_lastLoopCheck == 0)
@@ -432,7 +481,7 @@ public:
jsonPower.add(F("W"));
jsonShuntVoltage.add(_lastShuntVoltage);
jsonShuntVoltage.add(F("V"));
jsonShuntVoltage.add(F("mV"));
jsonOverflow.add(_lastOverflow ? F("true") : F("false"));
}
@@ -442,12 +491,13 @@ public:
JsonObject top = root.createNestedObject(FPSTR(_name));
top[F("Enabled")] = _settingEnabled;
top[F("I2CAddress")] = static_cast<uint8_t>(_i2cAddress);
top[F("CheckInterval")] = _checkInterval / 1000;
top[F("CheckInterval")] = _checkIntervalMs / 1000;
top[F("INASamples")] = _settingInaSamples;
top[F("INAConversionTime")] = _settingInaConversionTimeUs << 2;
top[F("Decimals")] = log10f(_decimalFactor);
top[F("ShuntResistor")] = _shuntResistor;
top[F("CurrentRange")] = _currentRange;
top[F("ShuntResistor")] = static_cast<float>(_shuntResistorUOhm) / 1000.0f;
top[F("CurrentRange")] = _currentRangeMa;
top[F("CurrentOffset")] = _currentOffsetMa;
#ifndef WLED_DISABLE_MQTT
top[F("MqttPublish")] = _mqttPublish;
top[F("MqttPublishAlways")] = _mqttPublishAlways;
@@ -457,6 +507,17 @@ public:
DEBUG_PRINTLN(F("INA226 config saved."));
}
void appendConfigData() override
{
oappend(F("addInfo('INA226:CheckInterval',1,'seconds');"));
oappend(F("addInfo('INA226:INASamples',1,'samples (1-1024)');"));
oappend(F("addInfo('INA226:INAConversionTime',1,'&micro;s');"));
oappend(F("addInfo('INA226:Decimals',1,'(0-5)');"));
oappend(F("addInfo('INA226:ShuntResistor',1,'m&Omega;');"));
oappend(F("addInfo('INA226:CurrentRange',1,'mA');"));
oappend(F("addInfo('INA226:CurrentOffset',1,'mA');"));
}
bool readFromConfig(JsonObject &root) override
{
JsonObject top = root[FPSTR(_name)];
@@ -472,12 +533,12 @@ public:
configComplete = false;
configComplete &= getJsonValue(top[F("I2CAddress")], _i2cAddress);
if (getJsonValue(top[F("CheckInterval")], _checkInterval))
if (getJsonValue(top[F("CheckInterval")], _checkIntervalMs))
{
if (1 <= _checkInterval && _checkInterval <= 600)
_checkInterval *= 1000;
if (1 <= _checkIntervalMs && _checkIntervalMs <= 600)
_checkIntervalMs *= 1000;
else
_checkInterval = DEFAULT_CHECKINTERVAL;
_checkIntervalMs = DEFAULT_CHECKINTERVAL;
}
else
configComplete = false;
@@ -511,8 +572,26 @@ public:
else
configComplete = false;
configComplete &= getJsonValue(top[F("ShuntResistor")], _shuntResistor);
configComplete &= getJsonValue(top[F("CurrentRange")], _currentRange);
float shuntMilliOhms;
if (getJsonValue(top[F("ShuntResistor")], shuntMilliOhms))
{
if (shuntMilliOhms > 0)
_shuntResistorUOhm = static_cast<uint32_t>(shuntMilliOhms * 1000.0f + 0.5f);
else
_shuntResistorUOhm = INA226_SHUNT_MICRO_OHMS;
}
else
configComplete = false;
if (getJsonValue(top[F("CurrentRange")], _currentRangeMa))
{
if (_currentRangeMa == 0 || _currentRangeMa > 20000)
_currentRangeMa = INA226_DEFAULT_CURRENT_RANGE;
}
else
configComplete = false;
if (!getJsonValue(top[F("CurrentOffset")], _currentOffsetMa))
_currentOffsetMa = INA226_CURRENT_OFFSET_MA; // Use compile-time default if missing from config
#ifndef WLED_DISABLE_MQTT
if (getJsonValue(top[F("MqttPublish")], tmpBool))
+31 -1
View File
@@ -18,6 +18,7 @@ The following settings can be configured in the Usermod Menu:
- **Decimals**: Number of decimals in the output.
- **ShuntResistor**: Shunt resistor value in milliohms. An R100 shunt resistor should be written as "100", while R010 should be "10".
- **CurrentRange**: Expected maximum current in milliamps (e.g., 5 A = 5000 mA).
- **CurrentOffset**: Current offset in milliamps, subtracted from raw readings. Useful for compensating a consistent bias in the sensor. Default is 0.
- **MqttPublish**: Enable or disable MQTT publishing.
- **MqttPublishAlways**: Publish always, regardless if there is a change.
- **MqttHomeAssistantDiscovery**: Enable Home Assistant discovery.
@@ -63,4 +64,33 @@ extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} INA226
build_flags = ${env:esp32dev.build_flags}
; -D USERMOD_INA226_DEBUG ; -- add a debug status to the info modal
```
```
### Compile-time Defaults
Several parameters can be overridden at compile time via `-D` build flags. This is useful for setting board-specific defaults so the device works correctly on first boot without manual configuration.
| Build Flag | Default | Unit | Description |
|---|---|---|---|
| `INA226_ADDRESS` | `0x40` | — | I2C address of the INA226 |
| `INA226_SHUNT_MICRO_OHMS` | `1000000` | μΩ | Shunt resistor value (1 000 000 μΩ = 1 Ω) |
| `INA226_DEFAULT_CURRENT_RANGE` | `1000` | mA | Expected maximum current (1000 mA = 1 A) |
| `INA226_CURRENT_OFFSET_MA` | `0` | mA | Current offset subtracted from readings |
| `INA226_CHECK_INTERVAL_MS` | `60000` | ms | Default interval between readings on first boot |
| `INA226_ENABLED_DEFAULT` | `false` | — | Enable the usermod on first boot |
Example for a board with a 2.888 mΩ effective shunt, 10 A range, -118 mA offset, 1 second polling, and enabled by default:
```ini
[env:my_board]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods} INA226
build_flags = ${env:esp32dev.build_flags}
-D INA226_ENABLED_DEFAULT=true
-D INA226_SHUNT_MICRO_OHMS=2888
-D INA226_DEFAULT_CURRENT_RANGE=10000
-D INA226_CURRENT_OFFSET_MA=-118
-D INA226_CHECK_INTERVAL_MS=1000
```
All compile-time defaults can still be changed at runtime through the Usermod settings page.
@@ -1,4 +1,4 @@
{
"name:": "ST7789_display",
"name": "ST7789_display",
"build": { "libArchive": false }
}
+17 -36
View File
@@ -296,17 +296,17 @@ void FFTcode(void * parameter)
ArduinoFFT<float> FFT = ArduinoFFT<float>(valFFT, vImag, samplesFFT, SAMPLE_RATE, true);
#elif !defined(UM_AUDIOREACTIVE_USE_INTEGER_FFT)
// allocate and initialize FFT buffers on first call
// note: free() is never used on these pointers. If it ever is implemented, this implementation can cause memory leaks (need to free raw pointers)
if (valFFT == nullptr) {
valFFT = (float*)heap_caps_aligned_calloc(16, 2 * samplesFFT, sizeof(float), MALLOC_CAP_8BIT); // SIMD requires aligned memory to 16-byte boundary. note in IDF5 there is MALLOC_CAP_SIMD available
if ((valFFT == nullptr)) return; // something went wrong
float* raw_buffer = (float*)heap_caps_malloc((2 * samplesFFT * sizeof(float)) + 16, MALLOC_CAP_8BIT);
if ((raw_buffer == nullptr)) return; // something went wrong
valFFT = (float*)(((uintptr_t)raw_buffer + 15) & ~15); // SIMD requires aligned memory to 16-byte boundary. note in IDF5 there is MALLOC_CAP_SIMD available
}
// create window
if (windowFFT == nullptr) {
windowFFT = (float*)heap_caps_aligned_calloc(16, samplesFFT, sizeof(float), MALLOC_CAP_8BIT); // SIMD requires aligned memory to 16-byte boundary. note in IDF5 there is MALLOC_CAP_SIMD available
if ((windowFFT == nullptr)) {
heap_caps_free(valFFT); valFFT = nullptr;
return; // something went wrong
}
float* raw_buffer = (float*)heap_caps_malloc((samplesFFT * sizeof(float)) + 16, MALLOC_CAP_8BIT);
if ((raw_buffer == nullptr)) return; // something went wrong
windowFFT = (float*)(((uintptr_t)raw_buffer + 15) & ~15); // SIMD requires aligned memory to 16-byte boundary
}
if (dsps_fft2r_init_fc32(NULL, samplesFFT) != ESP_OK) return; // initialize FFT tables
// create window function for FFT
@@ -316,20 +316,16 @@ void FFTcode(void * parameter)
dsps_wind_flat_top_f32(windowFFT, samplesFFT);
#endif
#else
// use integer FFT - allocate and initialize integer FFT buffers on first call, 4 bytes aligned (just in case, even if not strictly needed for int16_t)
if (valFFT == nullptr) valFFT = (int16_t*) heap_caps_aligned_calloc(4, samplesFFT * 2, sizeof(int16_t), MALLOC_CAP_8BIT);
// allocate and initialize integer FFT buffers on first call
if (valFFT == nullptr) valFFT = (int16_t*) calloc(sizeof(int16_t), samplesFFT * 2);
if ((valFFT == nullptr)) return; // something went wrong
// create window
if (windowFFT == nullptr) windowFFT = (int16_t*) heap_caps_aligned_calloc(4, samplesFFT, sizeof(int16_t), MALLOC_CAP_8BIT);
// create window function for FFT
float *windowFloat = (float*) heap_caps_aligned_calloc(4, samplesFFT, sizeof(float), MALLOC_CAP_8BIT); // temporary buffer for window function
if (windowFloat == nullptr || windowFFT == nullptr || valFFT == nullptr) { // something went wrong
if (windowFloat) heap_caps_free(windowFloat);
if (windowFFT) heap_caps_free(windowFFT); windowFFT = nullptr;
if (valFFT) heap_caps_free(valFFT); valFFT = nullptr;
return;
}
if (windowFFT == nullptr) windowFFT = (int16_t*) calloc(sizeof(int16_t), samplesFFT);
if ((windowFFT == nullptr)) return; // something went wrong
if (dsps_fft2r_init_sc16(NULL, samplesFFT) != ESP_OK) return; // initialize FFT tables
// create window function for FFT
float *windowFloat = (float*) calloc(sizeof(float), samplesFFT); // temporary buffer for window function
if ((windowFloat == nullptr)) return; // something went wrong
#ifdef FFT_PREFER_EXACT_PEAKS
dsps_wind_blackman_harris_f32(windowFloat, samplesFFT);
#else
@@ -339,7 +335,7 @@ void FFTcode(void * parameter)
for (int i = 0; i < samplesFFT; i++) {
windowFFT[i] = (int16_t)(windowFloat[i] * 32767.0f);
}
heap_caps_free(windowFloat); // free temporary buffer
free(windowFloat); // free temporary buffer
#endif
// see https://www.freertos.org/vtaskdelayuntil.html
@@ -472,6 +468,7 @@ void FFTcode(void * parameter)
}
FFT_Magnitude = FFT_Magnitude_int * 512; // scale to match raw float value
FFT_MajorPeak = FFT_MajorPeak_int;
FFT_Magnitude = FFT_Magnitude_int;
#endif
#endif
FFT_MajorPeak = constrain(FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects
@@ -2074,13 +2071,6 @@ class AudioReactive : public Usermod {
bool configComplete = !top.isNull();
bool oldEnabled = enabled;
bool oldAddPalettes = addPalettes;
#ifdef ARDUINO_ARCH_ESP32
auto oldDMType = dmType;
auto oldI2SsdPin = i2ssdPin;
auto oldI2swsPin = i2swsPin;
auto oldI2SckPin = i2sckPin;
auto oldI2SmclkPin = mclkPin;
#endif
configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
configComplete &= getJsonValue(top[FPSTR(_addPalettes)], addPalettes);
@@ -2122,15 +2112,6 @@ class AudioReactive : public Usermod {
// add/remove custom/audioreactive palettes
if ((oldAddPalettes && !addPalettes) || (oldAddPalettes && !enabled)) removeAudioPalettes();
if ((addPalettes && !oldAddPalettes && enabled) || (addPalettes && !oldEnabled && enabled)) createAudioPalettes();
#ifdef ARDUINO_ARCH_ESP32
// notify user when a reboot is necessary
if ((audioSource != nullptr) && (oldDMType != dmType)) errorFlag = ERR_REBOOT_NEEDED; // changing mic type requires reboot
if ( (audioSource != nullptr) && (enabled==true)
&& ((oldI2SsdPin != i2ssdPin) || (oldI2swsPin != i2swsPin) || (oldI2SckPin != i2sckPin)) ) errorFlag = ERR_REBOOT_NEEDED; // changing mic pins requires reboot
if ((audioSource != nullptr) && (oldI2SmclkPin != mclkPin)) errorFlag = ERR_REBOOT_NEEDED; // changing MCLK pin requires reboot
if ((oldDMType != dmType) && (oldDMType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing from analog mic requires power cycle
if ((oldDMType != dmType) && (dmType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing to analog mic requires power cycle
#endif
} // else setup() will create palettes
return configComplete;
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name:": "pov_display",
"name": "pov_display",
"build": { "libArchive": false},
"platforms": ["espressif32"]
}
+28 -28
View File
@@ -1061,7 +1061,7 @@ void mode_traffic_light(void) {
case 0: SEGMENT.setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break;
case 1: SEGMENT.setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); SEGMENT.setPixelColor(i+1, 0x00EECC00); break;
case 2: SEGMENT.setPixelColor(i+2, 0x0000FF00); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break;
case 3: SEGMENT.setPixelColor(i+1, gamma32inv(0x00EECC00)); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break; // gamma inversion to restore original pre 16.0 looks
case 3: SEGMENT.setPixelColor(i+1, 0x00EECC00); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break;
}
}
@@ -4182,14 +4182,14 @@ void mode_pacifica()
uint32_t nowOld = strip.now;
CRGBPalette16 pacifica_palette_1 =
{ 0x002229, 0x001E2F, 0x001934, 0x001938, 0x00143F, 0x001443, 0x00B047, 0x00B04C, // note: palettes are gamma inverted using gamma 2.0 to get closer to pre 16.0 looks
0x00004F, 0x000054, 0x000062, 0x00006F, 0x00007A, 0x000085, 0x47938A, 0x64D08E };
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
CRGBPalette16 pacifica_palette_2 =
{ 0x002229, 0x001E2F, 0x001934, 0x001938, 0x00143F, 0x001443, 0x00B047, 0x00B04C,
0x00004F, 0x000054, 0x000062, 0x00006F, 0x00007A, 0x000085, 0x369B90, 0x4FDC9B };
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
CRGBPalette16 pacifica_palette_3 =
{ 0x00142C, 0x00193B, 0x002247, 0x002551, 0x002C5A, 0x002F63, 0x00346B, 0x003671,
0x003B78, 0x003F7F, 0x00478E, 0x004D9C, 0x0054A9, 0x005AB4, 0x3F7FDC, 0x5A9CFF };
{ 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };
if (SEGMENT.palette) {
pacifica_palette_1 = SEGPALETTE;
@@ -4240,10 +4240,10 @@ void mode_pacifica()
c += CRGB(overage, overage2, qadd8(overage2, overage2));
}
//deepen the blues and greens note: no longer needed with proper gamma in 16.0
//c.blue = scale8(c.blue, 145);
//c.green = scale8(c.green, 200);
//c |= CRGB( 2, 5, 7);
//deepen the blues and greens
c.blue = scale8(c.blue, 145);
c.green = scale8(c.green, 200);
c |= CRGB( 2, 5, 7);
SEGMENT.setPixelColor(i, c);
}
@@ -4373,8 +4373,8 @@ void mode_noisepal(void) { // Slow noise pale
SEGENV.step = strip.now;
unsigned baseI = hw_random8();
uint32_t minBri = gamma8inv(128); // use gamma inversion on min brightness value to restore pre 16.0 looks (more brilliant palettes)
palettes[1] = CRGBPalette16(CHSV(baseI+hw_random8(64), 255, hw_random8(minBri,255)), CHSV(baseI+128, 255, hw_random8(minBri,255)), CHSV(baseI+hw_random8(92), 192, hw_random8(minBri,255)), CHSV(baseI+hw_random8(92), 255, hw_random8(minBri,255)));
//palettes[1] = CRGBPalette16(CHSV(baseI+hw_random8(64), 255, hw_random8(128,255)), CHSV(baseI+128, 255, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 192, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 255, hw_random8(128,255)));
palettes[1] = CRGBPalette16(CHSV(baseI+hw_random8(64), 255, hw_random8(128,255)), CHSV(baseI+128, 255, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 192, hw_random8(128,255)), CHSV(baseI+hw_random8(92), 255, hw_random8(128,255)));
}
//EVERY_N_MILLIS(10) { //(don't have to time this, effect function is only called every 24ms)
@@ -4759,10 +4759,10 @@ void mode_tv_simulator(void) {
tvSimulator->actualColorB = temp[n ];
}
}
// expand to 16 bit
nr = (uint8_t)(tvSimulator->actualColorR) * 257; // New R/G/B
ng = (uint8_t)(tvSimulator->actualColorG) * 257;
nb = (uint8_t)(tvSimulator->actualColorB) * 257;
// Apply gamma correction, further expand to 16/16/16
nr = (uint8_t)gamma8(tvSimulator->actualColorR) * 257; // New R/G/B
ng = (uint8_t)gamma8(tvSimulator->actualColorG) * 257;
nb = (uint8_t)gamma8(tvSimulator->actualColorB) * 257;
if (SEGENV.aux0 == 0) { // initialize next iteration
SEGENV.aux0 = 1;
@@ -5720,7 +5720,7 @@ void mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Ada
SEGENV.step = 0;
}
uint8_t fade = map(SEGMENT.custom1, 0, 255, 30, 250); // equals trail size
uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size
uint8_t speed = (256-SEGMENT.speed) >> map(min(rows, 150), 0, 150, 0, 3); // slower speeds for small displays
uint32_t spawnColor;
@@ -5729,8 +5729,8 @@ void mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Ada
spawnColor = SEGCOLOR(0);
trailColor = SEGCOLOR(1);
} else {
spawnColor = RGBW32(gamma8inv(175), gamma8inv(255), gamma8inv(175), 0); // use gamma inversion to restor original pre 16.0 looks
trailColor = RGBW32(gamma8inv(27), gamma8inv(130), gamma8inv(39), 0);
spawnColor = RGBW32(175,255,175,0);
trailColor = RGBW32(27,130,39,0);
}
bool emptyScreen = true;
@@ -7005,8 +7005,8 @@ static const char _data_FX_MODE_MIDNOISE[] PROGMEM = "Midnoise@Fade rate,Max. le
//////////////////////
// I am the god of hellfire. . . Volume (only) reactive fire routine. Oh, look how short this is.
void mode_noisefire(void) { // Noisefire. By Andrew Tuline.
CRGBPalette16 myPal = CRGBPalette16(CHSV(0,255,20), CHSV(0,255,30), CHSV(0,255,40), CHSV(0, 255, 44), // Fire palette definition. Lower value = darker.
CHSV(0, 255, 64), CRGB::Red, CRGB::Red, CRGB::Red,
CRGBPalette16 myPal = CRGBPalette16(CHSV(0,255,2), CHSV(0,255,4), CHSV(0,255,8), CHSV(0, 255, 8), // Fire palette definition. Lower value = darker.
CHSV(0, 255, 16), CRGB::Red, CRGB::Red, CRGB::Red,
CRGB::DarkOrange, CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
@@ -7242,7 +7242,7 @@ void mode_DJLight(void) { // Written by ??? Adapted by Will Ta
if (SEGENV.aux0 != secondHand) { // Triggered millis timing.
SEGENV.aux0 = secondHand;
CRGB color = CRGB(gamma8inv(fftResult[15]/2), gamma8inv(fftResult[5]/2), gamma8inv(fftResult[0]/2)); // apply gamma inversion to restor pre 16.0 looks
CRGB color = CRGB(fftResult[15]/2, fftResult[5]/2, fftResult[0]/2); // 16-> 15 as 16 is out of bounds
SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[4], 0, 255, 255, 4))); // TODO - Update
// if SEGLEN equals 1 these loops won't execute
@@ -7322,7 +7322,7 @@ void mode_freqmatrix(void) { // Freqmatrix. By Andreas Pleschung.
uint8_t i = lowerLimit!=upperLimit ? map(FFT_MajorPeak, lowerLimit, upperLimit, 0, 255) : FFT_MajorPeak; // may under/overflow - so we enforce uint8_t
unsigned b = 255 * intensity;
if (b > 255) b = 255;
color = CHSV(i, 240, gamma8inv(b)); // use gamma inversion on brightness to restore pre 16.0 looks
color = CHSV(i, 240, (uint8_t)b); // implicit conversion to RGB supplied by FastLED
}
// shift the pixels one pixel up
@@ -7413,7 +7413,7 @@ void mode_freqwave(void) { // Freqwave. By Andreas Pleschung.
int lowerLimit = 80 + 3 * SEGMENT.custom1;
uint8_t i = lowerLimit!=upperLimit ? map(FFT_MajorPeak, lowerLimit, upperLimit, 0, 255) : FFT_MajorPeak; // may under/overflow - so we enforce uint8_t
unsigned b = min(255.0f, 255.0f * intensity);
color = CHSV(i, 240, gamma8inv(b)); // use gamma inversion on brightness to restore pre 16.0 looks
color = CHSV(i, 240, (uint8_t)b); // implicit conversion to RGB supplied by FastLED
}
SEGMENT.setPixelColor(SEGLEN/2, color);
@@ -7520,7 +7520,7 @@ void mode_waterfall(void) { // Waterfall. By: Andrew Tuline
unsigned k = SEGLEN-1;
if (samplePeak) {
pixels[k] = (uint32_t)CRGB(CHSV(92,92,gamma8inv(92))); // use gamma inversion on brightness to restore pre 16.0 looks
pixels[k] = (uint32_t)CRGB(CHSV(92,92,92));
} else {
pixels[k] = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(pixCol+SEGMENT.intensity, false, PALETTE_SOLID_WRAP, 0), (uint8_t)my_magnitude);
}
@@ -7631,7 +7631,7 @@ void mode_2DFunkyPlank(void) { // Written by ??? Adapted by Will Ta
int v = map(fftResult[band % 16], 0, 255, 10, 255);
for (int w = 0; w < barWidth; w++) {
int xpos = (barWidth * b) + w;
SEGMENT.setPixelColorXY(xpos, 0, CHSV(hue, 255, gamma8inv(v))); // use gamma inversion on brightness to restore original pre 16.0 looks
SEGMENT.setPixelColorXY(xpos, 0, CHSV(hue, 255, v));
}
}
@@ -7980,7 +7980,7 @@ void mode_2Doctopus() {
byte radius = rMap[XY(x,y)].radius;
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
unsigned intensity = sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1));
//intensity = map((intensity*intensity) & 0xFFFF, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display -> no longer needed with proper gamma correction
intensity = map((intensity*intensity) & 0xFFFF, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity));
}
}
+2 -4
View File
@@ -42,7 +42,7 @@
#define DEFAULT_MODE (uint8_t)0
#define DEFAULT_SPEED (uint8_t)128
#define DEFAULT_INTENSITY (uint8_t)128
#define DEFAULT_COLOR (uint32_t)0xFFA000
#define DEFAULT_COLOR (uint32_t)0xFFAA00
#define DEFAULT_C1 (uint8_t)128
#define DEFAULT_C2 (uint8_t)128
#define DEFAULT_C3 (uint8_t)16
@@ -562,7 +562,7 @@ class Segment {
public:
Segment(uint16_t sStart=0, uint16_t sStop=30, uint16_t sStartY = 0, uint16_t sStopY = 1)
: colors{BLACK,BLACK,BLACK} // set colors to black, will be updated to orange if segment is created as "auto segment" or from UI
: colors{DEFAULT_COLOR,BLACK,BLACK}
, start(sStart)
, stop(sStop > sStart ? sStop : sStart+1) // minimum length is 1
, startY(sStartY)
@@ -618,7 +618,6 @@ class Segment {
DEBUGFX_PRINTLN();
#endif
clearName();
stopTransition(); // deallocate "_t" (transition) and with it "_segOld" note: _segOld has _t=null, see copy constructor
#ifdef WLED_ENABLE_GIF
endImagePlayback(this);
#endif
@@ -880,7 +879,6 @@ class WS2812FX {
printSize(), // prints memory usage for strip components
#endif
finalizeInit(), // initialises strip components
updatePixelBuffer(), // (re)allocate memory for _pixels[]
service(), // executes effect functions when due and calls strip.show()
setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K)
setBrightness(uint8_t b, bool direct = false), // sets strip brightness
+78 -69
View File
@@ -98,7 +98,7 @@ Segment& Segment::operator= (const Segment &orig) {
if (this != &orig) {
// clean destination
if (name) { p_free(name); name = nullptr; }
stopTransition(); // delete _t
if (_t) stopTransition(); // also erases _t
deallocateData();
p_free(pixels);
pixels = nullptr;
@@ -131,7 +131,7 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
//DEBUG_PRINTF_P(PSTR("-- Moving segment: %p -> %p\n"), &orig, this);
if (this != &orig) {
if (name) { p_free(name); name = nullptr; } // free old name
stopTransition(); // delete _t
if (_t) stopTransition(); // also erases _t
deallocateData(); // free old runtime data
p_free(pixels); // free old pixel buffer
// move source data
@@ -290,8 +290,6 @@ void Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
}
// starting a transition has to occur before change so we get current values 1st
// note: _t is the temporary segment that holds the values transitioned from (palette, colors, brightness,...) and the current segment holds the "to" values
// if this is a non FADE transition or an FX change, the _oldSegment is created which is a full copy of the segment before the change
void Segment::startTransition(uint16_t dur, bool segmentCopy) {
if (dur == 0 || !isActive()) {
if (isInTransition()) _t->_dur = 0;
@@ -301,42 +299,15 @@ void Segment::startTransition(uint16_t dur, bool segmentCopy) {
if (segmentCopy && !_t->_oldSegment) {
// already in transition but segment copy requested and not yet created
_t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings
_t->_start = millis(); // restart transition timer
_t->_start = millis(); // restart countdown
_t->_dur = dur;
_t->_prevPaletteBlends = 0; // reset palette blends
_t->_prevPaletteBlends = 0;
if (_t->_oldSegment) {
_t->_oldSegment->palette = _t->_palette; // restore original palette, colors, brightness and CCT (from start of transition)
_t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition)
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];
_t->_oldSegment->opacity = _t->_bri;
_t->_oldSegment->cct = _t->_cct;
// if already partway through a FADE transition, set old segment's colors to current blend to avoid jumping back to original colors
if (_t->_progress > 0) {
// already in a transition, see comment below
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = color_blend16(_t->_colors[i], colors[i], _t->_progress);
_t->_oldSegment->opacity = currentBri(); // update "original" brightness note: _t->_progress is updated in updateTransitionProgress() so still valid here
_t->_oldSegment->cct = currentCCT(); // update "original" CCT (reduces jump)
}
DEBUGFX_PRINTF_P(PSTR("-- Updated transition with segment copy: S=%p T(%p) O[%p] OP[%p]\n"), this, _t, _t->_oldSegment, _t->_oldSegment->pixels);
if (!_t->_oldSegment->isActive()) stopTransition();
}
} else if (_t->_progress > 0) {
// already in a transition: capture the current visual blend as the new "from" state so the incoming change does not cause a visible jump.
// _palT already holds the intermediate blended palette and will continue blending toward the new target (see beginDraw()), so no palette action needed.
// initial version by @blazoncek (https://github.com/blazoncek/WLED/commit/40d9812)
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_colors[i] = color_blend16(_t->_colors[i], colors[i], _t->_progress);
_t->_bri = currentBri(); // update "original" brightness note: _t->_progress is updated in updateTransitionProgress() so still valid here
_t->_cct = currentCCT(); // update "original" CCT (reduces jump)
// restart transition timer only if a pure FADE transition, otherwise let the FX change or non-FADE transition finish
// this avoids a re-start of the transition if color or brightness is changed during an ongoing FX or non-FADE transition
if (blendingStyle == TRANSITION_FADE) {
if (_t->_oldSegment != nullptr) {
if (_t->_oldSegment->mode != mode)
return; // do not reset transition if this is an FX change, note: the disadvantage is that colors still jump in that case
}
_t->_start = millis();
_t->_dur = dur;
_t->_prevPaletteBlends = 0;
}
}
return;
}
@@ -362,7 +333,6 @@ void Segment::startTransition(uint16_t dur, bool segmentCopy) {
}
void Segment::stopTransition() {
if (_t == nullptr) return; // no ongoing transition
DEBUG_PRINTF_P(PSTR("-- Stopping transition: S=%p T(%p) O[%p]\n"), this, _t, _t->_oldSegment);
delete _t;
_t = nullptr;
@@ -395,7 +365,7 @@ uint8_t Segment::currentBri() const {
if (prog < 0xFFFFU) {
// this will blend opacity in new mode if style is FADE (single effect call)
if (blendingStyle == TRANSITION_FADE) curBri = (prog * curBri + _t->_bri * (0xFFFFU - prog)) / 0xFFFFU;
else curBri = Segment::isPreviousMode() ? _t->_bri : curBri;
else curBri = Segment::isPreviousMode() ? _t->_bri : curBri;
}
return curBri;
}
@@ -482,7 +452,7 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
DEBUGFX_PRINTF_P(PSTR("Segment geometry: %d,%d -> %d,%d [%d,%d]\n"), (int)i1, (int)i2, (int)i1Y, (int)i2Y, (int)grp, (int)spc);
markForReset();
stopTransition(); // we can't use transition if segment dimensions changed
if (_t) stopTransition(); // we can't use transition if segment dimensions changed
stateChanged = true; // send UDP/WS broadcast
// apply change immediately
@@ -1147,11 +1117,11 @@ void Segment::blur(uint8_t blur_amount, bool smear) const {
* Rotates the color in HSV space, where pos is H. (0=0deg, 256=360deg)
*/
uint32_t Segment::color_wheel(uint8_t pos) const {
if (palette) return color_from_palette(pos, false, true, 0); // color_wheel is a continuous (moving) wheel, so wrap end->start (restores pre-0.16 behaviour)
if (palette) return color_from_palette(pos, false, false, 0); // only wrap if "always wrap" is set
uint8_t w = W(getCurrentColor(0));
CRGBW rgb;
rgb = CHSV32(static_cast<uint16_t>(pos << 8), 255, 255);
rgb.w = W(getCurrentColor(0)); // add white channel
return rgb.color32;
return rgb.color32 | (w << 24); // add white channel
}
/*
@@ -1302,17 +1272,11 @@ void WS2812FX::finalizeInit() {
deserializeMap(); // (re)load default ledmap (will also setUpMatrix() if ledmap does not exist)
// allocate frame buffer after matrix has been set up (gaps!)
updatePixelBuffer();
DEBUG_PRINTF_P(PSTR("Heap after strip init: %uB\n"), getFreeHeapSize());
}
// update global _pixels[] buffer to match getLengthTotal() note: if allocation fails, WLED will not render anything
void WS2812FX::updatePixelBuffer() {
uint32_t requiredMem = getLengthTotal() * sizeof(uint32_t);
p_free(_pixels); // using realloc on large buffers can cause additional fragmentation instead of reducing it
// use PSRAM if available: there is no measurable perfomance impact between PSRAM and DRAM on S2/S3 with QSPI PSRAM for this buffer
_pixels = static_cast<uint32_t*>(allocate_buffer(requiredMem, BFRALLOC_ENFORCE_PSRAM | BFRALLOC_NOBYTEACCESS | BFRALLOC_CLEAR));
DEBUG_PRINTF_P(PSTR("strip buffer size: %uB\n"), requiredMem);
_pixels = static_cast<uint32_t*>(allocate_buffer(getLengthTotal() * sizeof(uint32_t), BFRALLOC_ENFORCE_PSRAM | BFRALLOC_NOBYTEACCESS | BFRALLOC_CLEAR));
DEBUG_PRINTF_P(PSTR("strip buffer size: %uB\n"), getLengthTotal() * sizeof(uint32_t));
DEBUG_PRINTF_P(PSTR("Heap after strip init: %uB\n"), getFreeHeapSize());
}
void WS2812FX::service() {
@@ -1418,6 +1382,7 @@ static uint8_t _dummy (uint8_t a, uint8_t b) { return a; } // dummy (same as
void WS2812FX::blendSegment(const Segment &topSegment) const {
typedef uint8_t(*FuncType)(uint8_t, uint8_t);
// function pointer array: fill with _dummy if using special case: avoid OOB access and always provide a valid path
// note: making the function array static const uses more ram and comes at no significant speed gain
FuncType funcs[] = {
_dummy, _dummy, _dummy, _subtract,
_difference, _average, _dummy, _divide,
@@ -1449,14 +1414,71 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
const size_t matrixSize = Segment::maxWidth * Segment::maxHeight;
const size_t startIndx = XY(topSegment.start, topSegment.startY);
const size_t stopIndx = startIndx + length;
const unsigned progress = topSegment.progress();
const unsigned progInv = 0xFFFFU - progress;
uint8_t opacity = topSegment.currentBri(); // returns transitioned opacity for style FADE
uint8_t cct = topSegment.currentCCT();
if (gammaCorrectCol) opacity = gamma8inv(opacity); // use inverse gamma on brightness for correct color scaling after gamma correction (see #5343 for details)
Segment::setClippingRect(0, 0); // disable clipping by default
const Segment *segO = topSegment.getOldSegment();
const bool hasGrouping = topSegment.groupLength() != 1;
// fast path: handle the default case - no transitions, no grouping/spacing, no mirroring, no CCT
if (!segO && blendingStyle == TRANSITION_FADE && !hasGrouping && !topSegment.mirror && !topSegment.mirror_y) {
if (isMatrix && stopIndx <= matrixSize && !_pixelCCT) {
#ifndef WLED_DISABLE_2D
// Calculate pointer steps to avoid 'if' and 'XY()' inside loops
int x_inc = 1;
int y_inc = Segment::maxWidth;
int start_offset = XY(topSegment.start, topSegment.startY);
// adjust starting position and steps based on Reverse/Transpose
// note: transpose is handled in separate loop so it is still fast and no branching is needed in default path
if (!topSegment.transpose) {
if (topSegment.reverse) { start_offset += (width - 1); x_inc = -1; }
if (topSegment.reverse_y) { start_offset += (height - 1) * Segment::maxWidth; y_inc = -Segment::maxWidth; }
for (int y = 0; y < height; y++) {
uint32_t* pRow = &_pixels[start_offset + y * y_inc];
const int y_width = y * width;
for (int x = 0; x < width; x++) {
uint32_t* p = pRow + x * x_inc;
uint32_t c_a = topSegment.getPixelColorRaw(x + y_width);
*p = color_blend(*p, segblend(c_a, *p), opacity);
}
}
} else { // transposed
for (int y = 0; y < height; y++) {
const int px = topSegment.reverse ? (height - y - 1) : y; // source pixel: swap y into x, reverse if needed
for (int x = 0; x < width; x++) {
const int py = topSegment.reverse_y ? (width - x - 1) : x; // source pixel: swap x into y, reverse if needed
const uint32_t c_a = topSegment.getPixelColorRaw(px + py * height); // height = virtual width
const size_t idx = XY(topSegment.start + x, topSegment.startY + y); // write logical (non swapped) pixel coordinate
_pixels[idx] = color_blend(_pixels[idx], segblend(c_a, _pixels[idx]), opacity);
}
}
}
return;
#endif
} else if (!isMatrix) {
// 1D fast path, include CCT as it is more common on 1D setups
uint32_t* strip = _pixels;
int start = topSegment.start;
int off = topSegment.offset;
for (int i = 0; i < length; i++) {
uint32_t c_a = topSegment.getPixelColorRaw(i);
int p = topSegment.reverse ? (length - i - 1) : i;
int idx = start + p + off;
if (idx >= topSegment.stop) idx -= length;
strip[idx] = color_blend(strip[idx], segblend(c_a, strip[idx]), opacity);
if (_pixelCCT) _pixelCCT[idx] = cct;
}
return;
}
}
// slow path: handle transitions, grouping/spacing, segments with clipping and CCT pixels
Segment::setClippingRect(0, 0); // disable clipping by default
const unsigned progress = topSegment.progress();
const unsigned progInv = 0xFFFFU - progress;
const unsigned dw = (blendingStyle==TRANSITION_OUTSIDE_IN ? progInv : progress) * width / 0xFFFFU + 1;
const unsigned dh = (blendingStyle==TRANSITION_OUTSIDE_IN ? progInv : progress) * height / 0xFFFFU + 1;
const unsigned orgBS = blendingStyle;
@@ -1517,7 +1539,6 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
#ifndef WLED_DISABLE_2D
const int nCols = topSegment.virtualWidth();
const int nRows = topSegment.virtualHeight();
const Segment *segO = topSegment.getOldSegment();
const int oCols = segO ? segO->virtualWidth() : nCols;
const int oRows = segO ? segO->virtualHeight() : nRows;
@@ -1613,8 +1634,8 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
}
#endif
} else {
// 1D Slow Path
const int nLen = topSegment.virtualLength();
const Segment *segO = topSegment.getOldSegment();
const int oLen = segO ? segO->virtualLength() : nLen;
const auto setMirroredPixel = [&](int i, uint32_t c, uint8_t o) {
@@ -1694,7 +1715,7 @@ void WS2812FX::show() {
if (realtimeMode == REALTIME_MODE_INACTIVE || useMainSegmentOnly || realtimeOverride > REALTIME_OVERRIDE_NONE) {
// clear frame buffer
for (size_t i = 0; i < totalLen; i++) _pixels[i] = BLACK; // memset(_pixels, 0, sizeof(uint32_t) * getLengthTotal());
memset(_pixels, 0, sizeof(uint32_t) * totalLen);
// blend all segments into (cleared) buffer
for (Segment &seg : _segments) if (seg.isActive() && (seg.on || seg.isInTransition())) {
blendSegment(seg); // blend segment's buffer into frame buffer
@@ -1709,9 +1730,6 @@ void WS2812FX::show() {
int oldCCT = Bus::getCCT(); // store original CCT value (since it is global)
// when cctFromRgb is true we implicitly calculate WW and CW from RGB values (cct==-1)
if (cctFromRgb) BusManager::setSegmentCCT(-1);
// use color gamma correction if enabled, not in realtime mode with gamma disabled or currently overriding RT mode
bool useGammaCorrection = gammaCorrectCol && !(realtimeMode && arlsDisableGammaCorrection && !realtimeOverride);
for (size_t i = 0; i < totalLen; i++) {
// when correctWB is true setSegmentCCT() will convert CCT into K with which we can then
// correct/adjust RGB value according to desired CCT value, it will still affect actual WW/CW ratio
@@ -1720,8 +1738,8 @@ void WS2812FX::show() {
}
uint32_t c = _pixels[i]; // need a copy, do not modify _pixels directly (no byte access allowed on ESP32)
if (c > 0 && useGammaCorrection)
c = gamma32(c); // apply gamma correction if enabled note: applying gamma after brightness has too much color loss
if (c > 0 && !(realtimeMode && arlsDisableGammaCorrection))
c = gamma32(c); // apply gamma correction if enabled note: applying gamma after brightness has too much color loss
BusManager::setPixelColor(getMappedPixelIndex(i), c);
}
Bus::setCCT(oldCCT); // restore old CCT for ABL adjustments
@@ -1967,9 +1985,6 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
for (size_t i = 1; i < s; i++) {
_segments.emplace_back(segStarts[i], segStops[i]);
}
for (size_t i = 0; i < _segments.size(); i++) {
_segments[i].colors[0] = DEFAULT_COLOR; // set color to default orange on all segments
}
DEBUGFX_PRINTF_P(PSTR("%d auto segments created.\n"), _segments.size());
} else {
@@ -2065,13 +2080,10 @@ bool WS2812FX::deserializeMap(unsigned n) {
customMappingSize = 0; // prevent use of mapping if anything goes wrong
currentLedmap = 0;
if (n == 0 || isFile) interfaceUpdateCallMode = CALL_MODE_WS_SEND; // schedule WS update (to inform UI)
uint32_t lengthTotalBefore = strip.getLengthTotal();
if (!isFile && n==0 && isMatrix) {
// 2D panel support creates its own ledmap (on the fly) if a ledmap.json does not exist
setUpMatrix();
if (strip.getLengthTotal() != lengthTotalBefore)
strip.updatePixelBuffer(); // allocate _pixels[] to match new length
return false;
}
@@ -2119,7 +2131,6 @@ bool WS2812FX::deserializeMap(unsigned n) {
int index = atoi(number);
if (index < 0 || index > 65535) index = 0xFFFF; // prevent integer wrap around
customMappingTable[customMappingSize++] = index;
if (end != nullptr) break; // array closing ']' was in this chunk; stop before atoi() coerces trailing JSON keys into bogus entries
if (customMappingSize >= getLengthTotal()) break;
} else break; // there was nothing to read, stop
}
@@ -2147,8 +2158,6 @@ bool WS2812FX::deserializeMap(unsigned n) {
}
releaseJSONBufferLock();
if (strip.getLengthTotal() != lengthTotalBefore)
strip.updatePixelBuffer(); // allocate _pixels[] to match new length
return (customMappingSize > 0);
}
+23 -35
View File
@@ -351,25 +351,26 @@ void BusDigital::setColorOrder(uint8_t colorOrder) {
// credit @willmmiles & @netmindz https://github.com/wled/WLED/pull/4056
std::vector<LEDType> BusDigital::getLEDTypes() {
return {
{TYPE_WS2812_RGB, "D", PSTR("WS281x RGB")},
{TYPE_WS2811_400KHZ, "D", PSTR("400kHz RGB")},
{TYPE_TM1829, "D", PSTR("TM1829 RGB")},
{TYPE_UCS8903, "D", PSTR("UCS8903 RGB")},
{TYPE_APA106, "D", PSTR("APA106/PL9823 RGB")},
{TYPE_TM1914, "D", PSTR("TM1914 RGB")},
{TYPE_WS2812_RGB, "D", PSTR("WS281x")},
{TYPE_SK6812_RGBW, "D", PSTR("SK6812/WS2814 RGBW")},
{TYPE_TM1814, "D", PSTR("TM1814")},
{TYPE_WS2811_400KHZ, "D", PSTR("400kHz")},
{TYPE_TM1829, "D", PSTR("TM1829")},
{TYPE_UCS8903, "D", PSTR("UCS8903")},
{TYPE_APA106, "D", PSTR("APA106/PL9823")},
{TYPE_TM1914, "D", PSTR("TM1914")},
{TYPE_FW1906, "D", PSTR("FW1906 GRBCW")},
{TYPE_UCS8904, "D", PSTR("UCS8904 RGBW")},
{TYPE_TM1814, "D", PSTR("TM1814 RGBW")},
{TYPE_FW1906, "D", PSTR("FW1906/WS2811 RGBCCT")},
{TYPE_WS2805, "D", PSTR("WS2805 RGBCCT")},
{TYPE_SM16825, "D", PSTR("SM16825 RGBCCT")},
{TYPE_WS2805, "D", PSTR("WS2805 RGBCW")},
{TYPE_SM16825, "D", PSTR("SM16825 RGBCW")},
{TYPE_WS2812_1CH_X3, "D", PSTR("WS2811 White")},
//{TYPE_WS2812_2CH_X3, "D", PSTR("WS281x CCT")}, // not implemented
{TYPE_WS2812_WWA, "D", PSTR("WS281x WWA")}, // amber ignored
{TYPE_WS2801, "2P", PSTR("WS2801 RGB")},
{TYPE_APA102, "2P", PSTR("APA102 RGB")},
{TYPE_LPD8806, "2P", PSTR("LPD8806 RGB")},
{TYPE_LPD6803, "2P", PSTR("LPD6803 RGB")},
{TYPE_P9813, "2P", PSTR("P9813 RGB")},
{TYPE_WS2801, "2P", PSTR("WS2801")},
{TYPE_APA102, "2P", PSTR("APA102")},
{TYPE_LPD8806, "2P", PSTR("LPD8806")},
{TYPE_LPD6803, "2P", PSTR("LPD6803")},
{TYPE_P9813, "2P", PSTR("PP9813")},
};
}
@@ -610,7 +611,7 @@ std::vector<LEDType> BusPwm::getLEDTypes() {
{TYPE_ANALOG_2CH, "AA", PSTR("PWM CCT")},
{TYPE_ANALOG_3CH, "AAA", PSTR("PWM RGB")},
{TYPE_ANALOG_4CH, "AAAA", PSTR("PWM RGBW")},
{TYPE_ANALOG_5CH, "AAAAA", PSTR("PWM RGBCCT")},
{TYPE_ANALOG_5CH, "AAAAA", PSTR("PWM RGB+CCT")},
//{TYPE_ANALOG_6CH, "AAAAAA", PSTR("PWM RGB+DCCT")}, // unimplementable ATM
};
}
@@ -812,7 +813,6 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc.
// mxconfig.driver = HUB75_I2S_CFG::ICN2038S; // experimental - use specific shift register driver
// mxconfig.driver = HUB75_I2S_CFG::FM6124; // try this driver in case you panel stays dark, or when colors look too pastel
// Other possible shiftreg drivers: HUB75_I2S_CFG::FM6126A, HUB75_I2S_CFG::ICN2038S, HUB75_I2S_CFG::MBI5124, HUB75_I2S_CFG::DP3246
// mxconfig.latch_blanking = 3;
// mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M; // experimental - 5MHZ should be enugh, but colours looks slightly better at 10MHz
@@ -824,13 +824,8 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc.
mxconfig.chain_length = max((uint8_t) 1, min(chainLength, (uint8_t) 4));
if (mxconfig.mx_height >= 64 && (mxconfig.chain_length > 1)) {
#if defined(BOARD_HAS_PSRAM) // limitation to one panel only applies to boards without PSRAM
if (!psramFound() || ESP.getPsramSize() == 0) // PSRAM sanity check
#endif
{
DEBUGBUS_PRINTLN(F("WARNING, only single panel can be used of 64 pixel boards due to memory"));
mxconfig.chain_length = 1;
}
DEBUGBUS_PRINTLN(F("WARNING, only single panel can be used of 64 pixel boards due to memory"));
mxconfig.chain_length = 1;
}
if (bc.type == TYPE_HUB75MATRIX_HS) {
@@ -840,7 +835,6 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc.
_isVirtual = true;
mxconfig.mx_width = min((uint8_t) 64, panelWidth) * 2;
mxconfig.mx_height = min((uint8_t) 64, panelHeight) / 2;
mxconfig.driver = HUB75_I2S_CFG::FM6124; // use FM6124 for "outdoor" 4-scan panels - workaround until we can make the driver user-configurable
} else {
DEBUGBUS_PRINTLN("Unknown type");
return;
@@ -880,12 +874,6 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc.
// HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN};
mxconfig.gpio = { 1, 5, 6, 7, 13, 9, 16, 48, 47, 21, 38, 8, 4, 18 };
#elif defined(WAVESHARE_S3_PINOUT)
DEBUGBUS_PRINTLN("MatrixPanel_I2S_DMA - Waveshare S3 with PSRAM, Waveshare pinout");
// HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN};
mxconfig.gpio = {4, 5, 6, 7, 15, 16, 18, 8, 3, 42, 9, 40, 2, 41};
#else
DEBUGBUS_PRINTLN("MatrixPanel_I2S_DMA - S3 with PSRAM");
// HUB75_I2S_CFG::i2s_pins _pins={R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN};
@@ -1002,8 +990,10 @@ BusHub75Matrix::BusHub75Matrix(const BusConfig &bc) : Bus(bc.type, bc.start, bc.
}
setBitArray(_ledsDirty, _len, false); // reset dirty bits
// create LEDs buffer (initialized to BLACK), prefer DRAM if enough heap is available (faster in case global _pixels buffer is in PSRAM as not both will fit the cache)
_ledBuffer = static_cast<CRGB*>(allocate_buffer(_len * sizeof(CRGB), BFRALLOC_PREFER_DRAM | BFRALLOC_CLEAR));
if (mxconfig.double_buff == false) {
// create LEDs buffer (initialized to BLACK), prefer DRAM if enough heap is available (faster in case global _pixels buffer is in PSRAM as not both will fit the cache)
_ledBuffer = static_cast<CRGB*>(allocate_buffer(_len * sizeof(CRGB), BFRALLOC_PREFER_DRAM | BFRALLOC_CLEAR));
}
}
PANEL_CHAIN_TYPE chainType = CHAIN_NONE; // default for quarter-scan panels that do not use chaining
@@ -1134,8 +1124,6 @@ void BusHub75Matrix::cleanup() {
if (display != nullptr) delete display;
display = nullptr;
virtualDisp = nullptr; // note: when not using "NO_GFX" this causes a memory leak
#else // runtime reconfiguration is not working on -S3, request reboot from user instead
errorFlag = ERR_REBOOT_NEEDED;
#endif
if (_ledBuffer != nullptr) d_free(_ledBuffer); _ledBuffer = nullptr;
if (_ledsDirty != nullptr) d_free(_ledsDirty); _ledsDirty = nullptr;
+3 -2
View File
@@ -184,9 +184,10 @@ class Bus {
type == TYPE_NET_DDP_RGBW || type == TYPE_NET_ARTNET_RGBW; // network types with white channel
}
static constexpr bool hasCCT(uint8_t type) {
return type == TYPE_WS2812_WWA || type == TYPE_SM16825 ||
return type == TYPE_WS2812_2CH_X3 || type == TYPE_WS2812_WWA ||
type == TYPE_ANALOG_2CH || type == TYPE_ANALOG_5CH ||
type == TYPE_FW1906 || type == TYPE_WS2805;
type == TYPE_FW1906 || type == TYPE_WS2805 ||
type == TYPE_SM16825;
}
static constexpr bool isTypeValid(uint8_t type) { return (type > 15 && type < 128); }
static constexpr bool isDigital(uint8_t type) { return (type >= TYPE_DIGITAL_MIN && type <= TYPE_DIGITAL_MAX) || is2Pin(type); }
+15 -14
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#ifndef BusWrapper_h
#define BusWrapper_h
@@ -50,7 +50,7 @@
#define I_8266_U1_UCS_4 26
#define I_8266_DM_UCS_4 27
#define I_8266_BB_UCS_4 28
//FW1906 GRBCCT
//FW1906 GRBCW
#define I_8266_U0_FW6_5 29
#define I_8266_U1_FW6_5 30
#define I_8266_DM_FW6_5 31
@@ -60,7 +60,7 @@
#define I_8266_U1_APA106_3 34
#define I_8266_DM_APA106_3 35
#define I_8266_BB_APA106_3 36
//WS2805 (RGBCCT)
//WS2805 (RGBCW)
#define I_8266_U0_2805_5 37
#define I_8266_U1_2805_5 38
#define I_8266_DM_2805_5 39
@@ -70,7 +70,7 @@
#define I_8266_U1_TM1914_3 42
#define I_8266_DM_TM1914_3 43
#define I_8266_BB_TM1914_3 44
//SM16825 (RGBCCT)
//SM16825 (RGBCW)
#define I_8266_U0_SM16825_5 45
#define I_8266_U1_SM16825_5 46
#define I_8266_DM_SM16825_5 47
@@ -98,19 +98,19 @@
//UCS8904 (RGBW)
#define I_32_RN_UCS_4 25
#define I_32_I2_UCS_4 26
//FW1906 GRBCCT 6 color channels
//FW1906 GRBCW
#define I_32_RN_FW6_5 29
#define I_32_I2_FW6_5 30
//APA106
#define I_32_RN_APA106_3 33
#define I_32_I2_APA106_3 34
//WS2805 (RGBCCT)
//WS2805 (RGBCW)
#define I_32_RN_2805_5 37
#define I_32_I2_2805_5 38
//TM1914 (RGB)
#define I_32_RN_TM1914_3 41
#define I_32_I2_TM1914_3 42
//SM16825 (RGBCCT)
//SM16825 (RGBCW)
#define I_32_RN_SM16825_5 45
#define I_32_I2_SM16825_5 46
@@ -180,12 +180,12 @@
#define B_8266_U1_APA106_3 NeoPixelBus<NeoRbgFeature, NeoEsp8266Uart1Apa106Method> //3 chan, esp8266, gpio2
#define B_8266_DM_APA106_3 NeoPixelBus<NeoGrbFeature, NeoEsp8266DmaApa106Method> //3 chan, esp8266, gpio3
#define B_8266_BB_APA106_3 NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBangApa106Method> //3 chan, esp8266, bb (any pin but 16)
//FW1906 GRBCCT
//FW1906 GRBCW
#define B_8266_U0_FW6_5 NeoPixelBus<NeoGrbcwxFeature, NeoEsp8266Uart0Ws2813Method> //esp8266, gpio1
#define B_8266_U1_FW6_5 NeoPixelBus<NeoGrbcwxFeature, NeoEsp8266Uart1Ws2813Method> //esp8266, gpio2
#define B_8266_DM_FW6_5 NeoPixelBus<NeoGrbcwxFeature, NeoEsp8266Dma800KbpsMethod> //esp8266, gpio3
#define B_8266_BB_FW6_5 NeoPixelBus<NeoGrbcwxFeature, NeoEsp8266BitBang800KbpsMethod> //esp8266, bb
//WS2805 GRBCCT
//WS2805 GRBCW
#define B_8266_U0_2805_5 NeoPixelBus<NeoGrbwwFeature, NeoEsp8266Uart0Ws2805Method> //esp8266, gpio1
#define B_8266_U1_2805_5 NeoPixelBus<NeoGrbwwFeature, NeoEsp8266Uart1Ws2805Method> //esp8266, gpio2
#define B_8266_DM_2805_5 NeoPixelBus<NeoGrbwwFeature, NeoEsp8266DmaWs2805Method> //esp8266, gpio3
@@ -195,7 +195,7 @@
#define B_8266_U1_TM1914_3 NeoPixelBus<NeoRgbTm1914Feature, NeoEsp8266Uart1Tm1914Method>
#define B_8266_DM_TM1914_3 NeoPixelBus<NeoRgbTm1914Feature, NeoEsp8266DmaTm1914Method>
#define B_8266_BB_TM1914_3 NeoPixelBus<NeoRgbTm1914Feature, NeoEsp8266BitBangTm1914Method>
//Sm16825 (RGBCCT)
//Sm16825 (RGBWC)
#define B_8266_U0_SM16825_5 NeoPixelBus<NeoRgbwcSm16825eFeature, NeoEsp8266Uart0Ws2813Method>
#define B_8266_U1_SM16825_5 NeoPixelBus<NeoRgbwcSm16825eFeature, NeoEsp8266Uart1Ws2813Method>
#define B_8266_DM_SM16825_5 NeoPixelBus<NeoRgbwcSm16825eFeature, NeoEsp8266Dma800KbpsMethod>
@@ -285,11 +285,11 @@
#define B_32_RN_APA106_3 NeoPixelBus<NeoGrbFeature, NeoEsp32RmtMethod(Apa106)>
#define B_32_I2_APA106_3 NeoPixelBus<NeoGrbFeature, X1Apa106Method>
#define B_32_IP_APA106_3 NeoPixelBus<NeoGrbFeature, X8Apa106Method> // parallel I2S
//FW1906 GRBCCT 6 color channels
//FW1906 GRBCW
#define B_32_RN_FW6_5 NeoPixelBus<NeoGrbcwxFeature, NeoEsp32RmtMethod(Ws2812x)>
#define B_32_I2_FW6_5 NeoPixelBus<NeoGrbcwxFeature, X1800KbpsMethod>
#define B_32_IP_FW6_5 NeoPixelBus<NeoGrbcwxFeature, X8800KbpsMethod> // parallel I2S
//WS2805 RGBCCT
//WS2805 RGBWC
#define B_32_RN_2805_5 NeoPixelBus<NeoGrbwwFeature, NeoEsp32RmtMethod(Ws2805)>
#define B_32_I2_2805_5 NeoPixelBus<NeoGrbwwFeature, X1Ws2805Method>
#define B_32_IP_2805_5 NeoPixelBus<NeoGrbwwFeature, X8Ws2805Method> // parallel I2S
@@ -297,7 +297,7 @@
#define B_32_RN_TM1914_3 NeoPixelBus<NeoGrbTm1914Feature, NeoEsp32RmtMethod(Tm1914)>
#define B_32_I2_TM1914_3 NeoPixelBus<NeoGrbTm1914Feature, X1Tm1914Method>
#define B_32_IP_TM1914_3 NeoPixelBus<NeoGrbTm1914Feature, X8Tm1914Method> // parallel I2S
//Sm16825 (RGBCCT)
//Sm16825 (RGBWC)
#define B_32_RN_SM16825_5 NeoPixelBus<NeoRgbcwSm16825eFeature, NeoEsp32RmtMethod(Ws2812x)>
#define B_32_I2_SM16825_5 NeoPixelBus<NeoRgbcwSm16825eFeature, X1Ws2812xMethod>
#define B_32_IP_SM16825_5 NeoPixelBus<NeoRgbcwSm16825eFeature, X8Ws2812xMethod> // parallel I2S
@@ -358,7 +358,6 @@ class PolyBus {
#ifdef ESP8266
dotStar_strip->Begin();
#else
if (miso == -1) miso = 127; // note: in arduino core, -1 means "default" not "none", passing 127 as the MISO pin is a workaround to prevent SPI.begin() assign the default pin, see #5670
if (sck == -1 && mosi == -1) dotStar_strip->Begin();
else dotStar_strip->Begin(sck, miso, mosi, ss);
#endif
@@ -1316,6 +1315,7 @@ class PolyBus {
if (offset > 3) offset = 3;
switch (busType) {
case TYPE_WS2812_1CH_X3:
case TYPE_WS2812_2CH_X3:
case TYPE_WS2812_RGB:
case TYPE_WS2812_WWA:
t = I_8266_U0_NEO_3 + offset; break;
@@ -1358,6 +1358,7 @@ class PolyBus {
// Now determine actual bus type with the chosen offset
switch (busType) {
case TYPE_WS2812_1CH_X3:
case TYPE_WS2812_2CH_X3:
case TYPE_WS2812_RGB:
case TYPE_WS2812_WWA:
t = I_32_RN_NEO_3 + offset; break;
+1 -12
View File
@@ -319,7 +319,7 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#define TYPE_DIGITAL_MIN 16 // first usable digital type
#define TYPE_WS2812_1CH 18 //white-only chips (1 channel per IC) (unused)
#define TYPE_WS2812_1CH_X3 19 //white-only chips (3 channels per IC)
//#define TYPE_WS2812_2CH_X3 20 // use FW1906
#define TYPE_WS2812_2CH_X3 20 //CCT chips (1st IC controls WW + CW of 1st zone and CW of 2nd zone, 2nd IC controls WW of 2nd zone and WW + CW of 3rd zone)
#define TYPE_WS2812_WWA 21 //amber + warm + cold white
#define TYPE_WS2812_RGB 22
#define TYPE_GS8608 23 //same driver as WS2812, but will require signal 2x per second (else displays test pattern)
@@ -472,17 +472,6 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
#define ERR_UNDERVOLT 32 // An attached voltmeter has measured a voltage below the threshold (not implemented)
#define ERR_LOW_MEM 33 // low memory (RAM)
#define ERR_LOW_SEG_MEM 34 // low memory (effect data RAM)
#define ERR_LOW_WS_MEM 35 // low memory (ws)
//#define ERR_LOW_AJAX_MEM 36 // (not used any more) low memory (oappend)
#define ERR_LOW_BUF 37 // low memory (LED pixels buffer)
#define ERR_SYS_REBOOT 90 // reboot after error, trying to roll back
#define ERR_SYS_BROWNOUT 91 // reboot after brownout alert
#define ERR_PERSISTENT_THRESHOLD 100 // ToDO: errors below this value are non-persistent; persistent errors stay in the UI until restart
// ERR_PERSISTENT_THRESHOLD is a threshold value only - never assign directly to errorFlag
#define ERR_REBOOT_NEEDED 100 // reboot needed after changing hardware setting
#define ERR_POWEROFF_NEEDED 101 // power-cycle needed after changing hardware setting
// JSON buffer lock owners
#define JSON_LOCK_UNKNOWN 255
+10 -31
View File
@@ -1567,36 +1567,8 @@ function readState(s,command=false)
case 19:
errstr = "A filesystem error has occured.";
break;
// error code from WLEDMM - not supported yet
// case 33:
// errstr = "Low Memory (generic RAM).";
// break;
// case 34:
// errstr = "Low Memory (effect data).";
// break;
// case 35:
// errstr = "Low Memory (WS data).";
// break;
// case 36:
// errstr = "Low Memory (oappend buffer).";
// break;
// case 37:
// errstr = "no memory for LEDs buffer.";
// break;
case 90:
errstr = "Unexpected Restart.";
break;
case 91:
errstr = "Brownout Restart.";
break;
case 100:
errstr = "Please reboot WLED to activate changed settings.";
break;
case 101:
errstr = "Please switch your device off and back on.";
break;
}
showToast(((s.error<100) ? 'Error ': 'Note ') + s.error + ": " + errstr, true); // show "please restart" as a note, all others as errors
showToast('Error ' + s.error + ": " + errstr, true);
}
selectedPal = i.pal;
@@ -2846,7 +2818,14 @@ function rSegs()
cnfrS = false;
bt.style.color = "var(--c-f)";
bt.innerHTML = "Reset segments";
requestJson({"rSeg": true}); // send reset segment request, calls makeAutoSegments() in firmware
var obj = {"seg":[{"start":0,"stop":ledCount,"sel":true}]};
if (isM) {
obj.seg[0].stop = mw;
obj.seg[0].startX = 0;
obj.seg[0].stopY = mh;
}
for (let i=1; i<=lSeg; i++) obj.seg.push({"stop":0});
requestJson(obj);
}
function loadPalettesData() {
@@ -3618,4 +3597,4 @@ _C.addEventListener('touchstart', lock, false);
_C.addEventListener('mouseout', move, false);
_C.addEventListener('mouseup', move, false);
_C.addEventListener('touchend', move, false);
_C.addEventListener('touchend', move, false);
+2 -1
View File
@@ -1126,7 +1126,8 @@ Swap: <select id="xw${s}" name="XW${s}">
<div class="sec">
<h3>Power up</h3>
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
Bootup brightness: <input name="CA" type="number" class="m" min="1" max="255" required> (1-255)<br><br>
with brightness: <input name="CA" type="number" class="m" min="1" max="255" required> (1-255)<br>
<i>(disable if using boot preset to turn LEDs on)</i><br><br>
Apply preset <input name="BP" type="number" class="m" min="0" max="250" required> at boot (0 = none)<br><br>
</div>
<div class="sec">
+24 -89
View File
@@ -190,7 +190,7 @@
}
}
function pMP() { // populateMacroPresets
var presetOpts = '<option value="0">Default Action (0)</option>' + sortedPresetOptions;
var presetOpts = '<option value="0">Default Action</option>' + sortedPresetOptions;
var fields = ['A0','A1','MC','MN'];
for (var f of fields) {
var inp = gN(f);
@@ -219,38 +219,13 @@
rPS(sel, presetOpts, "data-preset");
}
}
function bAO() { // buildAnalogOptions: analog functions + per-segment opacity (segment 0 included; MD=0 => segment 0)
var o = '<optgroup label="Analog Functions"><option value="250">Global brightness (250)</option><option value="249">Effect speed (249)</option><option value="248">Effect intensity (248)</option><option value="247">Palette (247)</option><option value="200">Primary color hue (200)</option></optgroup><optgroup label="Analog Segment Opacity">';
for (var j=0; j<=32; j++) o += `<option value="${j}">Segment ${j} opacity</option>`;
o += '</optgroup>';
return o;
}
function isAnalogBtn(t) { return t==7 || t==8; } // BTN_TYPE_ANALOG / BTN_TYPE_ANALOG_INVERTED
function isSwitchBtn(t) { return t==4 || t==5 || t==9; } // BTN_TYPE_SWITCH / BTN_TYPE_PIR_SENSOR / BTN_TYPE_TOUCH_SWITCH
function btnTypeName(t) { // mirrors the button type dropdown on the LED settings page
switch (+t) {
case 2: return 'Pushbutton';
case 3: return 'Push inverted';
case 4: return 'Switch';
case 5: return 'PIR sensor';
case 6: return 'Touch';
case 7: return 'Analog';
case 8: return 'Analog inverted';
case 9: return 'Touch (switch)';
default: return 'Disabled';
}
}
function rBPO() { // refreshButtonPresetOptions
var presetOpts = '<option value="0">Default Action (0)</option>' + sortedPresetOptions;
var analogOpts = bAO();
var presetOpts = '<option value="0">Default Action</option>' + sortedPresetOptions;
var container = gId("macros");
if (!container) return;
// analog buttons only have an MD select (MP/ML are hidden 0 inputs); MD uses analog options, never presets
var sels = container.querySelectorAll('select[name^="MP"],select[name^="ML"],select[name^="MD"]');
for (var sel of sels) {
var bb = sel.closest ? sel.closest(".bb") : null;
var t = bb ? parseInt(bb.getAttribute("data-btype")||"0",10) : 0;
rPS(sel, isAnalogBtn(t) ? analogOpts : presetOpts, "data-preset");
rPS(sel, presetOpts, "data-preset");
}
}
function Wd()
@@ -271,73 +246,33 @@
if (d.Sf.LTR.value==="S") { d.Sf.LT.value = -1*parseFloat(d.Sf.LT.value); }
if (d.Sf.LNR.value==="W") { d.Sf.LN.value = -1*parseFloat(d.Sf.LN.value); }
}
function addRow(i,p,l,d,t) {
if (t===undefined) t = 0;
function addRow(i,p,l,d) {
var b = String.fromCharCode((i<10?48:55)+i);
var presetOpts = '<option value="0">Default Action (0)</option>' + sortedPresetOptions;
var typeName = btnTypeName(t);
var presetOpts = '<option value="0">Default Action</option>' + sortedPresetOptions;
var buttonBlock = document.createElement('div');
buttonBlock.className = 'bb';
buttonBlock.setAttribute('data-btype', t); // read back by rBPO() to rebuild selects correctly
if (isAnalogBtn(t)) {
// analog buttons: MD holds the function/segment; short/long press are unused (firmware defaults missing MP/ML to 0)
buttonBlock.innerHTML = `
<div class="bh">Analog ${i} - ${typeName}</div>
<div class="bs">
<div class="ba">
<label>Analog function</label>
<select name="MD${b}" class="s" required>${bAO()}</select>
</div>
buttonBlock.innerHTML = `
<div class="bh">Button ${i}</div>
<div class="bs">
<div class="ba">
<label>Push/Switch</label>
<select name="MP${b}" class="s" required>${presetOpts}</select>
</div>
<hr style="width:100%;margin:8px 0 0 0;">
`;
sPSV(buttonBlock.querySelector('select[name="MD'+b+'"]'), String(d), "data-preset");
} else if (isSwitchBtn(t)) {
// switches: MP fires on On->Off, ML on Off->On; double press (MD) is unused (firmware defaults missing MD to 0)
buttonBlock.innerHTML = `
<div class="bh">Switch ${i} - ${typeName}</div>
<div class="bs">
<div class="ba">
<label>On → Off</label>
<select name="MP${b}" class="s" required>${presetOpts}</select>
</div>
<div class="ba">
<label>Off → On</label>
<select name="ML${b}" class="s" required>${presetOpts}</select>
</div>
<div class="ba">
<label>Short (on→off)</label>
<select name="ML${b}" class="s" required>${presetOpts}</select>
</div>
<hr style="width:100%;margin:8px 0 0 0;">
`;
var switchSels = buttonBlock.querySelectorAll("select");
var switchVals = [String(p), String(l)];
for (var si=0; si<switchSels.length; si++) {
sPSV(switchSels[si], switchVals[si], "data-preset");
}
} else {
// pushbuttons: short (MP), long (ML) and double (MD) press
buttonBlock.innerHTML = `
<div class="bh">Button ${i} - ${typeName}</div>
<div class="bs">
<div class="ba">
<label>Short press</label>
<select name="MP${b}" class="s" required>${presetOpts}</select>
</div>
<div class="ba">
<label>Long press</label>
<select name="ML${b}" class="s" required>${presetOpts}</select>
</div>
<div class="ba">
<label>Double press</label>
<select name="MD${b}" class="s" required>${presetOpts}</select>
</div>
<div class="ba">
<label>Long (off→on)</label>
<select name="MD${b}" class="s" required>${presetOpts}</select>
</div>
<hr style="width:100%;margin:8px 0 0 0;">
`;
var buttonSels = buttonBlock.querySelectorAll("select");
var buttonVals = [String(p), String(l), String(d)];
for (var si=0; si<buttonSels.length; si++) {
sPSV(buttonSels[si], buttonVals[si], "data-preset");
}
</div>
<hr style="width:100%;margin:8px 0 0 0;">
`;
var buttonSels = buttonBlock.querySelectorAll("select");
var buttonVals = [String(p), String(l), String(d)];
for (var si=0; si<buttonSels.length; si++) {
sPSV(buttonSels[si], buttonVals[si], "data-preset");
}
gId("macros").appendChild(buttonBlock);
}
+1 -98
View File
@@ -47,7 +47,6 @@
d.rsvd = [];
d.ro_gpio = [];
d.extra = [];
d.a_pins = []; // analog pins array
}, ()=>{
if (d.um_p[0]==-1) d.um_p.shift(); // remove filler
d.Sf.SDA.max = d.Sf.SCL.max = d.Sf.MOSI.max = d.Sf.SCLK.max = d.Sf.MISO.max = d.max_gpio;
@@ -195,11 +194,7 @@
um += ":"+fld;
} else if (typeof(fld) === "number") sel.classList.add("pin"); // a hack to add a class
let arr = d.getElementsByName(um);
if (!arr || arr.length === 0) {
console.log("addDD: No elements found for name:", um);
return null; // no elements found
}
let idx = (arr[0] && arr[0].type==="hidden")?1:0; // ignore hidden field
let idx = arr[0].type==="hidden"?1:0; // ignore hidden field
if (arr.length > 1+idx) {
// we have array of values (usually pins)
for (let i of arr) {
@@ -261,98 +256,6 @@
e.preventDefault();
if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914
}
// TODO: rename this function, needs to be in sync with the now out of tree mod
function aOpt(name,el) {
let obj = d.getElementsByName(name);
if (!obj || obj.length === 0) return; // No elements found
var select = obj;
if (obj[el]) select = obj[el];
// Check if it's actually a select element with options
if (!select.options || !select.options.length) return;
for (let i=0; i<select.options.length; i++) {
let c = select.options[i];
let found = false;
for (let jj=0; jj<d.a_pins.length; jj++) if (d.a_pins[jj] == c.value) found = true; //value -1 or analog pins
if (c.value != -1 && !found) {
select.removeChild(c);
i--; //decrease i by one because the index has been adjusted
}
//https://www.javascripttutorial.net/javascript-dom/javascript-add-remove-options/
//https://www.javascripttutorial.net/javascript-dom/javascript-remove-items-from-a-select-conditionally/
}
}
function rOpt(name,el,txt,val) {
let obj = d.getElementsByName(name);
if (!obj || obj.length === 0) return; // No elements found
var select = obj;
if (obj[el]) select = obj[el];
// Check if element has childNodes
if (!select.childNodes || !select.childNodes.length) return;
for (let i=0; i<select.childNodes.length; i++) {
let c = select.childNodes[i];
if (c.value == val) c.text = txt;
}
}
function xOpt(name,el,txt,val) {
let obj = d.getElementsByName(name);
if (!obj || obj.length === 0) return; // No elements found
var select = obj;
if (obj[el]) select = obj[el];
// Check if element has childNodes
if (!select.childNodes || !select.childNodes.length) return;
for (let i=0; i<select.childNodes.length; i++) {
let c = select.childNodes[i];
if (c.value == val) c.text += txt;
}
}
function dOpt(name,el,valFrom,valTo) {
let obj = d.getElementsByName(name);
if (!obj || obj.length === 0) return; // No elements found
var select = obj;
if (obj[el]) select = obj[el];
// Check if it's actually a select element with options
if (!select.options || !select.options.length) return;
for (let i=0; i<select.options.length; i++) {
let c = select.options[i];
if (c.value >= valFrom && c.value <= valTo) {
select.removeChild(c);
i--; //decrease i by one because the index has been adjusted
}
//https://www.javascripttutorial.net/javascript-dom/javascript-add-remove-options/
//https://www.javascripttutorial.net/javascript-dom/javascript-remove-items-from-a-select-conditionally/
}
}
function dRO(name,el) {
// Initialize d.ro_gpio if not already set
if (!d.ro_gpio) d.ro_gpio = [];
let obj = d.getElementsByName(name);
if (!obj || obj.length === 0) return; // No elements found
var select = obj;
if (obj[el]) select = obj[el];
// Check if it's actually a select element with options
if (!select.options || !select.options.length) return;
// console.log("dRO", name, el, obj, "s", select, d.ro_gpio);
for (let i=0; i<select.options.length; i++) {
let c = select.options[i];
// console.log("dRO option", c, c.value, d.ro_gpio.includes(c.value));
for (let j=0; j<d.ro_gpio.length; j++) if (d.ro_gpio[j] == c.value) c.disabled=true; //if (d.ro_gpio.includes(c.value))
}
}
</script>
</head>
+11 -1
View File
@@ -106,12 +106,17 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol, size_
handleArtnetPollReply(clientIP);
return;
}
if (packetLen < 18) return; // need art_length (offset 16, 2 bytes) for DMX data
uni = p->art_universe;
dmxChannels = htons(p->art_length);
const int artNetMaxData = (packetLen >= 18) ? (int)(packetLen - 18) : 0; // art_data at offset 18; clamp so e131_data[dmxChannels] stays in bounds
if (dmxChannels > artNetMaxData) dmxChannels = artNetMaxData;
if (dmxChannels > MAX_CHANNELS_PER_UNIVERSE) dmxChannels = MAX_CHANNELS_PER_UNIVERSE;
e131_data = p->art_data;
seq = p->art_sequence_number;
mde = REALTIME_MODE_ARTNET;
} else if (protocol == P_E131) {
if (packetLen < 126) return; // need up to property_values[0] (offset 125) and property_value_count (offset 123)
// Ignore PREVIEW data (E1.31: 6.2.6)
if ((p->options & 0x80) != 0) return;
dmxChannels = htons(p->property_value_count) - 1; // on malformed packets, this can become negative, checked below
@@ -120,6 +125,9 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol, size_
uni = htons(p->universe);
e131_data = p->property_values;
seq = p->sequence_number;
const int e131MaxData = (packetLen > 126) ? (int)(packetLen - 126) : 0; // property_values at offset 125; clamp so e131_data[dmxChannels] stays in bounds
if (dmxChannels > e131MaxData) dmxChannels = e131MaxData;
if (dmxChannels > MAX_CHANNELS_PER_UNIVERSE) dmxChannels = MAX_CHANNELS_PER_UNIVERSE;
if (e131Priority != 0) {
if (p->priority < e131Priority ) return;
// track highest priority & skip all lower priorities
@@ -135,8 +143,10 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, byte protocol, size_
#ifdef WLED_ENABLE_DMX
// does not act on out-of-order packets yet
if (e131ProxyUniverse > 0 && uni == e131ProxyUniverse) {
// Art-Net: art_data is 0-indexed (channel 1 at index 0)
// E1.31: property_values[0] is start code, (channel 1 at index 1)
for (uint16_t i = 1; i <= dmxChannels; i++)
dmx.write(i, e131_data[i]);
dmx.write(i, mde == REALTIME_MODE_ARTNET ? e131_data[i-1] : e131_data[i]);
dmx.update();
}
#endif
-5
View File
@@ -414,11 +414,6 @@ namespace UsermodManager {
// Register usermods by building a static list via a linker section
#define REGISTER_USERMOD(x) DYNARRAY_MEMBER(Usermod*, usermods, um_##x, 1) = &x
//usermod.cpp
void userSetup();
void userConnected();
void userLoop();
//util.cpp
#ifdef ESP8266
#define HW_RND_REGISTER RANDOM_REG32
+1
View File
@@ -188,6 +188,7 @@ static bool appendObjectToFile(const char* key, const JsonDocument* content, uin
if (f.size() < 3) {
char init[10];
strcpy_P(init, PSTR("{\"0\":{}}"));
f.seek(0, SeekSet); // rewind to ensure we overwrite from the start, instead of appending
f.print(init);
}
+1 -1
View File
@@ -30,7 +30,7 @@ int fileReadCallback(void) {
int fileReadBlockCallback(void * buffer, int numberOfBytes) {
#ifdef CONFIG_IDF_TARGET_ESP32C3
unsigned t0 = millis();
while (strip.isUpdating() && (millis() - t0 < 150)) yield(); // be nice, but not too nice. Waits up to 150ms to avoid glitches
while (strip.isUpdating() && (millis() - t0 < 15)) yield(); // be nice, but not too nice. Waits up to 15ms to avoid glitches
#endif
return file.read((uint8_t*)buffer, numberOfBytes);
}
+7 -6
View File
@@ -116,8 +116,8 @@ void handleImprovPacket() {
return;
}
} else if (packetByte > 9) { //RPC data
if (packetByte > 137) return; //prevent buffer overflow
rpcData[packetByte - 10] = next;
if (packetByte > 137) return; //prevent buffer overflow
}
}
}
@@ -238,8 +238,8 @@ void handleImprovWifiScan() {
bool isOpen = WiFi.encryptionType(i) == WIFI_AUTH_OPEN;
#endif
char ssidStr[33] = {'\0'};
strlcpy(ssidStr, WiFi.SSID(i).c_str(), sizeof(ssidStr));
char ssidStr[33];
strcpy(ssidStr, WiFi.SSID(i).c_str());
const char *str[3] = {ssidStr, rssiStr, isOpen ? "NO":"YES"};
sendImprovRPCResult(ImprovRPCType::Request_Scan, 3, str);
}
@@ -258,13 +258,14 @@ static void parseWiFiCommand(char* rpcData) {
unsigned ssidLen = rpcData[1];
if (ssidLen > len -1 || ssidLen > 32) return;
memset(multiWiFi[0].clientSSID, 0, sizeof(multiWiFi[0].clientSSID));
memset(multiWiFi[0].clientSSID, 0, 32);
memcpy(multiWiFi[0].clientSSID, rpcData+2, ssidLen);
memset(multiWiFi[0].clientPass, 0, sizeof(multiWiFi[0].clientPass));
memset(multiWiFi[0].clientPass, 0, 64);
if (len > ssidLen +1) {
unsigned passLen = rpcData[2+ssidLen];
memcpy(multiWiFi[0].clientPass, rpcData+3+ssidLen, min(size_t(passLen), sizeof(multiWiFi[0].clientPass)));
memset(multiWiFi[0].clientPass, 0, 64);
memcpy(multiWiFi[0].clientPass, rpcData+3+ssidLen, passLen);
}
sendImprovStateResponse(0x03); //provisioning
+3 -12
View File
@@ -85,9 +85,6 @@ static bool deserializeSegment(JsonObject elem, byte it, byte presetId = 0)
//DEBUG_PRINTLN(F("-- JSON deserialize segment."));
Segment& seg = strip.getSegment(id);
if (newSeg && presetId == 0) {
seg.colors[0] = DEFAULT_COLOR; // set color of newly created segment to warm orange as an indicator to the user
}
// we do not want to make segment copy as it may use a lot of RAM (effect data and pixel buffer)
// so we will create a copy of segment options and compare it with original segment when done processing
SegmentCopy prev = {
@@ -488,14 +485,6 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
}
strip.resume();
}
// reset segment request
if (root[F("rSeg")] | false) {
strip.suspend();
strip.waitForIt();
strip.makeAutoSegments(true); // respects autoSegments flag
strip.resume();
stateChanged = true;
}
UsermodManager::readFromJsonState(root);
@@ -531,7 +520,9 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (root["win"].isNull() && getVal(root["ps"], presetCycCurr, 1, 250) && presetCycCurr > 0 && presetCycCurr < 251 && presetCycCurr != currentPreset) {
DEBUG_PRINTF_P(PSTR("Preset select: %d\n"), presetCycCurr);
// b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
applyPreset(presetCycCurr, callMode); // async load from file system (only preset ID was specified)
// async load from file system (only preset ID was specified)
// avoid propogating CALL_MODE_INIT, which may cause accidental recursion
applyPreset(presetCycCurr, callMode == CALL_MODE_INIT ? CALL_MODE_DIRECT_CHANGE : callMode);
return stateResponse;
} else presetCycCurr = currentPreset; // restore presetCycCurr
}
+1 -3
View File
@@ -126,6 +126,7 @@ void stateUpdated(byte callMode) {
jsonTransitionOnce = false;
transitionActive = false;
applyFinalBri();
strip.trigger();
} else {
if (transitionActive) {
briOld = briT;
@@ -231,10 +232,7 @@ void handleNightlight() {
{
for (unsigned i=0; i<4; i++) colPri[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
}
uint16_t transitionduration = strip.getTransition();
strip.setTransition(0); // temporary disable transition and set color & brightness directly, (hacky fix for #5620)
colorUpdated(CALL_MODE_NO_NOTIFY);
strip.setTransition(transitionduration); // restore transition time to previous value. Note: this needs proper fixing by disabling transitions completely in nightlight mode, reference implementation https://github.com/blazoncek/WLED/commit/c01a6b774969b652c30e383073958302042fd1f9
}
if (nper >= 1) //nightlight duration over
{
+2 -2
View File
@@ -194,8 +194,8 @@ void handlePresets()
changePreset = true;
} else {
if (!fdo["seg"].isNull() || !fdo["on"].isNull() || !fdo["bri"].isNull() || !fdo["nl"].isNull() || !fdo["ps"].isNull() || !fdo[F("playlist")].isNull()) changePreset = true;
if (!(tmpMode == CALL_MODE_BUTTON_PRESET && fdo["ps"].is<const char *>() && strchr(fdo["ps"].as<const char *>(),'~') != strrchr(fdo["ps"].as<const char *>(),'~')))
fdo.remove("ps"); // remove load request for presets to prevent recursive crash (if not called by button and contains preset cycling string "1~5~")
if (!(tmpMode == CALL_MODE_INIT || (tmpMode == CALL_MODE_BUTTON_PRESET && fdo["ps"].is<const char *>() && strchr(fdo["ps"].as<const char *>(),'~') != strrchr(fdo["ps"].as<const char *>(),'~'))))
fdo.remove("ps"); // remove load request for presets to prevent recursive crash (if not called by boot preset or button which contains preset cycling string "1~5~")
deserializeState(fdo, CALL_MODE_NO_NOTIFY, tmpPreset); // may change presetToApply by calling applyPreset()
}
if (!errorFlag && tmpPreset < 255 && changePreset) currentPreset = tmpPreset;
+16 -16
View File
@@ -110,24 +110,24 @@ void ESPAsyncE131::parsePacket(AsyncUDPPacket _packet) {
protocol = P_E131;
}
if (protocol == P_ARTNET) {
if (pktLen < 10) {
error = true; // Need at least Art-Net ID (8) + opcode (2)
} else {
if (memcmp(sbuff->art_id, ESPAsyncE131::ART_ID, sizeof(sbuff->art_id)))
error = true; //not "Art-Net"
if (sbuff->art_opcode != ARTNET_OPCODE_OPDMX && sbuff->art_opcode != ARTNET_OPCODE_OPPOLL)
error = true; //not a DMX or poll packet
}
if (protocol == P_ARTNET) {
if (memcmp(sbuff->art_id, ESPAsyncE131::ART_ID, sizeof(sbuff->art_id)))
error = true; //not ART_ID = "Art-Net"
if (sbuff->art_opcode != ARTNET_OPCODE_OPDMX && sbuff->art_opcode != ARTNET_OPCODE_OPPOLL)
error = true; //not a DMX or poll packet
} else { //E1.31 error handling
if (htonl(sbuff->root_vector) != ESPAsyncE131::VECTOR_ROOT)
error = true;
if (htonl(sbuff->frame_vector) != ESPAsyncE131::VECTOR_FRAME)
error = true;
if (sbuff->dmp_vector != ESPAsyncE131::VECTOR_DMP)
error = true;
if (sbuff->property_values[0] != 0)
if (pktLen < 126) { // need up to property_values[0] at offset 125
error = true;
} else {
if (htonl(sbuff->root_vector) != ESPAsyncE131::VECTOR_ROOT)
error = true;
if (htonl(sbuff->frame_vector) != ESPAsyncE131::VECTOR_FRAME)
error = true;
if (sbuff->dmp_vector != ESPAsyncE131::VECTOR_DMP)
error = true;
if (sbuff->property_values[0] != 0)
error = true;
}
}
if (error && _packet.localPort() == DDP_DEFAULT_PORT) { //DDP packet
+1 -1
View File
@@ -272,4 +272,4 @@ class E131Priority {
}
};
#endif // ESPASYNCE131_H_
#endif // ESPASYNCE131_H_
-29
View File
@@ -1,29 +0,0 @@
#include "wled.h"
/*
* This v1 usermod file allows you to add own functionality to WLED more easily
* See: https://github.com/wled-dev/WLED/wiki/Add-own-functionality
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h)
* If you just need 8 bytes, use 2551-2559 (you do not need to increase EEPSIZE)
*
* Consider the v2 usermod API if you need a more advanced feature set!
*/
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup()
{
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{
}
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop()
{
}
-11
View File
@@ -8,7 +8,6 @@
#else
#include <Update.h>
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
#include "rom/rtc.h" // for rtc_get_reset_reason()
#include "esp32/rtc.h" // for bootloop detection
#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(3, 3, 0)
#include "soc/rtc.h"
@@ -999,11 +998,6 @@ RTC_NOINIT_ATTR static uint32_t bl_crashcounter;
RTC_NOINIT_ATTR static uint32_t bl_actiontracker;
static inline ResetReason rebootReason() {
// check RTC restart reason first - brownout is not reliably reported by esp_reset_reason()
if (rtc_get_reset_reason(0) == RTCWDT_BROWN_OUT_RESET) return ResetReason::Brownout; // core0 brownout
#if SOC_CPU_CORES_NUM > 1
if (rtc_get_reset_reason(1) == RTCWDT_BROWN_OUT_RESET) return ResetReason::Brownout; // core1 brownout
#endif
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_BROWNOUT) return ResetReason::Brownout;
if (reason == ESP_RST_SW) return ResetReason::Software;
@@ -1038,7 +1032,6 @@ static bool detectBootLoop() {
case ResetReason::Crash:
{
DEBUG_PRINTLN(F("crash detected!"));
errorFlag = ERR_SYS_REBOOT;
uint32_t rebootinterval = rtctime - bl_last_boottime;
if (rebootinterval < BOOTLOOP_INTERVAL_MILLIS) {
bl_crashcounter++;
@@ -1059,7 +1052,6 @@ static bool detectBootLoop() {
case ResetReason::Brownout:
// crash due to brownout can't be detected unless using flash memory to store bootloop variables
DEBUG_PRINTLN(F("brownout detected"));
errorFlag = ERR_SYS_BROWNOUT;
//restoreConfig(); // TODO: blindly restoring config if brownout detected is a bad idea, need a better way (if at all)
break;
}
@@ -1304,9 +1296,6 @@ String computeSHA1(const String& input) {
#ifdef ESP32
#include "esp_adc_cal.h"
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4,4,7) // backwards compatibility patch
#define ADC_ATTEN_DB_12 ADC_ATTEN_DB_11
#endif
String generateDeviceFingerprint() {
uint32_t fp[2] = {0, 0}; // create 64 bit fingerprint
esp_chip_info_t chip_info;
+25 -26
View File
@@ -78,7 +78,6 @@ void WLED::loop()
#ifdef WLED_DEBUG
unsigned long usermodMillis = millis();
#endif
userLoop();
UsermodManager::loop();
#ifdef WLED_DEBUG
usermodMillis = millis() - usermodMillis;
@@ -178,7 +177,7 @@ void WLED::loop()
// calling getContiguousFreeHeap() during led update causes glitches on C3
// this can (probably) be removed once RMT driver for C3 is fixed
unsigned t0 = millis();
while (strip.isUpdating() && (millis() - t0 < 150)) delay(1); // be nice, but not too nice. Waits up to 150ms
while (strip.isUpdating() && (millis() - t0 < 15)) delay(1); // be nice, but not too nice. Waits up to 15ms
#endif
uint32_t heap = getContiguousFreeHeap(); // ESP32 family needs ~10k of contiguous free heap for UI to work properly
#endif
@@ -497,12 +496,17 @@ void WLED::setup()
DEBUG_PRINTF_P(PSTR("heap %u\n"), getFreeHeapSize());
DEBUG_PRINTLN(F("Usermods setup"));
userSetup();
UsermodManager::setup();
DEBUG_PRINTF_P(PSTR("heap %u\n"), getFreeHeapSize());
if (needsCfgSave) serializeConfigToFS(); // usermods required new parameters; need to wait for strip to be initialised #4752
if (bootPreset > 0) {
handlePresets(); // handle boot preset
handlePlaylist(); // handle playlist if preset queued one
handlePresets(); // handle presets again to give a chance for anything queued by the boot preset or playlist
}
if (strcmp(multiWiFi[0].clientSSID, DEFAULT_CLIENT_SSID) == 0 && !configBackupExists())
showWelcomePage = true;
@@ -610,35 +614,31 @@ void WLED::beginStrip()
// init offMode and relay
offMode = false; // init to on state to allow proper relay init
handleOnOff(true); // init relay and force off
if (rlyPin < 0) strip.show(); // ensure LEDs are off if no relay is used
// Note on how bootup behaviour works:
// if turnOnAtBoot is false: strip is set to black. It will fade in to startup brightness and orange when turned on
// if a bootup preset is set, it will fade to that preset if it has "on:true" set (to default brightness) or to that preset's brightness if set
// if turnOnAtBoot is true: the LEDs will fade in to orange and default brightness
// if a bootup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
// there is no way to have LEDs off at boot and upon turn-on have them immediatel jump to a target brightness but users can use a playlist to do that
bri = 0; // start off black by default (on a fresh install this is overruled by briS as turnOnAtBoot is true)
if (turnOnAtBoot) {
bri = briS; // load startup brightness (set in UI), 0 is not allowed in UI
if (briS > 0) bri = briS;
else if (bri == 0) bri = 128;
} else {
// fix for #3196
if (bootPreset > 0) {
// set all segments black (no transition)
for (unsigned i = 0; i < strip.getSegmentsNum(); i++) {
Segment &seg = strip.getSegment(i);
if (seg.isActive()) seg.colors[0] = BLACK;
}
colPri[0] = colPri[1] = colPri[2] = colPri[3] = 0; // needed for colorUpdated()
}
briLast = briS; bri = 0;
strip.fill(BLACK);
if (rlyPin < 0)
strip.show(); // ensure LEDs are off if no relay is used
}
else briLast = briS; // go to startup brightness (set in UI) when turning on (can be overruled by a preset)
colorUpdated(CALL_MODE_INIT); // set bootup brightness immediately, do not send notification (brightness is also set for preset if used, useful for swipe etc.)
colorUpdated(CALL_MODE_INIT); // will not send notification but will initiate transition
if (bootPreset > 0) {
applyPreset(bootPreset, CALL_MODE_INIT);
}
else {
// set color to warm welcoming orange (aka DEFAULT_COLOR) if no preset loaded (will fade to this color once turned on)
colPri[0] = R(DEFAULT_COLOR);
colPri[1] = G(DEFAULT_COLOR);
colPri[2] = B(DEFAULT_COLOR);
colPri[3] = W(DEFAULT_COLOR);
}
strip.setTransition(transitionDelayDefault); // restore default transition time
colorUpdated(CALL_MODE_INIT); // apply color & initiate transition, do not send notification
strip.setTransition(transitionDelayDefault); // restore transitions
}
void WLED::initAP(bool resetAP)
@@ -978,7 +978,6 @@ void WLED::handleConnection()
if (improvActive > 1) sendImprovIPRPCResult(ImprovRPCType::Command_Wifi);
}
initInterfaces();
userConnected();
UsermodManager::connected();
lastMqttReconnectAttempt = 0; // force immediate update
+3 -3
View File
@@ -7,7 +7,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2605010
#define VERSION 2605011
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
@@ -413,8 +413,8 @@ WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on col
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
WLED_GLOBAL float gammaCorrectVal _INIT(2.2f); // gamma correction value
WLED_GLOBAL byte colPri[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) primary color. colPri[] should be updated if you want to change the color.
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
WLED_GLOBAL byte colPri[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. colPri[] should be updated if you want to change the color.
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over
WLED_GLOBAL byte nightlightDelayMins _INIT(60);
+1 -1
View File
@@ -628,7 +628,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("MN"),macroNl);
int ii = 0;
for (const auto &button : buttons) {
settingsScript.printf_P(PSTR("addRow(%d,%d,%d,%d,%d);"), ii++, button.macroButton, button.macroLongPress, button.macroDoublePress, button.type);
settingsScript.printf_P(PSTR("addRow(%d,%d,%d,%d);"), ii++, button.macroButton, button.macroLongPress, button.macroDoublePress);
}
settingsScript.printf_P(PSTR("maxTimers=%d;"), WLED_MAX_TIMERS);