mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 08:46:34 +00:00
Merge remote-tracking branch 'upstream/0_15' into 0_15_trig_math
This commit is contained in:
commit
a0a46850f5
80
.github/workflows/build.yml
vendored
Normal file
80
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
name: WLED Build
|
||||
|
||||
# Only included into other workflows
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
|
||||
get_default_envs:
|
||||
name: Gather Environments
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
- name: Install PlatformIO
|
||||
run: pip install -r requirements.txt
|
||||
- name: Get default environments
|
||||
id: envs
|
||||
run: |
|
||||
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
environments: ${{ steps.envs.outputs.environments }}
|
||||
|
||||
|
||||
build:
|
||||
name: Build Enviornments
|
||||
runs-on: ubuntu-latest
|
||||
needs: get_default_envs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.platformio/.cache
|
||||
~/.buildcache
|
||||
build_output
|
||||
key: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }}
|
||||
restore-keys: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
- name: Install PlatformIO
|
||||
run: pip install -r requirements.txt
|
||||
- name: Build firmware
|
||||
run: pio run -e ${{ matrix.environment }}
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ matrix.environment }}
|
||||
path: |
|
||||
build_output/release/*.bin
|
||||
build_output/release/*_ESP02*.bin.gz
|
||||
|
||||
|
||||
testCdata:
|
||||
name: Test cdata.js
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm test
|
28
.github/workflows/release.yml
vendored
Normal file
28
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: WLED Release CI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
|
||||
wled_build:
|
||||
uses: ./.github/workflows/build.yml
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: wled_build
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: True
|
||||
files: |
|
||||
*.bin
|
||||
*.bin.gz
|
||||
|
97
.github/workflows/wled-ci.yml
vendored
97
.github/workflows/wled-ci.yml
vendored
@ -1,94 +1,11 @@
|
||||
name: WLED CI
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
get_default_envs:
|
||||
name: Gather Environments
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
- name: Install PlatformIO
|
||||
run: pip install -r requirements.txt
|
||||
- name: Get default environments
|
||||
id: envs
|
||||
run: |
|
||||
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
environments: ${{ steps.envs.outputs.environments }}
|
||||
|
||||
|
||||
build:
|
||||
name: Build Enviornments
|
||||
runs-on: ubuntu-latest
|
||||
needs: get_default_envs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.platformio/.cache
|
||||
~/.buildcache
|
||||
build_output
|
||||
key: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }}
|
||||
restore-keys: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
- name: Install PlatformIO
|
||||
run: pip install -r requirements.txt
|
||||
- name: Build firmware
|
||||
run: pio run -e ${{ matrix.environment }}
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ matrix.environment }}
|
||||
path: |
|
||||
build_output/release/*.bin
|
||||
build_output/release/*_ESP02*.bin.gz
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: True
|
||||
files: |
|
||||
*.bin
|
||||
*.bin.gz
|
||||
|
||||
|
||||
testCdata:
|
||||
name: Test cdata.js
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
wled_build:
|
||||
uses: ./.github/workflows/build.yml
|
||||
|
26
CHANGELOG.md
26
CHANGELOG.md
@ -1,9 +1,35 @@
|
||||
## WLED changelog
|
||||
|
||||
#### Build 2410270
|
||||
- WLED 0.15.0-b7 release
|
||||
- Re-license the WLED project from MIT to EUPL (#4194 by @Aircoookie)
|
||||
- Fix alexa devices invisible/uncontrollable (#4214 by @Svennte)
|
||||
- Add visual expand button on hover (#4172)
|
||||
- Usermod: Audioreactive tuning and performance enhancements (by @softhack007)
|
||||
- `/json/live` (JSON live data/peek) only enabled when WebSockets are disabled
|
||||
- Various bugfixes and optimisations: #4179, #4215, #4219, #4222, #4223, #4224, #4228, #4230
|
||||
|
||||
#### Build 2410140
|
||||
- WLED 0.15.0-b6 release
|
||||
- Added BRT timezone (#4188 by @LuisFadini)
|
||||
- Fixed the positioning of the "Download the latest binary" button (#4184 by @maxi4329)
|
||||
- Add WLED_AUTOSEGMENTS compile flag (#4183 by @PaoloTK)
|
||||
- New 512kB FS parition map for 4MB devices
|
||||
- Internal API change: Static PinManager & UsermodManager
|
||||
- Change in Improv chip ID and version generation
|
||||
- Various optimisations, bugfixes and enhancements (#4005, #4174 & #4175 by @Xevel, #4180, #4168, #4154, #4189 by @dosipod)
|
||||
|
||||
#### Build 2409170
|
||||
- UI: Introduce common.js in settings pages (size optimisation)
|
||||
- Add the ability to toggle the reception of palette synchronizations (#4137 by @felddy)
|
||||
- Usermod/FX: Temperature usermod added Temperature effect (example usermod effect by @blazoncek)
|
||||
- Fix AsyncWebServer version pin
|
||||
|
||||
#### Build 2409140
|
||||
- Configure different kinds of busses at compile (#4107 by @PaoloTK)
|
||||
- BREAKING: removes LEDPIN and DEFAULT_LED_TYPE compile overrides
|
||||
- Fetch LED types from Bus classes (dynamic UI) (#4129 by @netmindz, @blazoncek, @dedehai)
|
||||
- Temperature usermod: update OneWire to 2.3.8 (#4131 by @iammattcoleman)
|
||||
|
||||
#### Build 2409100
|
||||
- WLED 0.15.0-b5 release
|
||||
|
307
LICENSE
307
LICENSE
@ -1,21 +1,294 @@
|
||||
MIT License
|
||||
Copyright (c) 2016-present Christian Schwinne and individual WLED contributors
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
|
||||
Copyright (c) 2016 Christian Schwinne
|
||||
EUROPEAN UNION PUBLIC LICENCE v. 1.2
|
||||
EUPL © the European Union 2007, 2016
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This European Union Public Licence (the ‘EUPL’) applies to the Work (as
|
||||
defined below) which is provided under the terms of this Licence. Any use of
|
||||
the Work, other than as authorised under this Licence is prohibited (to the
|
||||
extent such use is covered by a right of the copyright holder of the Work).
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The Work is provided under the terms of this Licence when the Licensor (as
|
||||
defined below) has placed the following notice immediately following the
|
||||
copyright notice for the Work:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Licensed under the EUPL
|
||||
|
||||
or has expressed by any other means his willingness to license under the EUPL.
|
||||
|
||||
1. Definitions
|
||||
|
||||
In this Licence, the following terms have the following meaning:
|
||||
|
||||
- ‘The Licence’: this Licence.
|
||||
|
||||
- ‘The Original Work’: the work or software distributed or communicated by the
|
||||
Licensor under this Licence, available as Source Code and also as Executable
|
||||
Code as the case may be.
|
||||
|
||||
- ‘Derivative Works’: the works or software that could be created by the
|
||||
Licensee, based upon the Original Work or modifications thereof. This
|
||||
Licence does not define the extent of modification or dependence on the
|
||||
Original Work required in order to classify a work as a Derivative Work;
|
||||
this extent is determined by copyright law applicable in the country
|
||||
mentioned in Article 15.
|
||||
|
||||
- ‘The Work’: the Original Work or its Derivative Works.
|
||||
|
||||
- ‘The Source Code’: the human-readable form of the Work which is the most
|
||||
convenient for people to study and modify.
|
||||
|
||||
- ‘The Executable Code’: any code which has generally been compiled and which
|
||||
is meant to be interpreted by a computer as a program.
|
||||
|
||||
- ‘The Licensor’: the natural or legal person that distributes or communicates
|
||||
the Work under the Licence.
|
||||
|
||||
- ‘Contributor(s)’: any natural or legal person who modifies the Work under
|
||||
the Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||
|
||||
- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of
|
||||
the Work under the terms of the Licence.
|
||||
|
||||
- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending,
|
||||
renting, distributing, communicating, transmitting, or otherwise making
|
||||
available, online or offline, copies of the Work or providing access to its
|
||||
essential functionalities at the disposal of any other natural or legal
|
||||
person.
|
||||
|
||||
2. Scope of the rights granted by the Licence
|
||||
|
||||
The Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
sublicensable licence to do the following, for the duration of copyright
|
||||
vested in the Original Work:
|
||||
|
||||
- use the Work in any circumstance and for all usage,
|
||||
- reproduce the Work,
|
||||
- modify the Work, and make Derivative Works based upon the Work,
|
||||
- communicate to the public, including the right to make available or display
|
||||
the Work or copies thereof to the public and perform publicly, as the case
|
||||
may be, the Work,
|
||||
- distribute the Work or copies thereof,
|
||||
- lend and rent the Work or copies thereof,
|
||||
- sublicense rights in the Work or copies thereof.
|
||||
|
||||
Those rights can be exercised on any media, supports and formats, whether now
|
||||
known or later invented, as far as the applicable law permits so.
|
||||
|
||||
In the countries where moral rights apply, the Licensor waives his right to
|
||||
exercise his moral right to the extent allowed by law in order to make
|
||||
effective the licence of the economic rights here above listed.
|
||||
|
||||
The Licensor grants to the Licensee royalty-free, non-exclusive usage rights
|
||||
to any patents held by the Licensor, to the extent necessary to make use of
|
||||
the rights granted on the Work under this Licence.
|
||||
|
||||
3. Communication of the Source Code
|
||||
|
||||
The Licensor may provide the Work either in its Source Code form, or as
|
||||
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||
provides in addition a machine-readable copy of the Source Code of the Work
|
||||
along with each copy of the Work that the Licensor distributes or indicates,
|
||||
in a notice following the copyright notice attached to the Work, a repository
|
||||
where the Source Code is easily and freely accessible for as long as the
|
||||
Licensor continues to distribute or communicate the Work.
|
||||
|
||||
4. Limitations on copyright
|
||||
|
||||
Nothing in this Licence is intended to deprive the Licensee of the benefits
|
||||
from any exception or limitation to the exclusive rights of the rights owners
|
||||
in the Work, of the exhaustion of those rights or of other applicable
|
||||
limitations thereto.
|
||||
|
||||
5. Obligations of the Licensee
|
||||
|
||||
The grant of the rights mentioned above is subject to some restrictions and
|
||||
obligations imposed on the Licensee. Those obligations are the following:
|
||||
|
||||
Attribution right: The Licensee shall keep intact all copyright, patent or
|
||||
trademarks notices and all notices that refer to the Licence and to the
|
||||
disclaimer of warranties. The Licensee must include a copy of such notices and
|
||||
a copy of the Licence with every copy of the Work he/she distributes or
|
||||
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||
notices stating that the Work has been modified and the date of modification.
|
||||
|
||||
Copyleft clause: If the Licensee distributes or communicates copies of the
|
||||
Original Works or Derivative Works, this Distribution or Communication will be
|
||||
done under the terms of this Licence or of a later version of this Licence
|
||||
unless the Original Work is expressly distributed only under this version of
|
||||
the Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee
|
||||
(becoming Licensor) cannot offer or impose any additional terms or conditions
|
||||
on the Work or Derivative Work that alter or restrict the terms of the
|
||||
Licence.
|
||||
|
||||
Compatibility clause: If the Licensee Distributes or Communicates Derivative
|
||||
Works or copies thereof based upon both the Work and another work licensed
|
||||
under a Compatible Licence, this Distribution or Communication can be done
|
||||
under the terms of this Compatible Licence. For the sake of this clause,
|
||||
‘Compatible Licence’ refers to the licences listed in the appendix attached to
|
||||
this Licence. Should the Licensee's obligations under the Compatible Licence
|
||||
conflict with his/her obligations under this Licence, the obligations of the
|
||||
Compatible Licence shall prevail.
|
||||
|
||||
Provision of Source Code: When distributing or communicating copies of the
|
||||
Work, the Licensee will provide a machine-readable copy of the Source Code or
|
||||
indicate a repository where this Source will be easily and freely available
|
||||
for as long as the Licensee continues to distribute or communicate the Work.
|
||||
|
||||
Legal Protection: This Licence does not grant permission to use the trade
|
||||
names, trademarks, service marks, or names of the Licensor, except as required
|
||||
for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the copyright notice.
|
||||
|
||||
6. Chain of Authorship
|
||||
|
||||
The original Licensor warrants that the copyright in the Original Work granted
|
||||
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||
power and authority to grant the Licence.
|
||||
|
||||
Each Contributor warrants that the copyright in the modifications he/she
|
||||
brings to the Work are owned by him/her or licensed to him/her and that he/she
|
||||
has the power and authority to grant the Licence.
|
||||
|
||||
Each time You accept the Licence, the original Licensor and subsequent
|
||||
Contributors grant You a licence to their contributions to the Work, under the
|
||||
terms of this Licence.
|
||||
|
||||
7. Disclaimer of Warranty
|
||||
|
||||
The Work is a work in progress, which is continuously improved by numerous
|
||||
Contributors. It is not a finished work and may therefore contain defects or
|
||||
‘bugs’ inherent to this type of development.
|
||||
|
||||
For the above reason, the Work is provided under the Licence on an ‘as is’
|
||||
basis and without warranties of any kind concerning the Work, including
|
||||
without limitation merchantability, fitness for a particular purpose, absence
|
||||
of defects or errors, accuracy, non-infringement of intellectual property
|
||||
rights other than copyright as stated in Article 6 of this Licence.
|
||||
|
||||
This disclaimer of warranty is an essential part of the Licence and a
|
||||
condition for the grant of any rights to the Work.
|
||||
|
||||
8. Disclaimer of Liability
|
||||
|
||||
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||
material or moral, damages of any kind, arising out of the Licence or of the
|
||||
use of the Work, including without limitation, damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, loss of data or any commercial
|
||||
damage, even if the Licensor has been advised of the possibility of such
|
||||
damage. However, the Licensor will be liable under statutory product liability
|
||||
laws as far such laws apply to the Work.
|
||||
|
||||
9. Additional agreements
|
||||
|
||||
While distributing the Work, You may choose to conclude an additional
|
||||
agreement, defining obligations or services consistent with this Licence.
|
||||
However, if accepting obligations, You may act only on your own behalf and on
|
||||
your sole responsibility, not on behalf of the original Licensor or any other
|
||||
Contributor, and only if You agree to indemnify, defend, and hold each
|
||||
Contributor harmless for any liability incurred by, or claims asserted against
|
||||
such Contributor by the fact You have accepted any warranty or additional
|
||||
liability.
|
||||
|
||||
10. Acceptance of the Licence
|
||||
|
||||
The provisions of this Licence can be accepted by clicking on an icon ‘I
|
||||
agree’ placed under the bottom of a window displaying the text of this Licence
|
||||
or by affirming consent in any other similar way, in accordance with the rules
|
||||
of applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||
acceptance of this Licence and all of its terms and conditions.
|
||||
|
||||
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||
conditions by exercising any rights granted to You by Article 2 of this
|
||||
Licence, such as the use of the Work, the creation by You of a Derivative Work
|
||||
or the Distribution or Communication by You of the Work or copies thereof.
|
||||
|
||||
11. Information to the public
|
||||
|
||||
In case of any Distribution or Communication of the Work by means of
|
||||
electronic communication by You (for example, by offering to download the Work
|
||||
from a remote location) the distribution channel or media (for example, a
|
||||
website) must at least provide to the public the information requested by the
|
||||
applicable law regarding the Licensor, the Licence and the way it may be
|
||||
accessible, concluded, stored and reproduced by the Licensee.
|
||||
|
||||
12. Termination of the Licence
|
||||
|
||||
The Licence and the rights granted hereunder will terminate automatically upon
|
||||
any breach by the Licensee of the terms of the Licence.
|
||||
|
||||
Such a termination will not terminate the licences of any person who has
|
||||
received the Work from the Licensee under the Licence, provided such persons
|
||||
remain in full compliance with the Licence.
|
||||
|
||||
13. Miscellaneous
|
||||
|
||||
Without prejudice of Article 9 above, the Licence represents the complete
|
||||
agreement between the Parties as to the Work.
|
||||
|
||||
If any provision of the Licence is invalid or unenforceable under applicable
|
||||
law, this will not affect the validity or enforceability of the Licence as a
|
||||
whole. Such provision will be construed or reformed so as necessary to make it
|
||||
valid and enforceable.
|
||||
|
||||
The European Commission may publish other linguistic versions or new versions
|
||||
of this Licence or updated versions of the Appendix, so far this is required
|
||||
and reasonable, without reducing the scope of the rights granted by the
|
||||
Licence. New versions of the Licence will be published with a unique version
|
||||
number.
|
||||
|
||||
All linguistic versions of this Licence, approved by the European Commission,
|
||||
have identical value. Parties can take advantage of the linguistic version of
|
||||
their choice.
|
||||
|
||||
14. Jurisdiction
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- any litigation resulting from the interpretation of this License, arising
|
||||
between the European Union institutions, bodies, offices or agencies, as a
|
||||
Licensor, and any Licensee, will be subject to the jurisdiction of the Court
|
||||
of Justice of the European Union, as laid down in article 272 of the Treaty
|
||||
on the Functioning of the European Union,
|
||||
|
||||
- any litigation arising between other parties and resulting from the
|
||||
interpretation of this License, will be subject to the exclusive
|
||||
jurisdiction of the competent court where the Licensor resides or conducts
|
||||
its primary business.
|
||||
|
||||
15. Applicable Law
|
||||
|
||||
Without prejudice to specific agreement between parties,
|
||||
|
||||
- this Licence shall be governed by the law of the European Union Member State
|
||||
where the Licensor has his seat, resides or has his registered office,
|
||||
|
||||
- this licence shall be governed by Belgian law if the Licensor has no seat,
|
||||
residence or registered office inside a European Union Member State.
|
||||
|
||||
Appendix
|
||||
|
||||
‘Compatible Licences’ according to Article 5 EUPL are:
|
||||
|
||||
- GNU General Public License (GPL) v. 2, v. 3
|
||||
- GNU Affero General Public License (AGPL) v. 3
|
||||
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||
- Eclipse Public License (EPL) v. 1.0
|
||||
- CeCILL v. 2.0, v. 2.1
|
||||
- Mozilla Public Licence (MPL) v. 2
|
||||
- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
|
||||
- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for
|
||||
works other than software
|
||||
- European Union Public Licence (EUPL) v. 1.1, v. 1.2
|
||||
- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong
|
||||
Reciprocity (LiLiQ-R+).
|
||||
|
||||
The European Commission may update this Appendix to later versions of the
|
||||
above licences without producing a new version of the EUPL, as long as they
|
||||
provide the rights granted in Article 2 of this Licence and protect the
|
||||
covered Source Code from exclusive appropriation.
|
||||
|
||||
All other changes or additions to this Appendix require the production of a
|
||||
new EUPL version.
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b5",
|
||||
"version": "0.15.0-b7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b5",
|
||||
"version": "0.15.0-b7",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"clean-css": "^5.3.3",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wled",
|
||||
"version": "0.15.0-b5",
|
||||
"version": "0.15.0-b7",
|
||||
"description": "Tools for WLED project",
|
||||
"main": "tools/cdata.js",
|
||||
"directories": {
|
||||
@ -27,5 +27,8 @@
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"inliner": "^1.13.1",
|
||||
"nodemon": "^3.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,9 @@ def _create_dirs(dirs=["map", "release", "firmware"]):
|
||||
os.makedirs(os.path.join(OUTPUT_DIR, d), exist_ok=True)
|
||||
|
||||
def create_release(source):
|
||||
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
|
||||
if release_name:
|
||||
release_name_def = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
|
||||
if release_name_def:
|
||||
release_name = release_name_def.replace("\\\"", "")
|
||||
version = _get_cpp_define_value(env, "WLED_VERSION")
|
||||
release_file = os.path.join(OUTPUT_DIR, "release", f"WLED_{version}_{release_name}.bin")
|
||||
release_gz_file = release_file + ".gz"
|
||||
|
@ -197,6 +197,7 @@ build_flags =
|
||||
; decrease code cache size and increase IRAM to fit all pixel functions
|
||||
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
|
||||
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown
|
||||
-D NON32XFER_HANDLER ;; ask forgiveness for PROGMEM misuse
|
||||
|
||||
lib_deps =
|
||||
#https://github.com/lorol/LITTLEFS.git
|
||||
@ -260,6 +261,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
# additional build flags for audioreactive
|
||||
AR_build_flags = -D USERMOD_AUDIOREACTIVE
|
||||
-D sqrt_internal=sqrtf ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
|
||||
AR_lib_deps = kosme/arduinoFFT @ 2.0.1
|
||||
|
||||
[esp32_idf_V4]
|
||||
@ -343,7 +345,7 @@ 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
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266\" #-DWLED_DISABLE_2D
|
||||
lib_deps = ${esp8266.lib_deps}
|
||||
monitor_filters = esp8266_exception_decoder
|
||||
|
||||
@ -352,13 +354,13 @@ extends = env:nodemcuv2
|
||||
;; using platform version and build options from WLED 0.14.0
|
||||
platform = ${esp8266.platform_compat}
|
||||
platform_packages = ${esp8266.platform_packages_compat}
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP8266_compat #-DWLED_DISABLE_2D
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP8266_compat\" #-DWLED_DISABLE_2D
|
||||
;; lib_deps = ${esp8266.lib_deps_compat} ;; experimental - use older NeoPixelBus 2.7.9
|
||||
|
||||
[env:nodemcuv2_160]
|
||||
extends = env:nodemcuv2
|
||||
board_build.f_cpu = 160000000L
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP8266_160 #-DWLED_DISABLE_2D
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_160\" #-DWLED_DISABLE_2D
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
|
||||
[env:esp8266_2m]
|
||||
@ -367,7 +369,7 @@ 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
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02\"
|
||||
lib_deps = ${esp8266.lib_deps}
|
||||
|
||||
[env:esp8266_2m_compat]
|
||||
@ -375,12 +377,12 @@ extends = env:esp8266_2m
|
||||
;; using platform version and build options from WLED 0.14.0
|
||||
platform = ${esp8266.platform_compat}
|
||||
platform_packages = ${esp8266.platform_packages_compat}
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP02_compat #-DWLED_DISABLE_2D
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP02_compat\" #-DWLED_DISABLE_2D
|
||||
|
||||
[env:esp8266_2m_160]
|
||||
extends = env:esp8266_2m
|
||||
board_build.f_cpu = 160000000L
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02_160
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02_160\"
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
|
||||
[env:esp01_1m_full]
|
||||
@ -389,7 +391,7 @@ 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
|
||||
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
|
||||
lib_deps = ${esp8266.lib_deps}
|
||||
|
||||
@ -398,12 +400,12 @@ extends = env:esp01_1m_full
|
||||
;; using platform version and build options from WLED 0.14.0
|
||||
platform = ${esp8266.platform_compat}
|
||||
platform_packages = ${esp8266.platform_packages_compat}
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP01_compat -D WLED_DISABLE_OTA #-DWLED_DISABLE_2D
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP01_compat\" -D WLED_DISABLE_OTA #-DWLED_DISABLE_2D
|
||||
|
||||
[env:esp01_1m_full_160]
|
||||
extends = env:esp01_1m_full
|
||||
board_build.f_cpu = 160000000L
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_DISABLE_OTA
|
||||
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP01_160\" -D WLED_DISABLE_OTA
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
; -D WLED_USE_REAL_MATH ;; may fix wrong sunset/sunrise times, at the cost of 7064 bytes FLASH and 975 bytes RAM
|
||||
|
||||
@ -412,7 +414,7 @@ board = esp32dev
|
||||
platform = ${esp32.platform}
|
||||
platform_packages = ${esp32.platform_packages}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET
|
||||
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
|
||||
${esp32.AR_build_flags}
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
@ -424,7 +426,7 @@ board = esp32dev
|
||||
platform = ${esp32_idf_V4.platform}
|
||||
platform_packages = ${esp32_idf_V4.platform_packages}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_8M #-D WLED_DISABLE_BROWNOUT_DET
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
|
||||
${esp32.AR_build_flags}
|
||||
lib_deps = ${esp32_idf_V4.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
@ -440,7 +442,7 @@ board = esp32dev
|
||||
platform = ${esp32_idf_V4.platform}
|
||||
platform_packages = ${esp32_idf_V4.platform_packages}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_16M #-D WLED_DISABLE_BROWNOUT_DET
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
|
||||
${esp32.AR_build_flags}
|
||||
lib_deps = ${esp32_idf_V4.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
@ -456,7 +458,7 @@ board_build.flash_mode = dio
|
||||
;platform = ${esp32.platform}
|
||||
;platform_packages = ${esp32.platform_packages}
|
||||
;build_unflags = ${common.build_unflags}
|
||||
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32_audioreactive #-D WLED_DISABLE_BROWNOUT_DET
|
||||
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_audioreactive\" #-D WLED_DISABLE_BROWNOUT_DET
|
||||
; ${esp32.AR_build_flags}
|
||||
;lib_deps = ${esp32.lib_deps}
|
||||
; ${esp32.AR_lib_deps}
|
||||
@ -471,7 +473,7 @@ platform = ${esp32.platform}
|
||||
platform_packages = ${esp32.platform_packages}
|
||||
upload_speed = 921600
|
||||
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
|
||||
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 WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
|
||||
${esp32.AR_build_flags}
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
@ -487,7 +489,7 @@ board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = qio
|
||||
board_build.partitions = ${esp32.extended_partitions}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_WROVER
|
||||
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
|
||||
-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
|
||||
${esp32.AR_build_flags}
|
||||
@ -501,7 +503,7 @@ platform_packages = ${esp32c3.platform_packages}
|
||||
framework = arduino
|
||||
board = esp32-c3-devkitm-1
|
||||
board_build.partitions = ${esp32.default_partitions}
|
||||
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=ESP32-C3
|
||||
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C3\"
|
||||
-D WLED_WATCHDOG_TIMEOUT=0
|
||||
-DLOLIN_WIFI_FIX ; seems to work much better with this
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
|
||||
@ -518,7 +520,7 @@ platform = ${esp32s3.platform}
|
||||
platform_packages = ${esp32s3.platform_packages}
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_16MB_opi
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_16MB_opi\"
|
||||
-D CONFIG_LITTLEFS_FOR_IDF_3_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
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
||||
@ -541,7 +543,7 @@ platform = ${esp32s3.platform}
|
||||
platform_packages = ${esp32s3.platform_packages}
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB_opi
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_8MB_opi\"
|
||||
-D CONFIG_LITTLEFS_FOR_IDF_3_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
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
||||
@ -554,6 +556,33 @@ board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = qio
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[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}
|
||||
board = esp32s3camlcd ;; this is the only standard board with "opi_opi"
|
||||
board_build.arduino.memory_type = opi_opi
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_WROOM-2\"
|
||||
-D CONFIG_LITTLEFS_FOR_IDF_3_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
|
||||
;; -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
|
||||
-D LEDPIN=38 -D DATA_PINS=38 ;; buildin WS2812b LED
|
||||
-D BTNPIN=0 -D RLYPIN=16 -D IRPIN=17 -D AUDIOPIN=-1
|
||||
-D WLED_DEBUG
|
||||
${esp32.AR_build_flags}
|
||||
-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}
|
||||
${esp32.AR_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_4M_qspi]
|
||||
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
|
||||
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
|
||||
@ -561,7 +590,7 @@ platform = ${esp32s3.platform}
|
||||
platform_packages = ${esp32s3.platform_packages}
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_4M_qspi
|
||||
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
|
||||
@ -582,7 +611,7 @@ board_build.partitions = ${esp32.default_partitions}
|
||||
board_build.flash_mode = qio
|
||||
board_build.f_flash = 80000000L
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2
|
||||
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
|
||||
-DARDUINO_USB_DFU_ON_BOOT=0
|
||||
|
@ -37,7 +37,7 @@ build_flags = ${common.build_flags} ${esp8266.build_flags}
|
||||
; *** To use the below defines/overrides, copy and paste each onto it's own line just below build_flags in the section above.
|
||||
;
|
||||
; Set a release name that may be used to distinguish required binary for flashing
|
||||
; -D WLED_RELEASE_NAME=ESP32_MULTI_USREMODS
|
||||
; -D WLED_RELEASE_NAME=\"ESP32_MULTI_USREMODS\"
|
||||
;
|
||||
; disable specific features
|
||||
; -D WLED_DISABLE_OTA
|
||||
@ -111,7 +111,6 @@ build_flags = ${common.build_flags} ${esp8266.build_flags}
|
||||
;
|
||||
; Use 4 Line Display usermod with SPI display
|
||||
; -D USERMOD_FOUR_LINE_DISPLAY
|
||||
; -D USE_ALT_DISPlAY # mandatory
|
||||
; -DFLD_SPI_DEFAULT
|
||||
; -D FLD_TYPE=SSD1306_SPI64
|
||||
; -D FLD_PIN_CLOCKSPI=14
|
||||
@ -377,7 +376,6 @@ build_flags = ${common.build_flags} ${esp32.build_flags}
|
||||
-D USERMOD_DALLASTEMPERATURE
|
||||
-D USERMOD_FOUR_LINE_DISPLAY
|
||||
-D TEMPERATURE_PIN=23
|
||||
-D USE_ALT_DISPlAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
OneWire@~2.3.5
|
||||
|
@ -61,7 +61,7 @@ See [here](https://kno.wled.ge/basics/compatible-hardware)!
|
||||
|
||||
## ✌️ Other
|
||||
|
||||
Licensed under the MIT license
|
||||
Licensed under the EUPL v1.2 license
|
||||
Credits [here](https://kno.wled.ge/about/contributors/)!
|
||||
|
||||
Join the Discord server to discuss everything about WLED!
|
||||
@ -80,5 +80,5 @@ If WLED really brightens up your day, you can [ {
|
||||
async function minify(str, type = "plain") {
|
||||
const options = {
|
||||
collapseWhitespace: true,
|
||||
conservativeCollapse: true, // preserve spaces in text
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
minifyCSS: true,
|
||||
|
@ -425,10 +425,10 @@ class Animated_Staircase : public Usermod {
|
||||
}
|
||||
|
||||
void appendConfigData() {
|
||||
//oappend(SET_F("dd=addDropdown('staircase','selectfield');"));
|
||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
||||
//oappend(SET_F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field
|
||||
//oappend(F("dd=addDropdown('staircase','selectfield');"));
|
||||
//oappend(F("addOption(dd,'1st value',0);"));
|
||||
//oappend(F("addOption(dd,'2nd value',1);"));
|
||||
//oappend(F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
|
||||
|
@ -767,22 +767,22 @@ void UsermodBME68X::appendConfigData() {
|
||||
// snprintf_P(charbuffer, 127, PSTR("addInfo('%s:%s',1,'*) Set to minus to deactivate (all sensors)');"), UMOD_NAME, _nameTemp); oappend(charbuffer);
|
||||
|
||||
/* Dropdown for Celsius/Fahrenheit*/
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(UMOD_NAME);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_nameTempScale);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'Celsius',0);"));
|
||||
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||
|
||||
/* i²C Address*/
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(UMOD_NAME);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_nameI2CAdr);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'0x76',0x76);"));
|
||||
oappend(SET_F("addOption(dd,'0x77',0x77);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'0x76',0x76);"));
|
||||
oappend(F("addOption(dd,'0x77',0x77);"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -478,29 +478,29 @@ class UsermodBattery : public Usermod
|
||||
void appendConfigData()
|
||||
{
|
||||
// Total: 462 Bytes
|
||||
oappend(SET_F("td=addDropdown('Battery','type');")); // 34 Bytes
|
||||
oappend(SET_F("addOption(td,'Unkown','0');")); // 28 Bytes
|
||||
oappend(SET_F("addOption(td,'LiPo','1');")); // 26 Bytes
|
||||
oappend(SET_F("addOption(td,'LiOn','2');")); // 26 Bytes
|
||||
oappend(SET_F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
||||
oappend(SET_F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
||||
oappend(SET_F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
||||
oappend(F("td=addDropdown('Battery','type');")); // 34 Bytes
|
||||
oappend(F("addOption(td,'Unkown','0');")); // 28 Bytes
|
||||
oappend(F("addOption(td,'LiPo','1');")); // 26 Bytes
|
||||
oappend(F("addOption(td,'LiOn','2');")); // 26 Bytes
|
||||
oappend(F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
||||
oappend(F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
||||
oappend(F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
||||
oappend(F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
||||
oappend(F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
||||
oappend(F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
||||
|
||||
// this option list would exeed the oappend() buffer
|
||||
// a list of all presets to select one from
|
||||
// oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||
// the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);"));
|
||||
// oappend(F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||
// the loop generates: oappend(F("addOption(bd, 'preset name', preset id);"));
|
||||
// for(int8_t i=1; i < 42; i++) {
|
||||
// oappend(SET_F("addOption(bd, 'Preset#"));
|
||||
// oappend(F("addOption(bd, 'Preset#"));
|
||||
// oappendi(i);
|
||||
// oappend(SET_F("',"));
|
||||
// oappend(F("',"));
|
||||
// oappendi(i);
|
||||
// oappend(SET_F(");"));
|
||||
// oappend(F(");"));
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -287,11 +287,11 @@ class MyExampleUsermod : public Usermod {
|
||||
*/
|
||||
void appendConfigData() override
|
||||
{
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'<i>(this is a great config value)</i>');"));
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');"));
|
||||
oappend(SET_F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F("','testInt');"));
|
||||
oappend(SET_F("addOption(dd,'Nothing',0);"));
|
||||
oappend(SET_F("addOption(dd,'Everything',42);"));
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":great")); oappend(F("',1,'<i>(this is a great config value)</i>');"));
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":testString")); oappend(F("',1,'enter any string you want');"));
|
||||
oappend(F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(F("','testInt');"));
|
||||
oappend(F("addOption(dd,'Nothing',0);"));
|
||||
oappend(F("addOption(dd,'Everything',42);"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,11 +149,11 @@ public:
|
||||
void appendConfigData()
|
||||
{
|
||||
// Display 'ms' next to the 'Loop Interval' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');"));
|
||||
oappend(F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');"));
|
||||
// Display '°C' next to the 'Activation Threshold' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');"));
|
||||
oappend(F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');"));
|
||||
// Display '0 = Disabled' next to the 'Preset To Activate' setting
|
||||
oappend(SET_F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');"));
|
||||
oappend(F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');"));
|
||||
}
|
||||
|
||||
bool readFromConfig(JsonObject &root)
|
||||
|
@ -511,8 +511,8 @@ void PIRsensorSwitch::addToConfig(JsonObject &root)
|
||||
|
||||
void PIRsensorSwitch::appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
|
||||
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
|
||||
char str[128];
|
||||
sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i);
|
||||
|
@ -377,10 +377,10 @@ class St7789DisplayUsermod : public Usermod {
|
||||
|
||||
|
||||
void appendConfigData() override {
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -435,10 +435,10 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void UsermodTemperature::appendConfigData() {
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
||||
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
||||
oappend(F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||
oappend(F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
float UsermodTemperature::getTemperature() {
|
||||
|
@ -191,8 +191,8 @@ constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT resul
|
||||
#define LOG_256 5.54517744f // log(256)
|
||||
|
||||
// These are the input and output vectors. Input vectors receive computed results from FFT.
|
||||
static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins
|
||||
static float vImag[samplesFFT] = {0.0f}; // imaginary parts
|
||||
static float* vReal = nullptr; // FFT sample inputs / freq output - these are our raw result bins
|
||||
static float* vImag = nullptr; // imaginary parts
|
||||
|
||||
// Create FFT object
|
||||
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||
@ -200,14 +200,9 @@ static float vImag[samplesFFT] = {0.0f}; // imaginary parts
|
||||
// #define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc) - not faster on ESP32
|
||||
// #define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - slower on ESP32
|
||||
// Below options are forcing ArduinoFFT to use sqrtf() instead of sqrt()
|
||||
#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32
|
||||
#define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83
|
||||
|
||||
#include <arduinoFFT.h>
|
||||
|
||||
/* Create FFT object with weighing factor storage */
|
||||
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, true);
|
||||
// #define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83 - since v2.0.0 this must be done in build_flags
|
||||
|
||||
#include <arduinoFFT.h> // FFT object is created in FFTcode
|
||||
// Helper functions
|
||||
|
||||
// compute average of several FFT result bins
|
||||
@ -226,6 +221,18 @@ void FFTcode(void * parameter)
|
||||
{
|
||||
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
|
||||
|
||||
// allocate FFT buffers on first call
|
||||
if (vReal == nullptr) vReal = (float*) calloc(sizeof(float), samplesFFT);
|
||||
if (vImag == nullptr) vImag = (float*) calloc(sizeof(float), samplesFFT);
|
||||
if ((vReal == nullptr) || (vImag == nullptr)) {
|
||||
// something went wrong
|
||||
if (vReal) free(vReal); vReal = nullptr;
|
||||
if (vImag) free(vImag); vImag = nullptr;
|
||||
return;
|
||||
}
|
||||
// Create FFT object with weighing factor storage
|
||||
ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, true);
|
||||
|
||||
// see https://www.freertos.org/vtaskdelayuntil.html
|
||||
const TickType_t xFrequency = FFT_MIN_CYCLE * portTICK_PERIOD_MS;
|
||||
|
||||
@ -247,6 +254,7 @@ void FFTcode(void * parameter)
|
||||
|
||||
// get a fresh batch of samples from I2S
|
||||
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
|
||||
memset(vImag, 0, samplesFFT * sizeof(float)); // set imaginary parts to 0
|
||||
|
||||
#if defined(WLED_DEBUG) || defined(SR_DEBUG)
|
||||
if (start < esp_timer_get_time()) { // filter out overflows
|
||||
@ -265,8 +273,6 @@ void FFTcode(void * parameter)
|
||||
// find highest sample in the batch
|
||||
float maxSample = 0.0f; // max sample from FFT batch
|
||||
for (int i=0; i < samplesFFT; i++) {
|
||||
// set imaginary parts to 0
|
||||
vImag[i] = 0;
|
||||
// pick our our current mic sample - we take the max value from all samples that go into FFT
|
||||
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts
|
||||
if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]);
|
||||
@ -297,7 +303,7 @@ void FFTcode(void * parameter)
|
||||
#endif
|
||||
|
||||
} else { // noise gate closed - only clear results as FFT was skipped. MIC samples are still valid when we do this.
|
||||
memset(vReal, 0, sizeof(vReal));
|
||||
memset(vReal, 0, samplesFFT * sizeof(float));
|
||||
FFT_MajorPeak = 1;
|
||||
FFT_Magnitude = 0.001;
|
||||
}
|
||||
@ -1879,57 +1885,59 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
void appendConfigData() override
|
||||
void appendConfigData(Print& uiScript) override
|
||||
{
|
||||
uiScript.print(F("ux='AudioReactive';")); // ux = shortcut for Audioreactive - fingers crossed that "ux" isn't already used as JS var, html post parameter or css style
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');"));
|
||||
uiScript.print(F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[]
|
||||
uiScript.print(F("dd=addDropdown(ux,'digitalmic:type');"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
oappend(SET_F("addOption(dd,'Generic Analog',0);"));
|
||||
uiScript.print(F("addOption(dd,'Generic Analog',0);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'Generic I2S',1);"));
|
||||
oappend(SET_F("addOption(dd,'ES7243',2);"));
|
||||
oappend(SET_F("addOption(dd,'SPH0654',3);"));
|
||||
oappend(SET_F("addOption(dd,'Generic I2S with Mclk',4);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S',1);"));
|
||||
uiScript.print(F("addOption(dd,'ES7243',2);"));
|
||||
uiScript.print(F("addOption(dd,'SPH0654',3);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S with Mclk',4);"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
oappend(SET_F("addOption(dd,'Generic I2S PDM',5);"));
|
||||
uiScript.print(F("addOption(dd,'Generic I2S PDM',5);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'ES8388',6);"));
|
||||
uiScript.print(F("addOption(dd,'ES8388',6);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','config:AGC');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
oappend(SET_F("addOption(dd,'Normal',1);"));
|
||||
oappend(SET_F("addOption(dd,'Vivid',2);"));
|
||||
oappend(SET_F("addOption(dd,'Lazy',3);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'config:AGC');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("addOption(dd,'Normal',1);"));
|
||||
uiScript.print(F("addOption(dd,'Vivid',2);"));
|
||||
uiScript.print(F("addOption(dd,'Lazy',3);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','dynamics:limiter');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
oappend(SET_F("addOption(dd,'On',1);"));
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:rise',1,'ms <i>(♪ effects only)</i>');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:dynamics:fall',1,'ms <i>(♪ effects only)</i>');"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'dynamics:limiter');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("addOption(dd,'On',1);"));
|
||||
uiScript.print(F("addInfo(ux+':dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field
|
||||
uiScript.print(F("addInfo(ux+':dynamics:rise',1,'ms <i>(♪ effects only)</i>');"));
|
||||
uiScript.print(F("addInfo(ux+':dynamics:fall',1,'ms <i>(♪ effects only)</i>');"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','frequency:scale');"));
|
||||
oappend(SET_F("addOption(dd,'None',0);"));
|
||||
oappend(SET_F("addOption(dd,'Linear (Amplitude)',2);"));
|
||||
oappend(SET_F("addOption(dd,'Square Root (Energy)',3);"));
|
||||
oappend(SET_F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'frequency:scale');"));
|
||||
uiScript.print(F("addOption(dd,'None',0);"));
|
||||
uiScript.print(F("addOption(dd,'Linear (Amplitude)',2);"));
|
||||
uiScript.print(F("addOption(dd,'Square Root (Energy)',3);"));
|
||||
uiScript.print(F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||
#endif
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
uiScript.print(F("dd=addDropdown(ux,'sync:mode');"));
|
||||
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("addOption(dd,'Send',1);"));
|
||||
uiScript.print(F("addOption(dd,'Send',1);"));
|
||||
#endif
|
||||
oappend(SET_F("addOption(dd,'Receive',2);"));
|
||||
uiScript.print(F("addOption(dd,'Receive',2);"));
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',0,'<i>sd/data/dout</i>','I2S SD');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',1,'<i>ws/clk/lrck</i>','I2S WS');"));
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',2,'<i>sck/bclk</i>','I2S SCK');"));
|
||||
uiScript.print(F("addInfo(ux+':digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
||||
uiScript.print(F("addInfo(uxp,0,'<i>sd/data/dout</i>','I2S SD');"));
|
||||
uiScript.print(F("addInfo(uxp,1,'<i>ws/clk/lrck</i>','I2S WS');"));
|
||||
uiScript.print(F("addInfo(uxp,2,'<i>sck/bclk</i>','I2S SCK');"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'<i>only use -1, 0, 1 or 3</i>','I2S MCLK');"));
|
||||
uiScript.print(F("addInfo(uxp,3,'<i>only use -1, 0, 1 or 3</i>','I2S MCLK');"));
|
||||
#else
|
||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'<i>master clock</i>','I2S MCLK');"));
|
||||
uiScript.print(F("addInfo(uxp,3,'<i>master clock</i>','I2S MCLK');"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ There are however plans to create a lightweight audioreactive for the 8266, with
|
||||
### using latest _arduinoFFT_ library version 2.x
|
||||
The latest arduinoFFT release version should be used for audioreactive.
|
||||
|
||||
* `build_flags` = `-D USERMOD_AUDIOREACTIVE`
|
||||
* `build_flags` = `-D USERMOD_AUDIOREACTIVE -D sqrt_internal=sqrtf`
|
||||
* `lib_deps`= `kosme/arduinoFFT @ 2.0.1`
|
||||
|
||||
## Configuration
|
||||
|
@ -305,14 +305,14 @@ class BobLightUsermod : public Usermod {
|
||||
}
|
||||
|
||||
void appendConfigData() override {
|
||||
//oappend(SET_F("dd=addDropdown('usermod','selectfield');"));
|
||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
||||
oappend(SET_F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||
//oappend(F("dd=addDropdown('usermod','selectfield');"));
|
||||
//oappend(F("addOption(dd,'1st value',0);"));
|
||||
//oappend(F("addOption(dd,'2nd value',1);"));
|
||||
oappend(F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
void addToConfig(JsonObject& root) override {
|
||||
|
@ -264,7 +264,7 @@ void MultiRelay::handleOffTimer() {
|
||||
void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer
|
||||
DEBUG_PRINTLN(F("Relays: Initialize HTML API"));
|
||||
|
||||
server.on(SET_F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) {
|
||||
server.on(F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) {
|
||||
DEBUG_PRINTLN(F("Relays: HTML API"));
|
||||
String janswer;
|
||||
String error = "";
|
||||
@ -765,10 +765,10 @@ void MultiRelay::addToConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void MultiRelay::appendConfigData() {
|
||||
oappend(SET_F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(SET_F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
||||
//oappend(SET_F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');"));
|
||||
oappend(SET_F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
oappend(F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
||||
//oappend(F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');"));
|
||||
oappend(F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,23 +387,23 @@ class PixelsDiceTrayUsermod : public Usermod {
|
||||
// To work around this, add info text to the end of the preceding item.
|
||||
//
|
||||
// See addInfo in wled00/data/settings_um.htm for details on what this function does.
|
||||
oappend(SET_F(
|
||||
oappend(F(
|
||||
"addInfo('DiceTray:ble_scan_duration',1,'<br><br><i>Set to \"*\" to "
|
||||
"connect to any die.<br>Leave Blank to disable.</i><br><i "
|
||||
"class=\"warn\">Saving will replace \"*\" with die names.</i>','');"));
|
||||
#if USING_TFT_DISPLAY
|
||||
oappend(SET_F("ddr=addDropdown('DiceTray','rotation');"));
|
||||
oappend(SET_F("addOption(ddr,'0 deg',0);"));
|
||||
oappend(SET_F("addOption(ddr,'90 deg',1);"));
|
||||
oappend(SET_F("addOption(ddr,'180 deg',2);"));
|
||||
oappend(SET_F("addOption(ddr,'270 deg',3);"));
|
||||
oappend(SET_F(
|
||||
oappend(F("ddr=addDropdown('DiceTray','rotation');"));
|
||||
oappend(F("addOption(ddr,'0 deg',0);"));
|
||||
oappend(F("addOption(ddr,'90 deg',1);"));
|
||||
oappend(F("addOption(ddr,'180 deg',2);"));
|
||||
oappend(F("addOption(ddr,'270 deg',3);"));
|
||||
oappend(F(
|
||||
"addInfo('DiceTray:rotation',1,'<br><i class=\"warn\">DO NOT CHANGE "
|
||||
"SPI PINS.</i><br><i class=\"warn\">CHANGES ARE IGNORED.</i>','');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
||||
oappend(SET_F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
||||
oappend(F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -310,22 +310,22 @@ void ShtUsermod::onMqttConnect(bool sessionPresent) {
|
||||
* @return void
|
||||
*/
|
||||
void ShtUsermod::appendConfigData() {
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(_name);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_shtType);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'SHT30',0);"));
|
||||
oappend(SET_F("addOption(dd,'SHT31',1);"));
|
||||
oappend(SET_F("addOption(dd,'SHT35',2);"));
|
||||
oappend(SET_F("addOption(dd,'SHT85',3);"));
|
||||
oappend(SET_F("dd=addDropdown('"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'SHT30',0);"));
|
||||
oappend(F("addOption(dd,'SHT31',1);"));
|
||||
oappend(F("addOption(dd,'SHT35',2);"));
|
||||
oappend(F("addOption(dd,'SHT85',3);"));
|
||||
oappend(F("dd=addDropdown('"));
|
||||
oappend(_name);
|
||||
oappend(SET_F("','"));
|
||||
oappend(F("','"));
|
||||
oappend(_unitOfTemp);
|
||||
oappend(SET_F("');"));
|
||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
||||
oappend(F("');"));
|
||||
oappend(F("addOption(dd,'Celsius',0);"));
|
||||
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ void setup() {
|
||||
jsonTransitionOnce = true;
|
||||
strip.setTransition(0); //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
|
@ -86,7 +86,7 @@ void startWipe()
|
||||
bri = briLast; //turn on
|
||||
transitionDelayTemp = 0; //no transition
|
||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||
resetTimebase(); //make sure wipe starts from beginning
|
||||
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||
|
||||
//set wipe direction
|
||||
Segment& seg = strip.getSegment(0);
|
||||
|
@ -7,11 +7,12 @@ platform = ${esp32.platform}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp32}
|
||||
-D USERMOD_FOUR_LINE_DISPLAY -D USE_ALT_DISPlAY
|
||||
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
|
||||
upload_speed = 460800
|
||||
-D USERMOD_FOUR_LINE_DISPLAY
|
||||
-D FLD_TYPE=SH1106
|
||||
-D I2CSCLPIN=27
|
||||
-D I2CSDAPIN=26
|
||||
|
||||
lib_deps =
|
||||
${esp32.lib_deps}
|
||||
U8g2@~2.34.4
|
||||
Wire
|
||||
|
@ -1,16 +1,8 @@
|
||||
# I2C/SPI 4 Line Display Usermod ALT
|
||||
|
||||
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
|
||||
"usermod_v2_four_line_display"
|
||||
"usermod_v2_rotary_encoder_ui"
|
||||
This usermod could be used in compination with `usermod_v2_rotary_encoder_ui_ALT`.
|
||||
|
||||
The core of these usermods are a copy of the originals. The main changes are to the FourLineDisplay usermod.
|
||||
The display usermod UI has been completely changed.
|
||||
|
||||
|
||||
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
||||
Without the display, it functions identical to the original.
|
||||
The original "usermod_v2_auto_save" will not work with the display just yet.
|
||||
## Functionalities
|
||||
|
||||
Press the encoder to cycle through the options:
|
||||
* Brightness
|
||||
@ -18,26 +10,18 @@ Press the encoder to cycle through the options:
|
||||
* Intensity
|
||||
* Palette
|
||||
* Effect
|
||||
* Main Color (only if display is used)
|
||||
* Saturation (only if display is used)
|
||||
* Main Color
|
||||
* Saturation
|
||||
|
||||
Press and hold the encoder to display Network Info. If AP is active, it will display AP, SSID and password
|
||||
Press and hold the encoder to display Network Info. If AP is active, it will display the AP, SSID and Password
|
||||
|
||||
Also shows if the timer is enabled
|
||||
Also shows if the timer is enabled.
|
||||
|
||||
[See the pair of usermods in action](https://www.youtube.com/watch?v=ulZnBt9z3TI)
|
||||
|
||||
## Installation
|
||||
|
||||
Please refer to the original `usermod_v2_rotary_encoder_ui` readme for the main instructions.
|
||||
|
||||
Copy the example `platformio_override.sample.ini` from the usermod_v2_rotary_encoder_ui_ALT folder to the root directory of your particular build and rename it to `platformio_override.ini`.
|
||||
|
||||
This file should be placed in the same directory as `platformio.ini`.
|
||||
|
||||
Then, to activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file,
|
||||
or add `-D USE_ALT_DISPlAY` to the original `platformio_override.ini.sample` file
|
||||
|
||||
Copy the example `platformio_override.sample.ini` to the root directory of your particular build.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -1202,21 +1202,21 @@ void FourLineDisplayUsermod::onUpdateBegin(bool init) {
|
||||
//}
|
||||
|
||||
void FourLineDisplayUsermod::appendConfigData() {
|
||||
oappend(SET_F("dd=addDropdown('4LineDisplay','type');"));
|
||||
oappend(SET_F("addOption(dd,'None',0);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306',1);"));
|
||||
oappend(SET_F("addOption(dd,'SH1106',2);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1305',4);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1309 128x64',9);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||
oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
||||
oappend(F("dd=addDropdown('4LineDisplay','type');"));
|
||||
oappend(F("addOption(dd,'None',0);"));
|
||||
oappend(F("addOption(dd,'SSD1306',1);"));
|
||||
oappend(F("addOption(dd,'SH1106',2);"));
|
||||
oappend(F("addOption(dd,'SSD1306 128x64',3);"));
|
||||
oappend(F("addOption(dd,'SSD1305',4);"));
|
||||
oappend(F("addOption(dd,'SSD1305 128x64',5);"));
|
||||
oappend(F("addOption(dd,'SSD1309 128x64',9);"));
|
||||
oappend(F("addOption(dd,'SSD1306 SPI',6);"));
|
||||
oappend(F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||
oappend(F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||
oappend(F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
||||
oappend(F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -0,0 +1,14 @@
|
||||
[platformio]
|
||||
default_envs = esp32dev
|
||||
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
platform = ${esp32.platform}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp32}
|
||||
-D USERMOD_ROTARY_ENCODER_UI
|
||||
-D USERMOD_ROTARY_ENCODER_GPIO=INPUT
|
||||
-D ENCODER_DT_PIN=21
|
||||
-D ENCODER_CLK_PIN=23
|
||||
-D ENCODER_SW_PIN=0
|
@ -1,16 +1,8 @@
|
||||
# Rotary Encoder UI Usermod ALT
|
||||
|
||||
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
|
||||
"usermod_v2_four_line_display"
|
||||
"usermod_v2_rotary_encoder_ui"
|
||||
This usermod supports the UI of the `usermod_v2_rotary_encoder_ui_ALT`.
|
||||
|
||||
The core of these usermods are a copy of the originals. The main changes are to the FourLineDisplay usermod.
|
||||
The display usermod UI has been completely changed.
|
||||
|
||||
|
||||
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
||||
Without the display, it functions identical to the original.
|
||||
The original "usermod_v2_auto_save" will not work with the display just yet.
|
||||
## Functionalities
|
||||
|
||||
Press the encoder to cycle through the options:
|
||||
* Brightness
|
||||
@ -21,8 +13,7 @@ Press the encoder to cycle through the options:
|
||||
* Main Color (only if display is used)
|
||||
* Saturation (only if display is used)
|
||||
|
||||
Press and hold the encoder to display Network Info
|
||||
if AP is active, it will display the AP, SSID and Password
|
||||
Press and hold the encoder to display Network Info. If AP is active, it will display the AP, SSID and Password
|
||||
|
||||
Also shows if the timer is enabled.
|
||||
|
||||
@ -30,9 +21,7 @@ Also shows if the timer is enabled.
|
||||
|
||||
## Installation
|
||||
|
||||
Copy the example `platformio_override.sample.ini` to the root directory of your particular build and rename it to `platformio_override.ini`.
|
||||
|
||||
To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file, or add `-D USE_ALT_DISPlAY` to your `platformio_override.ini` file
|
||||
Copy the example `platformio_override.sample.ini` to the root directory of your particular build.
|
||||
|
||||
### Define Your Options
|
||||
|
||||
@ -40,7 +29,6 @@ To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE
|
||||
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp
|
||||
also tells this usermod that the display is available
|
||||
(see the Four Line Display usermod `readme.md` for more details)
|
||||
* `USE_ALT_DISPlAY` - Mandatory to use Four Line Display
|
||||
* `ENCODER_DT_PIN` - defaults to 18
|
||||
* `ENCODER_CLK_PIN` - defaults to 5
|
||||
* `ENCODER_SW_PIN` - defaults to 19
|
||||
@ -50,7 +38,7 @@ To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE
|
||||
|
||||
### PlatformIO requirements
|
||||
|
||||
Note: the Four Line Display usermod requires the libraries `U8g2` and `Wire`.
|
||||
No special requirements.
|
||||
|
||||
## Change Log
|
||||
|
||||
|
@ -1090,8 +1090,8 @@ void RotaryEncoderUIUsermod::addToConfig(JsonObject &root) {
|
||||
}
|
||||
|
||||
void RotaryEncoderUIUsermod::appendConfigData() {
|
||||
oappend(SET_F("addInfo('Rotary-Encoder:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(SET_F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
oappend(F("addInfo('Rotary-Encoder:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||
oappend(F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -433,8 +433,8 @@ class WordClockUsermod : public Usermod
|
||||
|
||||
void appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');"));
|
||||
oappend(SET_F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');"));
|
||||
oappend(F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');"));
|
||||
oappend(F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -54,13 +54,13 @@ class WireguardUsermod : public Usermod {
|
||||
}
|
||||
|
||||
void appendConfigData() {
|
||||
oappend(SET_F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
void addToConfig(JsonObject& root) {
|
||||
|
@ -2,24 +2,10 @@
|
||||
WS2812FX.cpp contains all effect methods
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
@ -1980,7 +1966,7 @@ uint16_t mode_palette() {
|
||||
const bool inputAnimateRotation = SEGMENT.check2;
|
||||
const bool inputAssumeSquare = SEGMENT.check3;
|
||||
|
||||
const angleType theta = (!inputAnimateRotation) ? (inputRotation * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
|
||||
const angleType theta = (!inputAnimateRotation) ? ((inputRotation + 128) * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
|
||||
const mathType sinTheta = sinFunction(theta);
|
||||
const mathType cosTheta = cosFunction(theta);
|
||||
|
||||
@ -1999,7 +1985,7 @@ uint16_t mode_palette() {
|
||||
// So the rectangle needs to have exactly the right size. That size depends on the rotation.
|
||||
// This scale computation here only considers one dimension. You can think of it like the rectangle is always scaled so that
|
||||
// the left and right most points always match the left and right side of the display.
|
||||
const mathType scale = std::abs(sinTheta) + (std::abs(cosTheta) * maxYOut / maxXOut);
|
||||
const mathType scale = std::abs(sinTheta) + (std::abs(cosTheta) * maxYOut / maxXOut);
|
||||
// 2D simulation:
|
||||
// If we are dealing with a 1D setup, we assume that each segment represents one line on a 2-dimensional display.
|
||||
// The function is called once per segments, so we need to handle one line at a time.
|
||||
@ -2030,8 +2016,8 @@ uint16_t mode_palette() {
|
||||
colorIndex = ((inputSize - 112) * colorIndex) / 16;
|
||||
}
|
||||
// Finally, shift the palette a bit.
|
||||
const int paletteOffset = (!inputAnimateShift) ? (inputShift-128) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
|
||||
colorIndex += paletteOffset;
|
||||
const int paletteOffset = (!inputAnimateShift) ? (inputShift) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
|
||||
colorIndex -= paletteOffset;
|
||||
const uint32_t color = SEGMENT.color_wheel((uint8_t)colorIndex);
|
||||
if (isMatrix) {
|
||||
SEGMENT.setPixelColorXY(x, y, color);
|
||||
@ -2042,7 +2028,7 @@ uint16_t mode_palette() {
|
||||
}
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Anamorphic;;!;12;c1=128,c2=128,c3=128,o1=1,o2=1,o3=0";
|
||||
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Anamorphic;;!;12;ix=112,c1=0,o1=1,o2=0,o3=1";
|
||||
|
||||
|
||||
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active
|
||||
@ -2520,9 +2506,9 @@ static uint16_t ripple_base() {
|
||||
#endif
|
||||
{
|
||||
int left = rippleorigin - propI -1;
|
||||
int right = rippleorigin + propI +3;
|
||||
int right = rippleorigin + propI +2;
|
||||
for (int v = 0; v < 4; v++) {
|
||||
unsigned mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp);
|
||||
unsigned mag = scale8(cubicwave8((propF>>2) + v * 64), amp);
|
||||
SEGMENT.setPixelColor(left + v, color_blend(SEGMENT.getPixelColor(left + v), col, mag)); // TODO
|
||||
SEGMENT.setPixelColor(right - v, color_blend(SEGMENT.getPixelColor(right - v), col, mag)); // TODO
|
||||
}
|
||||
@ -3561,7 +3547,7 @@ uint16_t mode_exploding_fireworks(void)
|
||||
if (segs <= (strip.getMaxSegments() /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs
|
||||
int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg
|
||||
|
||||
unsigned numSparks = min(2 + ((rows*cols) >> 1), maxSparks);
|
||||
unsigned numSparks = min(5 + ((rows*cols) >> 1), maxSparks);
|
||||
unsigned dataSize = sizeof(spark) * numSparks;
|
||||
if (!SEGENV.allocateData(dataSize + sizeof(float))) return mode_static(); //allocation failed
|
||||
float *dying_gravity = reinterpret_cast<float*>(SEGENV.data + dataSize);
|
||||
@ -3616,7 +3602,8 @@ uint16_t mode_exploding_fireworks(void)
|
||||
* Size is proportional to the height.
|
||||
*/
|
||||
unsigned nSparks = flare->pos + random8(4);
|
||||
nSparks = constrain(nSparks, 4, numSparks);
|
||||
nSparks = std::max(nSparks, 4U); // This is not a standard constrain; numSparks is not guaranteed to be at least 4
|
||||
nSparks = std::min(nSparks, numSparks);
|
||||
|
||||
// initialize sparks
|
||||
if (SEGENV.aux0 == 2) {
|
||||
@ -4031,7 +4018,7 @@ uint16_t mode_pacifica()
|
||||
|
||||
// Increment the four "color index start" counters, one for each wave layer.
|
||||
// Each is incremented at a different speed, and the speeds vary over time.
|
||||
unsigned sCIStart1 = SEGENV.aux0, sCIStart2 = SEGENV.aux1, sCIStart3 = SEGENV.step, sCIStart4 = SEGENV.step >> 16;
|
||||
unsigned sCIStart1 = SEGENV.aux0, sCIStart2 = SEGENV.aux1, sCIStart3 = SEGENV.step & 0xFFFF, sCIStart4 = (SEGENV.step >> 16);
|
||||
uint32_t deltams = (FRAMETIME >> 2) + ((FRAMETIME * SEGMENT.speed) >> 7);
|
||||
uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7);
|
||||
strip.now = deltat;
|
||||
@ -4046,7 +4033,7 @@ uint16_t mode_pacifica()
|
||||
sCIStart3 -= (deltams1 * beatsin88_t(501,5,7));
|
||||
sCIStart4 -= (deltams2 * beatsin88_t(257,4,6));
|
||||
SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2;
|
||||
SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3;
|
||||
SEGENV.step = (sCIStart4 << 16) | (sCIStart3 & 0xFFFF);
|
||||
|
||||
// Clear out the LED array to a dim background blue-green
|
||||
//SEGMENT.fill(132618);
|
||||
@ -4077,7 +4064,7 @@ uint16_t mode_pacifica()
|
||||
c.green = scale8(c.green, 200);
|
||||
c |= CRGB( 2, 5, 7);
|
||||
|
||||
SEGMENT.setPixelColor(i, c.red, c.green, c.blue);
|
||||
SEGMENT.setPixelColor(i, c);
|
||||
}
|
||||
|
||||
strip.now = nowOld;
|
||||
@ -4644,7 +4631,7 @@ uint16_t mode_tv_simulator(void) {
|
||||
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;";
|
||||
static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;!;01";
|
||||
|
||||
|
||||
/*
|
||||
|
70
wled00/FX.h
70
wled00/FX.h
@ -2,24 +2,10 @@
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified for WLED
|
||||
*/
|
||||
@ -61,6 +47,15 @@
|
||||
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||
#define FRAMETIME strip.getFrameTime()
|
||||
|
||||
// FPS calculation (can be defined as compile flag for debugging)
|
||||
#ifndef FPS_CALC_AVG
|
||||
#define FPS_CALC_AVG 7 // average FPS calculation over this many frames (moving average)
|
||||
#endif
|
||||
#ifndef FPS_MULTIPLIER
|
||||
#define FPS_MULTIPLIER 1 // dev option: multiplier to get sub-frame FPS without floats
|
||||
#endif
|
||||
#define FPS_CALC_SHIFT 7 // bit shift for fixed point math
|
||||
|
||||
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#ifdef ESP8266
|
||||
@ -539,12 +534,12 @@ typedef struct Segment {
|
||||
inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||
|
||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
void setCCT(uint16_t k);
|
||||
void setOpacity(uint8_t o);
|
||||
void setOption(uint8_t n, bool val);
|
||||
void setMode(uint8_t fx, bool loadDefaults = false);
|
||||
void setPalette(uint8_t pal);
|
||||
Segment &setColor(uint8_t slot, uint32_t c);
|
||||
Segment &setCCT(uint16_t k);
|
||||
Segment &setOpacity(uint8_t o);
|
||||
Segment &setOption(uint8_t n, bool val);
|
||||
Segment &setMode(uint8_t fx, bool loadDefaults = false);
|
||||
Segment &setPalette(uint8_t pal);
|
||||
uint8_t differs(Segment& b) const;
|
||||
void refreshLightCapabilities();
|
||||
|
||||
@ -559,7 +554,7 @@ typedef struct Segment {
|
||||
* Call resetIfRequired before calling the next effect function.
|
||||
* Safe to call from interrupts and network requests.
|
||||
*/
|
||||
inline void markForReset() { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
||||
inline Segment &markForReset() { reset = true; return *this; } // setOption(SEG_OPTION_RESET, true)
|
||||
|
||||
// transition functions
|
||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||
@ -613,9 +608,15 @@ typedef struct Segment {
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
[[gnu::hot]] uint16_t virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
[[gnu::hot]] uint16_t virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
[[gnu::hot]] unsigned virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
[[gnu::hot]] unsigned virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
inline unsigned nrOfVStrips() const { // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
return (is2D() && map1D2D == M12_pBar) ? virtualWidth() : 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
#ifndef WLED_DISABLE_2D
|
||||
[[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment
|
||||
[[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
@ -720,7 +721,11 @@ class WS2812FX { // 96 bytes
|
||||
#ifndef WLED_DISABLE_2D
|
||||
panels(1),
|
||||
#endif
|
||||
#ifdef WLED_AUTOSEGMENTS
|
||||
autoSegments(true),
|
||||
#else
|
||||
autoSegments(false),
|
||||
#endif
|
||||
correctWB(false),
|
||||
cctFromRgb(false),
|
||||
// semi-private (just obscured) used in effect functions through macros
|
||||
@ -733,7 +738,7 @@ class WS2812FX { // 96 bytes
|
||||
_transitionDur(750),
|
||||
_targetFps(WLED_FPS),
|
||||
_frametime(FRAMETIME_FIXED),
|
||||
_cumulativeFps(2),
|
||||
_cumulativeFps(50 << FPS_CALC_SHIFT),
|
||||
_isServicing(false),
|
||||
_isOffRefreshRequired(false),
|
||||
_hasWhiteChannel(false),
|
||||
@ -788,7 +793,8 @@ class WS2812FX { // 96 bytes
|
||||
setTargetFps(uint8_t fps),
|
||||
setupEffectData(); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void resetTimebase() { timebase = 0UL - millis(); }
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) { seg.markForReset().resetIfRequired(); } }
|
||||
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
@ -844,10 +850,8 @@ class WS2812FX { // 96 bytes
|
||||
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms)
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase,
|
||||
getPixelColor(uint16_t) const;
|
||||
unsigned long now, timebase;
|
||||
uint32_t getPixelColor(unsigned) const;
|
||||
|
||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
FX_2Dfcn.cpp contains all 2D utility functions
|
||||
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2022 Blaz Kristan (https://blaz.at/home)
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Parts of the code adapted from WLED Sound Reactive
|
||||
*/
|
||||
@ -171,7 +156,7 @@ uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
||||
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
if (!isActive()) return; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
@ -266,7 +251,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||
// returns RGBW values of pixel
|
||||
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
||||
if (!isActive()) return 0; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if (reverse ) x = virtualWidth() - x - 1;
|
||||
if (reverse_y) y = virtualHeight() - y - 1;
|
||||
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
||||
|
@ -2,24 +2,10 @@
|
||||
WS2812FX_fcn.cpp contains all utility functions
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
@ -523,46 +509,53 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
||||
}
|
||||
|
||||
|
||||
bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed
|
||||
if (slot >= NUM_COLORS || c == colors[slot]) return false;
|
||||
Segment &Segment::setColor(uint8_t slot, uint32_t c) {
|
||||
if (slot >= NUM_COLORS || c == colors[slot]) return *this;
|
||||
if (!_isRGB && !_hasW) {
|
||||
if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black
|
||||
if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black
|
||||
if (slot == 0 && c == BLACK) return *this; // on/off segment cannot have primary color black
|
||||
if (slot == 1 && c != BLACK) return *this; // on/off segment cannot have secondary color non black
|
||||
}
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
colors[slot] = c;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
return true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setCCT(uint16_t k) {
|
||||
Segment &Segment::setCCT(uint16_t k) {
|
||||
if (k > 255) { //kelvin value, convert to 0-255
|
||||
if (k < 1900) k = 1900;
|
||||
if (k > 10091) k = 10091;
|
||||
k = (k - 1900) >> 5;
|
||||
}
|
||||
if (cct == k) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
cct = k;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
if (cct != k) {
|
||||
//DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k);
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
cct = k;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setOpacity(uint8_t o) {
|
||||
if (opacity == o) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
Segment &Segment::setOpacity(uint8_t o) {
|
||||
if (opacity != o) {
|
||||
//DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
|
||||
startTransition(strip.getTransition()); // start transition prior to change
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setOption(uint8_t n, bool val) {
|
||||
Segment &Segment::setOption(uint8_t n, bool val) {
|
||||
bool prevOn = on;
|
||||
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||
if (val) options |= 0x01 << n;
|
||||
else options &= ~(0x01 << n);
|
||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
Segment &Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
// skip reserved
|
||||
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
||||
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
||||
@ -594,9 +587,10 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
markForReset();
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Segment::setPalette(uint8_t pal) {
|
||||
Segment &Segment::setPalette(uint8_t pal) {
|
||||
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes
|
||||
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes
|
||||
if (pal != palette) {
|
||||
@ -604,37 +598,24 @@ void Segment::setPalette(uint8_t pal) {
|
||||
palette = pal;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
uint16_t IRAM_ATTR Segment::virtualWidth() const {
|
||||
unsigned IRAM_ATTR Segment::virtualWidth() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
||||
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vWidth;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR Segment::virtualHeight() const {
|
||||
unsigned IRAM_ATTR Segment::virtualHeight() const {
|
||||
unsigned groupLen = groupLength();
|
||||
unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
|
||||
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vHeight;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const {
|
||||
unsigned vLen = 1;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
switch (map1D2D) {
|
||||
case M12_pBar:
|
||||
vLen = virtualWidth();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return vLen;
|
||||
}
|
||||
|
||||
// Constants for mapping mode "Pinwheel"
|
||||
#ifndef WLED_DISABLE_2D
|
||||
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
|
||||
@ -1201,10 +1182,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
|
||||
//do not call this method from system context (network callback)
|
||||
void WS2812FX::finalizeInit() {
|
||||
//reset segment runtimes
|
||||
for (segment &seg : _segments) {
|
||||
seg.markForReset();
|
||||
seg.resetIfRequired();
|
||||
}
|
||||
restartRuntime();
|
||||
|
||||
// for the lack of better place enumerate ledmaps here
|
||||
// if we do it in json.cpp (serializeInfo()) we are getting flashes on LEDs
|
||||
@ -1308,14 +1286,9 @@ void WS2812FX::finalizeInit() {
|
||||
_isOffRefreshRequired |= bus->isOffRefreshRequired() && !bus->isPWM(); // use refresh bit for phase shift with analog
|
||||
unsigned busEnd = bus->getStart() + bus->getLength();
|
||||
if (busEnd > _length) _length = busEnd;
|
||||
#ifdef ESP8266
|
||||
// why do we need to reinitialise GPIO3???
|
||||
//if (!bus->isDigital() || bus->is2Pin()) continue;
|
||||
//uint8_t pins[5];
|
||||
//if (!bus->getPins(pins)) continue;
|
||||
//BusDigital* bd = static_cast<BusDigital*>(bus);
|
||||
//if (pins[0] == 3) bd->reinit();
|
||||
#endif
|
||||
|
||||
// This must be done after all buses have been created, as some kinds (parallel I2S) interact
|
||||
bus->begin();
|
||||
}
|
||||
|
||||
Segment::maxWidth = _length;
|
||||
@ -1351,7 +1324,7 @@ void WS2812FX::service() {
|
||||
if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
||||
{
|
||||
doShow = true;
|
||||
unsigned delay = FRAMETIME;
|
||||
unsigned frameDelay = FRAMETIME;
|
||||
|
||||
if (!seg.freeze) { //only run effect function if not frozen
|
||||
int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based)
|
||||
@ -1371,7 +1344,7 @@ void WS2812FX::service() {
|
||||
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
|
||||
// would need to be allocated for each effect and then blended together for each pixel.
|
||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||
frameDelay = (*_mode[seg.mode])(); // run new/current mode
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
Segment::tmpsegd_t _tmpSegData;
|
||||
@ -1380,16 +1353,16 @@ void WS2812FX::service() {
|
||||
_virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed)
|
||||
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
||||
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
||||
delay = MIN(delay,d2); // use shortest delay
|
||||
frameDelay = min(frameDelay,d2); // use shortest delay
|
||||
Segment::modeBlend(false); // unset semaphore
|
||||
}
|
||||
#endif
|
||||
seg.call++;
|
||||
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||
if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition
|
||||
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||
}
|
||||
|
||||
seg.next_time = nowUp + delay;
|
||||
seg.next_time = nowUp + frameDelay;
|
||||
}
|
||||
_segment_index++;
|
||||
}
|
||||
@ -1416,7 +1389,7 @@ void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) {
|
||||
BusManager::setPixelColor(i, col);
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) const {
|
||||
uint32_t IRAM_ATTR WS2812FX::getPixelColor(unsigned i) const {
|
||||
i = getMappedPixelIndex(i);
|
||||
if (i >= _length) return 0;
|
||||
return BusManager::getPixelColor(i);
|
||||
@ -1434,10 +1407,12 @@ void WS2812FX::show() {
|
||||
|
||||
unsigned long showNow = millis();
|
||||
size_t diff = showNow - _lastShow;
|
||||
size_t fpsCurr = 200;
|
||||
if (diff > 0) fpsCurr = 1000 / diff;
|
||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
|
||||
_lastShow = showNow;
|
||||
|
||||
if (diff > 0) { // skip calculation if no time has passed
|
||||
size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math
|
||||
_cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding
|
||||
_lastShow = showNow;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1454,7 +1429,7 @@ bool WS2812FX::isUpdating() const {
|
||||
*/
|
||||
uint16_t WS2812FX::getFps() const {
|
||||
if (millis() - _lastShow > 2000) return 0;
|
||||
return _cumulativeFps +1;
|
||||
return (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; // _cumulativeFps is stored in fixed point
|
||||
}
|
||||
|
||||
void WS2812FX::setTargetFps(uint8_t fps) {
|
||||
|
@ -150,7 +150,7 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||
//_buffering = bc.doubleBuffer;
|
||||
uint16_t lenToCreate = bc.count;
|
||||
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz);
|
||||
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr);
|
||||
_valid = (_busPtr != nullptr);
|
||||
DEBUG_PRINTF_P(PSTR("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n"), _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], is2Pin(bc.type)?_pins[1]:255, _iType, _milliAmpsPerLed, _milliAmpsMax);
|
||||
}
|
||||
@ -410,9 +410,9 @@ std::vector<LEDType> BusDigital::getLEDTypes() {
|
||||
};
|
||||
}
|
||||
|
||||
void BusDigital::reinit() {
|
||||
void BusDigital::begin() {
|
||||
if (!_valid) return;
|
||||
PolyBus::begin(_busPtr, _iType, _pins);
|
||||
PolyBus::begin(_busPtr, _iType, _pins, _frequencykHz);
|
||||
}
|
||||
|
||||
void BusDigital::cleanup() {
|
||||
@ -910,7 +910,7 @@ void BusManager::on() {
|
||||
if (busses[i]->isDigital() && busses[i]->getPins(pins)) {
|
||||
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
|
||||
BusDigital *bus = static_cast<BusDigital*>(busses[i]);
|
||||
bus->reinit();
|
||||
bus->begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ class Bus {
|
||||
|
||||
virtual ~Bus() {} //throw the bus under the bus
|
||||
|
||||
virtual void begin() {};
|
||||
virtual void show() = 0;
|
||||
virtual bool canShow() const { return true; }
|
||||
virtual void setStatusPixel(uint32_t c) {}
|
||||
@ -213,7 +214,7 @@ class BusDigital : public Bus {
|
||||
uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; }
|
||||
uint16_t getUsedCurrent() const override { return _milliAmpsTotal; }
|
||||
uint16_t getMaxCurrent() const override { return _milliAmpsMax; }
|
||||
void reinit();
|
||||
void begin() override;
|
||||
void cleanup();
|
||||
|
||||
static std::vector<LEDType> getLEDTypes();
|
||||
|
@ -336,7 +336,7 @@ class PolyBus {
|
||||
|
||||
// initialize SPI bus speed for DotStar methods
|
||||
template <class T>
|
||||
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz = 0U) {
|
||||
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz /* 0 == use default */) {
|
||||
T dotStar_strip = static_cast<T>(busPtr);
|
||||
#ifdef ESP8266
|
||||
dotStar_strip->Begin();
|
||||
@ -363,7 +363,7 @@ class PolyBus {
|
||||
tm1914_strip->SetPixelSettings(NeoTm1914Settings()); //NeoTm1914_Mode_DinFdinAutoSwitch, NeoTm1914_Mode_DinOnly, NeoTm1914_Mode_FdinOnly
|
||||
}
|
||||
|
||||
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz = 0U) {
|
||||
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz /* only used by DotStar */) {
|
||||
switch (busType) {
|
||||
case I_NONE: break;
|
||||
#ifdef ESP8266
|
||||
@ -480,7 +480,7 @@ class PolyBus {
|
||||
}
|
||||
}
|
||||
|
||||
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) {
|
||||
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel) {
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
|
||||
// NOTE: "channel" is only used on ESP32 (and its variants) for RMT channel allocation
|
||||
// since 0.15.0-b3 I2S1 is favoured for classic ESP32 and moved to position 0 (channel 0) so we need to subtract 1 for correct RMT allocation
|
||||
@ -597,7 +597,7 @@ class PolyBus {
|
||||
case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break;
|
||||
case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[1], pins[0]); break;
|
||||
}
|
||||
begin(busPtr, busType, pins, clock_kHz);
|
||||
|
||||
return busPtr;
|
||||
}
|
||||
|
||||
|
@ -215,6 +215,7 @@ void handleAnalog(uint8_t b)
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
} else {
|
||||
if (bri == 0) strip.restartRuntime();
|
||||
bri = aRead;
|
||||
}
|
||||
} else if (macroDoublePress[b] == 249) {
|
||||
|
@ -53,7 +53,7 @@
|
||||
#else
|
||||
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, 6 LEDC, only has 1 I2S but NPB does not support it ATM
|
||||
#define WLED_MAX_BUSSES 4 // will allow 2 digital & 2 analog RGB
|
||||
#define WLED_MAX_BUSSES 6 // will allow 2 digital & 2 analog RGB or 6 PWM white
|
||||
#define WLED_MAX_DIGITAL_CHANNELS 2
|
||||
//#define WLED_MAX_ANALOG_CHANNELS 6
|
||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||
|
@ -144,7 +144,7 @@ button {
|
||||
}
|
||||
|
||||
.huge {
|
||||
font-size: 42px;
|
||||
font-size: 60px !important;
|
||||
}
|
||||
|
||||
.segt, .plentry TABLE {
|
||||
@ -584,6 +584,10 @@ button {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
#rover .ibtn {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#ndlt {
|
||||
margin: 12px 0;
|
||||
}
|
||||
@ -624,7 +628,7 @@ button {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.infobtn {
|
||||
#info .ibtn {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
@ -848,7 +852,7 @@ input[type=range]::-moz-range-thumb {
|
||||
width: 135px;
|
||||
}
|
||||
|
||||
#nodes .infobtn {
|
||||
#nodes .ibtn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -1036,7 +1040,7 @@ textarea {
|
||||
|
||||
.segname .flr, .pname .flr {
|
||||
transform: rotate(0deg);
|
||||
right: -6px;
|
||||
/*right: -6px;*/
|
||||
}
|
||||
|
||||
/* segment power wrapper */
|
||||
@ -1331,6 +1335,11 @@ TD .checkmark, TD .radiomark {
|
||||
box-shadow: 0 0 10px 4px var(--c-1);
|
||||
}
|
||||
|
||||
.lstI .flr:hover {
|
||||
background: var(--c-6);
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
#pcont .selected:not([class*="expanded"]) {
|
||||
bottom: 52px;
|
||||
top: 42px;
|
||||
@ -1524,7 +1533,7 @@ dialog {
|
||||
#info table .btn, #nodes table .btn {
|
||||
width: 200px;
|
||||
}
|
||||
#info .infobtn, #nodes .infobtn {
|
||||
#info .ibtn, #nodes .ibtn {
|
||||
width: 145px;
|
||||
}
|
||||
#info div, #nodes div, #nodes a.btn {
|
||||
|
@ -304,10 +304,10 @@
|
||||
</div>
|
||||
<div id="kv">Loading...</div><br>
|
||||
<div>
|
||||
<button class="btn infobtn" onclick="requestJson()">Refresh</button>
|
||||
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
||||
<button class="btn infobtn" onclick="window.open(getURL('/update'),'_self');">Update WLED</button>
|
||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
||||
<button class="btn ibtn" onclick="requestJson()">Refresh</button>
|
||||
<button class="btn ibtn" onclick="toggleNodes()">Instance List</button>
|
||||
<button class="btn ibtn" onclick="window.open(getURL('/update'),'_self');">Update WLED</button>
|
||||
<button class="btn ibtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
||||
</div>
|
||||
<br>
|
||||
<span class="h">Made with <span id="heart">❤︎</span> by <a href="https://github.com/Aircoookie/" target="_blank">Aircoookie</a> and the <a href="https://wled.discourse.group/" target="_blank">WLED community</a></span>
|
||||
@ -318,7 +318,7 @@
|
||||
<div id="ndlt">WLED instances</div>
|
||||
<div id="kn">Loading...</div>
|
||||
<div style="position:sticky;bottom:0;">
|
||||
<button class="btn infobtn" onclick="loadNodes()">Refresh</button>
|
||||
<button class="btn ibtn" onclick="loadNodes()">Refresh</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -331,8 +331,8 @@
|
||||
<div id="lv">?</div><br><br>
|
||||
To use built-in effects, use an override button below.<br>
|
||||
You can return to realtime mode by pressing the star in the top left corner.<br>
|
||||
<button class="btn" onclick="setLor(1)">Override once</button>
|
||||
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
||||
<button class="btn ibtn" onclick="setLor(1)">Override once</button>
|
||||
<button class="btn ibtn" onclick="setLor(2)">Override until reboot</button><br>
|
||||
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
||||
</div>
|
||||
|
||||
|
@ -2827,7 +2827,7 @@ function search(field, listId = null) {
|
||||
|
||||
// restore default preset sorting if no search term is entered
|
||||
if (!search) {
|
||||
if (listId === 'pcont') { populatePresets(); return; }
|
||||
if (listId === 'pcont') { populatePresets(); return; }
|
||||
if (listId === 'pallist') {
|
||||
let id = parseInt(d.querySelector('#pallist input[name="palette"]:checked').value); // preserve selected palette
|
||||
populatePalettes();
|
||||
@ -2846,12 +2846,16 @@ function search(field, listId = null) {
|
||||
|
||||
// filter list items but leave (Default & Solid) always visible
|
||||
const listItems = gId(listId).querySelectorAll('.lstI');
|
||||
listItems.forEach((listItem,i)=>{
|
||||
if (listId!=='pcont' && i===0) return;
|
||||
listItems.forEach((listItem, i) => {
|
||||
if (listId !== 'pcont' && i === 0) return;
|
||||
const listItemName = listItem.querySelector('.lstIname').innerText.toUpperCase();
|
||||
const searchIndex = listItemName.indexOf(field.value.toUpperCase());
|
||||
listItem.style.display = (searchIndex < 0) ? 'none' : '';
|
||||
listItem.dataset.searchIndex = searchIndex;
|
||||
if (searchIndex < 0) {
|
||||
listItem.dataset.searchIndex = Number.MAX_SAFE_INTEGER;
|
||||
} else {
|
||||
listItem.dataset.searchIndex = searchIndex;
|
||||
}
|
||||
listItem.style.display = (searchIndex < 0) && !listItem.classList.contains("selected") ? 'none' : '';
|
||||
});
|
||||
|
||||
// sort list items by search index and name
|
||||
@ -2920,11 +2924,11 @@ function filterFx() {
|
||||
inputField.value = '';
|
||||
inputField.focus();
|
||||
clean(inputField.nextElementSibling);
|
||||
gId("fxlist").querySelectorAll('.lstI').forEach((listItem,i) => {
|
||||
gId("fxlist").querySelectorAll('.lstI').forEach((listItem, i) => {
|
||||
const listItemName = listItem.querySelector('.lstIname').innerText;
|
||||
let hide = false;
|
||||
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { if (e.checked && !listItemName.includes(e.dataset.flt)) hide = i>0 /*true*/; });
|
||||
listItem.style.display = hide ? 'none' : '';
|
||||
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { if (e.checked && !listItemName.includes(e.dataset.flt)) hide = i > 0 /*true*/; });
|
||||
listItem.style.display = hide && !listItem.classList.contains("selected") ? 'none' : '';
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,15 +42,14 @@
|
||||
if (loc) d.Sf.action = getURL('/settings/leds');
|
||||
}
|
||||
function bLimits(b,v,p,m,l,o=5,d=2,a=6) {
|
||||
// maxB - max buses (can be changed if using ESP32 parallel I2S)
|
||||
// maxD - max digital channels (can be changed if using ESP32 parallel I2S)
|
||||
// maxA - max analog channels
|
||||
// maxV - min virtual buses
|
||||
// maxPB - max LEDs per bus
|
||||
// maxM - max LED memory
|
||||
// maxL - max LEDs (will serve to determine ESP >1664 == ESP32)
|
||||
// maxCO - max Color Order mappings
|
||||
oMaxB = maxB = b; maxD = d, maxA = a, maxV = v; maxM = m; maxPB = p; maxL = l; maxCO = o;
|
||||
oMaxB = maxB = b; // maxB - max buses (can be changed if using ESP32 parallel I2S)
|
||||
maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S)
|
||||
maxA = a; // maxA - max analog channels
|
||||
maxV = v; // maxV - min virtual buses
|
||||
maxPB = p; // maxPB - max LEDs per bus
|
||||
maxM = m; // maxM - max LED memory
|
||||
maxL = l; // maxL - max LEDs (will serve to determine ESP >1664 == ESP32)
|
||||
maxCO = o; // maxCO - max Color Order mappings
|
||||
}
|
||||
function pinsOK() {
|
||||
var ok = true;
|
||||
@ -119,7 +118,12 @@
|
||||
var en = d.Sf.ABL.checked;
|
||||
gId('abl').style.display = (en) ? 'inline':'none';
|
||||
gId('psu2').style.display = (en) ? 'inline':'none';
|
||||
if (!en) d.Sf.PPL.checked = false;
|
||||
if (!en) {
|
||||
// limiter disabled
|
||||
d.Sf.PPL.checked = false;
|
||||
// d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((e)=>{e.selectedIndex = 0;}); // select default LED mA
|
||||
// d.Sf.querySelectorAll("#mLC input[name^=LA]").forEach((e)=>{e.min = 0; e.value = 0;}); // set min & value to 0
|
||||
}
|
||||
UI();
|
||||
}
|
||||
// enable per port limiter and calculate current
|
||||
@ -132,46 +136,51 @@
|
||||
d.Sf.MA.min = abl && !ppl ? 250 : 0;
|
||||
gId("psuMA").style.display = ppl ? 'none' : 'inline';
|
||||
gId("ppldis").style.display = ppl ? 'inline' : 'none';
|
||||
// set PPL minimum value and clear actual PPL limit if ABL disabled
|
||||
// set PPL minimum value and clear actual PPL limit if ABL is disabled
|
||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,x)=>{
|
||||
var n = String.fromCharCode((x<10?48:55)+x);
|
||||
gId("PSU"+n).style.display = ppl ? "inline" : "none";
|
||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||
const c = parseInt(d.Sf["LC"+n].value); //get LED count
|
||||
i.min = ppl && !(isVir(t) || isAna(t)) ? 250 : 0;
|
||||
if (!abl || isVir(t) || isAna(t)) i.value = 0;
|
||||
i.min = ppl && isDig(t) ? 250 : 0;
|
||||
if (!abl || !isDig(t)) i.value = 0;
|
||||
else if (ppl) sumMA += parseInt(i.value,10);
|
||||
else if (sDI) i.value = Math.round(parseInt(d.Sf.MA.value,10)*c/sDI);
|
||||
});
|
||||
if (ppl) d.Sf.MA.value = sumMA; // populate UI ABL value if PPL used
|
||||
}
|
||||
// enable and update LED Amps
|
||||
function enLA(s,n)
|
||||
{
|
||||
const abl = d.Sf.ABL.checked;
|
||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none";
|
||||
if (s.value!=="0") d.Sf["LA"+n].value = s.value;
|
||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
||||
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none"; // show/hide custom mA field
|
||||
if (s.value!=="0") d.Sf["LA"+n].value = s.value; // set value from select object
|
||||
d.Sf["LA"+n].min = (!isDig(t) || !abl) ? 0 : 1; // set minimum value for validation
|
||||
}
|
||||
function setABL()
|
||||
{
|
||||
d.Sf.ABL.checked = parseInt(d.Sf.MA.value) > 0;
|
||||
let en = parseInt(d.Sf.MA.value) > 0;
|
||||
// check if ABL is enabled (max mA entered per output)
|
||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,n)=>{
|
||||
if (parseInt(i.value) > 0) d.Sf.ABL.checked = true;
|
||||
if (parseInt(i.value) > 0) en = true;
|
||||
});
|
||||
d.Sf.ABL.checked = en;
|
||||
// select appropriate LED current
|
||||
d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((sel,x)=>{
|
||||
sel.value = 0; // set custom
|
||||
var n = String.fromCharCode((x<10?48:55)+x);
|
||||
switch (parseInt(d.Sf["LA"+n].value)) {
|
||||
case 0: break; // disable ABL
|
||||
case 15: sel.value = 15; break;
|
||||
case 30: sel.value = 30; break;
|
||||
case 35: sel.value = 35; break;
|
||||
case 55: sel.value = 55; break;
|
||||
case 255: sel.value = 255; break;
|
||||
}
|
||||
enLA(sel,n);
|
||||
if (en)
|
||||
switch (parseInt(d.Sf["LA"+n].value)) {
|
||||
case 0: break; // disable ABL
|
||||
case 15: sel.value = 15; break;
|
||||
case 30: sel.value = 30; break;
|
||||
case 35: sel.value = 35; break;
|
||||
case 55: sel.value = 55; break;
|
||||
case 255: sel.value = 255; break;
|
||||
}
|
||||
else sel.value = 0;
|
||||
enLA(sel,n); // configure individual limiter
|
||||
});
|
||||
enABL();
|
||||
gId('m1').innerHTML = maxM;
|
||||
@ -202,7 +211,7 @@
|
||||
let gRGBW = false, memu = 0;
|
||||
let busMA = 0;
|
||||
let sLC = 0, sPC = 0, sDI = 0, maxLC = 0;
|
||||
const ablEN = d.Sf.ABL.checked;
|
||||
const abl = d.Sf.ABL.checked;
|
||||
maxB = oMaxB; // TODO make sure we start with all possible buses
|
||||
let setPinConfig = (n,t) => {
|
||||
let p0d = "GPIO:";
|
||||
@ -249,12 +258,12 @@
|
||||
var t = parseInt(s.value);
|
||||
memu += getMem(t, n); // calc memory
|
||||
setPinConfig(n,t);
|
||||
gId("abl"+n).style.display = (!ablEN || isVir(t) || isAna(t)) ? "none" : "inline";
|
||||
if (change) {
|
||||
gId("abl"+n).style.display = (!abl || !isDig(t)) ? "none" : "inline"; // show/hide individual ABL settings
|
||||
if (change) { // did we change LED type?
|
||||
gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state (mandatory for TM1814)
|
||||
if (isAna(t)) d.Sf["LC"+n].value = 1; // for sanity change analog count just to 1 LED
|
||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
||||
d.Sf["MA"+n].min = (isVir(t) || isAna(t)) ? 0 : 250;
|
||||
d.Sf["LA"+n].min = (!isDig(t) || !abl) ? 0 : 1; // set minimum value for LED mA
|
||||
d.Sf["MA"+n].min = (!isDig(t)) ? 0 : 250; // set minimum value for PSU mA
|
||||
}
|
||||
gId("rf"+n).onclick = mustR(t) ? (()=>{return false}) : (()=>{}); // prevent change change of "Refresh" checkmark when mandatory
|
||||
gRGBW |= hasW(t); // RGBW checkbox
|
||||
@ -294,7 +303,7 @@
|
||||
if (s+c > sLC) sLC = s+c; //update total count
|
||||
if (c > maxLC) maxLC = c; //max per output
|
||||
if (!isVir(t)) sPC += c; //virtual out busses do not count towards physical LEDs
|
||||
if (!(isVir(t) || isAna(t))) {
|
||||
if (isDig(t)) {
|
||||
sDI += c; // summarize digital LED count
|
||||
let maPL = parseInt(d.Sf["LA"+n].value);
|
||||
if (maPL == 255) maPL = 12;
|
||||
|
@ -72,7 +72,7 @@
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||
(c) 2016-2024 Christian Schwinne <br>
|
||||
<i>Licensed under the <a href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">MIT license</a></i><br><br>
|
||||
<i>Licensed under the <a href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">EUPL v1.2 license</a></i><br><br>
|
||||
Server message: <span class="sip"> Response error! </span><hr>
|
||||
<div id="toast"></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
|
@ -156,6 +156,7 @@
|
||||
<option value="20">AKST/AKDT (Anchorage)</option>
|
||||
<option value="21">MX-CST</option>
|
||||
<option value="22">PKT (Pakistan)</option>
|
||||
<option value="23">BRT (Brasília)</option>
|
||||
</select><br>
|
||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||
Current local time is <span class="times">unknown</span>.<br>
|
||||
|
@ -17,7 +17,8 @@
|
||||
<h2>WLED Software Update</h2>
|
||||
<form method='POST' action='./update' id='uf' enctype='multipart/form-data' onsubmit="U()">
|
||||
Installed version: <span class="sip">##VERSION##</span><br>
|
||||
Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases" target="_blank">
|
||||
Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases" target="_blank"
|
||||
style="vertical-align: text-bottom; display: inline-flex;">
|
||||
<img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br>
|
||||
<input type='file' name='update' required><br> <!--should have accept='.bin', but it prevents file upload from android app-->
|
||||
<button type="submit">Update!</button><br>
|
||||
|
@ -169,7 +169,6 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
||||
void setValuesFromSegment(uint8_t s);
|
||||
void setValuesFromMainSeg();
|
||||
void setValuesFromFirstSelectedSeg();
|
||||
void resetTimebase();
|
||||
void toggleOnOff();
|
||||
void applyBri();
|
||||
void applyFinalBri();
|
||||
@ -324,6 +323,10 @@ class Usermod {
|
||||
protected:
|
||||
// Shim for oappend(), which used to exist in utils.cpp
|
||||
template<typename T> static inline void oappend(const T& t) { oappend_shim->print(t); };
|
||||
#ifdef ESP8266
|
||||
// Handle print(PSTR()) without crashing by detecting PROGMEM strings
|
||||
static void oappend(const char* c) { if ((intptr_t) c >= 0x40000000) oappend_shim->print(FPSTR(c)); else oappend_shim->print(c); };
|
||||
#endif
|
||||
};
|
||||
|
||||
class UsermodManager {
|
||||
|
@ -194,24 +194,22 @@ void sendImprovIPRPCResult(ImprovRPCType type) {
|
||||
}
|
||||
|
||||
void sendImprovInfoResponse() {
|
||||
const char* bString =
|
||||
#ifdef ESP8266
|
||||
"esp8266"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
"esp32-c3"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
"esp32-s2"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
"esp32-s3";
|
||||
#else // ESP32
|
||||
"esp32";
|
||||
#endif
|
||||
;
|
||||
|
||||
char bString[32];
|
||||
#ifdef ESP8266
|
||||
strcpy(bString, "esp8266");
|
||||
#else // ESP32
|
||||
strncpy(bString, ESP.getChipModel(), 31);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
bString[5] = '\0'; // disregard chip revision for classic ESP32
|
||||
#else
|
||||
bString[31] = '\0'; // just in case
|
||||
#endif
|
||||
strlwr(bString);
|
||||
#endif
|
||||
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||
char vString[20];
|
||||
sprintf_P(vString, PSTR("0.15.0-b5/%i"), VERSION);
|
||||
char vString[32];
|
||||
sprintf_P(vString, PSTR("%s/%i"), versionString, VERSION);
|
||||
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
||||
|
||||
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
||||
|
@ -346,7 +346,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
int tr = -1;
|
||||
long tr = -1;
|
||||
if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times
|
||||
tr = root[F("transition")] | -1;
|
||||
if (tr >= 0) {
|
||||
@ -363,7 +363,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
|
||||
tr = root[F("tb")] | -1;
|
||||
if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis();
|
||||
if (tr >= 0) strip.timebase = (unsigned long)tr - millis();
|
||||
|
||||
JsonObject nl = root["nl"];
|
||||
nightlightActive = getBoolVal(nl["on"], nightlightActive);
|
||||
@ -454,21 +454,25 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
handleSet(nullptr, apireq, false); // may set stateChanged
|
||||
}
|
||||
|
||||
// applying preset (2 cases: a) API call includes all preset values ("pd"), b) API only specifies preset ID ("ps"))
|
||||
// Applying preset from JSON API has 2 cases: a) "pd" AKA "preset direct" and b) "ps" AKA "preset select"
|
||||
// a) "preset direct" can only be an integer value representing preset ID. "preset direct" assumes JSON API contains the rest of preset content (i.e. from UI call)
|
||||
// "preset direct" JSON can contain "ps" API (i.e. call from UI to cycle presets) in such case stateChanged has to be false (i.e. no "win" or "seg" API)
|
||||
// b) "preset select" can be cycling ("1~5~""), random ("r" or "1~5r"), ID, etc. value allowed from JSON API. This type of call assumes no state changing content in API call
|
||||
byte presetToRestore = 0;
|
||||
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
||||
if (!root[F("pd")].isNull() && stateChanged) {
|
||||
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
||||
currentPreset = root[F("pd")] | currentPreset;
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise it was set in handleSet() [set.cpp]
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise presetCycCurr was set in handleSet() [set.cpp]
|
||||
presetToRestore = currentPreset; // stateUpdated() will clear the preset, so we need to restore it after
|
||||
DEBUG_PRINTF_P(PSTR("Preset direct: %d\n"), currentPreset);
|
||||
} else if (!root["ps"].isNull()) {
|
||||
ps = presetCycCurr;
|
||||
if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
|
||||
// we have "ps" call (i.e. from button or external API call) or "pd" that includes "ps" (i.e. from UI call)
|
||||
if (root["win"].isNull() && getVal(root["ps"], &presetCycCurr, 0, 0) && 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())
|
||||
presetCycCurr = ps;
|
||||
applyPreset(ps, callMode); // async load from file system (only preset ID was specified)
|
||||
applyPreset(presetCycCurr, callMode); // async load from file system (only preset ID was specified)
|
||||
return stateResponse;
|
||||
}
|
||||
} else presetCycCurr = currentPreset; // restore presetCycCurr
|
||||
}
|
||||
|
||||
JsonObject playlist = root[F("playlist")];
|
||||
|
@ -47,17 +47,12 @@ void applyValuesToSelectedSegs()
|
||||
}
|
||||
|
||||
|
||||
void resetTimebase()
|
||||
{
|
||||
strip.timebase = 0 - millis();
|
||||
}
|
||||
|
||||
|
||||
void toggleOnOff()
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = briLast;
|
||||
strip.restartRuntime();
|
||||
} else
|
||||
{
|
||||
briLast = bri;
|
||||
@ -122,7 +117,7 @@ void stateUpdated(byte callMode) {
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
if (briT == 0) {
|
||||
if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
|
||||
if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning
|
||||
}
|
||||
|
||||
if (bri > 0) briLast = bri;
|
||||
|
@ -36,8 +36,9 @@ Timezone* tz;
|
||||
#define TZ_ANCHORAGE 20
|
||||
#define TZ_MX_CENTRAL 21
|
||||
#define TZ_PAKISTAN 22
|
||||
#define TZ_BRASILIA 23
|
||||
|
||||
#define TZ_COUNT 23
|
||||
#define TZ_COUNT 24
|
||||
#define TZ_INIT 255
|
||||
|
||||
byte tzCurrent = TZ_INIT; //uninitialized
|
||||
@ -135,6 +136,10 @@ static const std::pair<TimeChangeRule, TimeChangeRule> TZ_TABLE[] PROGMEM = {
|
||||
/* TZ_PAKISTAN */ {
|
||||
{Last, Sun, Mar, 1, 300}, //Pakistan Standard Time = UTC + 5 hours
|
||||
{Last, Sun, Mar, 1, 300}
|
||||
},
|
||||
/* TZ_BRASILIA */ {
|
||||
{Last, Sun, Mar, 1, -180}, //Brasília Standard Time = UTC - 3 hours
|
||||
{Last, Sun, Mar, 1, -180}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -201,7 +201,12 @@ bool PinManager::isPinOk(byte gpio, bool output)
|
||||
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
|
||||
#endif
|
||||
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
|
||||
if (gpio > 32 && gpio < 38) return !psramFound(); // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM
|
||||
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI // 33-37: never available if using _octal_ Flash (opi_opi)
|
||||
if (gpio > 32 && gpio < 38) return false;
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_MODE_OCT // 33-37: not available if using _octal_ PSRAM (qio_opi), but free to use on _quad_ PSRAM (qio_qspi)
|
||||
if (gpio > 32 && gpio < 38) return !psramFound();
|
||||
#endif
|
||||
// 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board.
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
// strapping pins: 0, 45 & 46
|
||||
|
@ -143,6 +143,7 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID,
|
||||
|
||||
void handlePresets()
|
||||
{
|
||||
byte presetErrFlag = ERR_NONE;
|
||||
if (presetToSave) {
|
||||
strip.suspend();
|
||||
doSaveState();
|
||||
@ -166,14 +167,16 @@ void handlePresets()
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
||||
deserializeJson(*pDoc,tmpRAMbuffer);
|
||||
errorFlag = ERR_NONE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||
presetErrFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||
}
|
||||
fdo = pDoc->as<JsonObject>();
|
||||
|
||||
// only reset errorflag if previous error was preset-related
|
||||
if ((errorFlag == ERR_NONE) || (errorFlag == ERR_FS_PLOAD)) errorFlag = presetErrFlag;
|
||||
|
||||
//HTTP API commands
|
||||
const char* httpwin = fdo["win"];
|
||||
if (httpwin) {
|
||||
|
@ -215,6 +215,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
||||
|
||||
// we will not bother with pre-allocating ColorOrderMappings vector
|
||||
BusManager::getColorOrderMap().reset();
|
||||
for (int s = 0; s < WLED_MAX_COLOR_ORDER_MAPPINGS; s++) {
|
||||
int offset = s < 10 ? 48 : 55;
|
||||
char xs[4] = "XS"; xs[2] = offset+s; xs[3] = 0; //start LED
|
||||
@ -1191,7 +1192,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
|
||||
// internal call, does not send XML response
|
||||
pos = req.indexOf(F("IN"));
|
||||
if (pos < 1) {
|
||||
if ((request != nullptr) && (pos < 1)) {
|
||||
auto response = request->beginResponseStream("text/xml");
|
||||
XML_response(*response);
|
||||
request->send(response);
|
||||
|
@ -34,8 +34,8 @@ static const int enablePin = -1; // disable the enable pin because it is not ne
|
||||
static const int rxPin = -1; // disable the receiving pin because it is not needed - softhack007: Pin=-1 means "use default" not "disable"
|
||||
static const int txPin = 2; // transmit DMX data over this pin (default is pin 2)
|
||||
|
||||
//DMX value array and size. Entry 0 will hold startbyte
|
||||
static uint8_t dmxData[dmxMaxChannel] = { 0 };
|
||||
//DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
|
||||
static uint8_t dmxData[dmxMaxChannel+1] = { 0 };
|
||||
static int chanSize = 0;
|
||||
#if !defined(DMX_SEND_ONLY)
|
||||
static int currentChannel = 0;
|
||||
|
@ -120,10 +120,8 @@ private:
|
||||
|
||||
void encodeLightId(uint8_t idx, char* out)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
|
||||
sprintf_P(out, PSTR("%02X:%02X:%02X:%02X:%02X:%02X:00:11-%02X"), mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], idx);
|
||||
String mymac = WiFi.macAddress();
|
||||
sprintf_P(out, PSTR("%02X:%s:AB-%02X"), idx, mymac.c_str(), idx);
|
||||
}
|
||||
|
||||
// construct 'globally unique' Json dict key fitting into signed int
|
||||
|
@ -380,6 +380,12 @@ void WLED::setup()
|
||||
case FM_QOUT: DEBUG_PRINT(F("(QOUT)"));break;
|
||||
case FM_DIO: DEBUG_PRINT(F("(DIO)")); break;
|
||||
case FM_DOUT: DEBUG_PRINT(F("(DOUT)"));break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) && CONFIG_ESPTOOLPY_FLASHMODE_OPI
|
||||
case FM_FAST_READ: DEBUG_PRINT(F("(OPI)")); break;
|
||||
#else
|
||||
case FM_FAST_READ: DEBUG_PRINT(F("(fast_read)")); break;
|
||||
#endif
|
||||
case FM_SLOW_READ: DEBUG_PRINT(F("(slow_read)")); break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
|
@ -3,12 +3,12 @@
|
||||
/*
|
||||
Main sketch, global variable declarations
|
||||
@title WLED project sketch
|
||||
@version 0.15.0-b5
|
||||
@version 0.15.0-b7
|
||||
@author Christian Schwinne
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2409170
|
||||
#define VERSION 2410270
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -36,12 +36,13 @@
|
||||
#undef WLED_ENABLE_ADALIGHT // disable has priority over enable
|
||||
#endif
|
||||
//#define WLED_ENABLE_DMX // uses 3.5kb
|
||||
//#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled)
|
||||
#ifndef WLED_DISABLE_LOXONE
|
||||
#define WLED_ENABLE_LOXONE // uses 1.2kb
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_WEBSOCKETS
|
||||
#define WLED_ENABLE_WEBSOCKETS
|
||||
#else
|
||||
#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled)
|
||||
#endif
|
||||
|
||||
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
||||
@ -263,12 +264,12 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument<PSRAM_Allocator>;
|
||||
#define WLED_VERSION dev
|
||||
#endif
|
||||
#ifndef WLED_RELEASE_NAME
|
||||
#define WLED_RELEASE_NAME dev_release
|
||||
#define WLED_RELEASE_NAME "Custom"
|
||||
#endif
|
||||
|
||||
// Global Variable definitions
|
||||
WLED_GLOBAL char versionString[] _INIT(TOSTRING(WLED_VERSION));
|
||||
WLED_GLOBAL char releaseString[] _INIT(TOSTRING(WLED_RELEASE_NAME)); // somehow this will not work if using "const char releaseString[]
|
||||
WLED_GLOBAL char releaseString[] _INIT(WLED_RELEASE_NAME); // must include the quotes when defining, e.g -D WLED_RELEASE_NAME=\"ESP32_MULTI_USREMODS\"
|
||||
#define WLED_CODENAME "Kōsen"
|
||||
|
||||
// AP and OTA default passwords (for maximum security change them!)
|
||||
@ -316,8 +317,6 @@ WLED_GLOBAL bool rlyOpenDrain _INIT(RLYODRAIN);
|
||||
constexpr uint8_t hardwareTX = 1;
|
||||
#endif
|
||||
|
||||
//WLED_GLOBAL byte presetToApply _INIT(0);
|
||||
|
||||
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
|
||||
|
||||
// WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
||||
|
@ -193,12 +193,12 @@ void createEditHandler(bool enable) {
|
||||
editHandler = &server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
|
||||
#endif
|
||||
#else
|
||||
editHandler = &server.on(SET_F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
editHandler = &server.on(F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 501, FPSTR(s_notimplemented), F("The FS editor is disabled in this build."), 254);
|
||||
});
|
||||
#endif
|
||||
} else {
|
||||
editHandler = &server.on(SET_F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
editHandler = &server.on(F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_cfg), 254);
|
||||
});
|
||||
}
|
||||
@ -427,11 +427,11 @@ void initServer()
|
||||
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send_P(200, FPSTR(CONTENT_TYPE_HTML), PAGE_dmxmap , dmxProcessor);
|
||||
});
|
||||
#else
|
||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 501, FPSTR(s_notimplemented), F("DMX support is not enabled in this build."), 254);
|
||||
});
|
||||
#endif
|
||||
|
@ -172,7 +172,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
settingsScript.printf_P(PSTR("addWiFi(\"%s\",\",%s\",0x%X,0x%X,0x%X);"),
|
||||
settingsScript.printf_P(PSTR("addWiFi(\"%s\",\"%s\",0x%X,0x%X,0x%X);"),
|
||||
multiWiFi[n].clientSSID,
|
||||
fpass,
|
||||
(uint32_t) multiWiFi[n].staticIP, // explicit cast required as this is a struct
|
||||
@ -227,7 +227,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||
if (Network.isEthernet()) strcat_P(s ,SET_F(" (Ethernet)"));
|
||||
if (Network.isEthernet()) strcat_P(s ,PSTR(" (Ethernet)"));
|
||||
#endif
|
||||
printSetClassElementHTML(settingsScript,PSTR("sip"),0,s);
|
||||
} else
|
||||
@ -465,7 +465,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
printSetFormValue(settingsScript,PSTR("MG"),mqttGroupTopic);
|
||||
printSetFormCheckbox(settingsScript,PSTR("BM"),buttonPublishMqtt);
|
||||
printSetFormCheckbox(settingsScript,PSTR("RT"),retainMqttMsg);
|
||||
settingsScript.printf_P(PSTR("d.Sf.MD.maxlength=%d;d.Sf.MG.maxlength=%d;d.Sf.MS.maxlength=%d;"),
|
||||
settingsScript.printf_P(PSTR("d.Sf.MD.maxLength=%d;d.Sf.MG.maxLength=%d;d.Sf.MS.maxLength=%d;"),
|
||||
MQTT_MAX_TOPIC_LEN, MQTT_MAX_TOPIC_LEN, MQTT_MAX_SERVER_LEN);
|
||||
#else
|
||||
settingsScript.print(F("toggle('MQTT');")); // hide MQTT settings
|
||||
@ -501,7 +501,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
#endif
|
||||
printSetFormValue(settingsScript,PSTR("BD"),serialBaud);
|
||||
#ifndef WLED_ENABLE_ADALIGHT
|
||||
settingsScript.print(F("toggle('Serial);"));
|
||||
settingsScript.print(F("toggle('Serial');"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user