mirror of
https://github.com/wled/WLED.git
synced 2026-06-30 00:34:25 +00:00
Compare commits
233 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1795797e0e | |||
| 58bf4c83e9 | |||
| 69c2b2d5c2 | |||
| 830f5df465 | |||
| ce249aef64 | |||
| ff97ad5fe0 | |||
| 68b61f0831 | |||
| 6cdf650535 | |||
| 0a0800d98d | |||
| 0f34973ee5 | |||
| 72aee0680c | |||
| 86db5010f8 | |||
| 584f9aba16 | |||
| 5aa41c49bd | |||
| cc26179e56 | |||
| 6ae22c9eb4 | |||
| 33e6aee880 | |||
| 67f654e99c | |||
| decfad483a | |||
| 1ec2579f0d | |||
| 2d3c8c9920 | |||
| 1046de21a9 | |||
| b7f9f71568 | |||
| f68f91d2c9 | |||
| 59898a9b8f | |||
| 3d864b178d | |||
| 6186e32814 | |||
| 372577cb3d | |||
| 0a190271e5 | |||
| d337c8a313 | |||
| 91bcfc14ad | |||
| 42f4bcb8a9 | |||
| 8e501d9c91 | |||
| 0f30c54ca6 | |||
| 741037a242 | |||
| f5ef3f91ce | |||
| a1a22ec7b1 | |||
| 6641724616 | |||
| 722d6e8cdc | |||
| 8e94cf5bc4 | |||
| e6458922e1 | |||
| 4ba60a606f | |||
| f58187e579 | |||
| 8793db356f | |||
| b185a0216d | |||
| 560eb3763a | |||
| 6531a0804d | |||
| d5eb95028e | |||
| 37623edfc1 | |||
| 34a35d02a5 | |||
| cfe7bad45d | |||
| 0cd709723a | |||
| aa6e719129 | |||
| 979c724c91 | |||
| 665d66f45e | |||
| 367d64f41f | |||
| 59c5991d2d | |||
| 8935997228 | |||
| c8f50e6f5a | |||
| 83065c15ae | |||
| 88994e95be | |||
| f0e182bd29 | |||
| c05097351d | |||
| 57cca612db | |||
| 8204e1bafe | |||
| 8039b71b76 | |||
| 1edfc81259 | |||
| e321514e4f | |||
| b0b9fc58da | |||
| 360333c022 | |||
| 0b7f77b2f7 | |||
| 05959f94a8 | |||
| 3e085024a0 | |||
| bef897f679 | |||
| dba7fcaaff | |||
| 8aa5501571 | |||
| 41fd877adb | |||
| d66258f53b | |||
| aaf76cc4d6 | |||
| 7872c633f3 | |||
| ccd40e1f27 | |||
| d466cab664 | |||
| c74b988c90 | |||
| fe14c3104b | |||
| 47af19519f | |||
| aea18fa87b | |||
| e0b0b2a475 | |||
| 93e3e2ed02 | |||
| d00dbacca6 | |||
| 988254bb9f | |||
| dd397fe673 | |||
| 7c57de901d | |||
| a4359fa57f | |||
| 0c3ff97e16 | |||
| a871f110f5 | |||
| 49f653c621 | |||
| 64d57f51d5 | |||
| eaffac61c9 | |||
| 0466daa552 | |||
| 88032d5e4b | |||
| 9161672b43 | |||
| 45cdfde61a | |||
| 120da32d69 | |||
| eb60ff91e4 | |||
| 449069a344 | |||
| d7d4e7dfb4 | |||
| f16ca9c8ae | |||
| 5f219e60b8 | |||
| 18a9986d1d | |||
| 7a71efe916 | |||
| a535c56b4d | |||
| e37707d520 | |||
| fd6f568023 | |||
| 02e593da0b | |||
| e8d481720a | |||
| f4f4978eeb | |||
| 49a63fc15e | |||
| 1bc71f2352 | |||
| 70b0aeac95 | |||
| d20dbeb204 | |||
| 69d494ad40 | |||
| 8aa4beeaea | |||
| 012fbdd6e9 | |||
| 01328a65c1 | |||
| a2d970e155 | |||
| cb666cedc5 | |||
| 5e0a0a7561 | |||
| 3af2ae5f2f | |||
| 259bf3c0f8 | |||
| 2481aab860 | |||
| ac96ee7568 | |||
| 2b32918db0 | |||
| 5e49a1cffb | |||
| 910caae463 | |||
| 35ce05a73b | |||
| ba377d7c29 | |||
| 1cce33e0d3 | |||
| 6d7c1d0bbd | |||
| 96510614a3 | |||
| 1185886eab | |||
| a94a3f7003 | |||
| 144f1f13a8 | |||
| 5a7aa8d8a8 | |||
| 42b91f2122 | |||
| a966c41bc2 | |||
| 36ebcb50f7 | |||
| 3149a80dcf | |||
| bab31833f0 | |||
| 48b0ba0643 | |||
| 0198a614b9 | |||
| 14f2ca4223 | |||
| 7932a249e0 | |||
| 474e1fe2e5 | |||
| 7aec31f039 | |||
| e2dd6303ea | |||
| 7242e9d842 | |||
| ab0cde110f | |||
| c735feb90a | |||
| a6faf942f1 | |||
| 370e4c8e2f | |||
| 8e90242e95 | |||
| 97dacb6a04 | |||
| 061920bb9c | |||
| 97704e08de | |||
| a51aec6f19 | |||
| c21ed0714f | |||
| a2dce56809 | |||
| 036f5199e5 | |||
| 1914e4ee3b | |||
| 9c072ec921 | |||
| cf4dfe958e | |||
| 2cccbd175c | |||
| cb61c4fe7d | |||
| 4a0a4c632b | |||
| 5b2ae15d8d | |||
| 44ddc21530 | |||
| 063592c845 | |||
| 4955af0a11 | |||
| 9df5d056b9 | |||
| 3486e3bcbb | |||
| 91eb69643d | |||
| 48b27d12ac | |||
| 78c1051cbb | |||
| 2302863386 | |||
| 7560811480 | |||
| 12f6fbc005 | |||
| c819814904 | |||
| 0ef5ee74d4 | |||
| 875711d38e | |||
| 9b9474282d | |||
| 1284aba5d0 | |||
| fa6fc4f0b6 | |||
| f7d9461d1c | |||
| 51862e3572 | |||
| 7153fd8fe4 | |||
| 35c1f415c3 | |||
| cf03f1a16e | |||
| 5be517b519 | |||
| aaf51927a6 | |||
| 630533d125 | |||
| a78d39ff1e | |||
| 7722faf9d7 | |||
| 72a43c6431 | |||
| 7c6828d443 | |||
| f8f46736ec | |||
| e4f8534cf0 | |||
| 79ecffe0f3 | |||
| 1fb636d8ea | |||
| e04c855e6c | |||
| 6a627a86b7 | |||
| 746df24011 | |||
| da64f71ce2 | |||
| 8972b6bfe2 | |||
| 8241468fe2 | |||
| e9b740a915 | |||
| 548bb6ffd5 | |||
| 964c8cee66 | |||
| 9d1f36c553 | |||
| ad921f031f | |||
| 3d2fac0ad4 | |||
| a5f28d0fcb | |||
| fb8f8f0b08 | |||
| 53fdf9a89c | |||
| a1316034c1 | |||
| 75df4affa8 | |||
| 820c841376 | |||
| 34d50710b3 | |||
| d0d62d9493 | |||
| 89b2bc2992 | |||
| e019d36221 | |||
| 3bcb0c902e | |||
| 75b679814b | |||
| 0a21869362 |
+2
-9
@@ -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.
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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).
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Generated
+2
-2
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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(.);")
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -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://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
@@ -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
@@ -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
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"name:": "EleksTube_IPS",
|
||||
"name": "EleksTube_IPS",
|
||||
"build": { "libArchive": false },
|
||||
"dependencies": {
|
||||
"TFT_eSPI" : "2.5.33"
|
||||
|
||||
@@ -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,'µs');"));
|
||||
oappend(F("addInfo('INA226:Decimals',1,'(0-5)');"));
|
||||
oappend(F("addInfo('INA226:ShuntResistor',1,'mΩ');"));
|
||||
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))
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"name:": "pov_display",
|
||||
"name": "pov_display",
|
||||
"build": { "libArchive": false},
|
||||
"platforms": ["espressif32"]
|
||||
}
|
||||
|
||||
+28
-28
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -272,4 +272,4 @@ class E131Priority {
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ESPASYNCE131_H_
|
||||
#endif // ESPASYNCE131_H_
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user