mirror of
https://github.com/wled/WLED.git
synced 2025-04-23 14:27:18 +00:00
Merge branch '0_15' into 0_15__speed_improvements
This commit is contained in:
commit
5c2bac4b9d
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": {
|
||||
|
@ -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
|
||||
@ -259,7 +260,8 @@ lib_deps =
|
||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||
${env.lib_deps}
|
||||
# additional build flags for audioreactive
|
||||
AR_build_flags = -D USERMOD_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]
|
||||
@ -430,7 +432,26 @@ lib_deps = ${esp32_idf_V4.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.partitions = ${esp32.large_partitions}
|
||||
board_upload.flash_size = 8MB
|
||||
board_upload.maximum_size = 8388608
|
||||
; board_build.f_flash = 80000000L
|
||||
; board_build.flash_mode = qio
|
||||
|
||||
[env:esp32dev_16M]
|
||||
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
|
||||
${esp32.AR_build_flags}
|
||||
lib_deps = ${esp32_idf_V4.lib_deps}
|
||||
${esp32.AR_lib_deps}
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.partitions = ${esp32.extreme_partitions}
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.maximum_size = 16777216
|
||||
board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = dio
|
||||
|
||||
;[env:esp32dev_audioreactive]
|
||||
;board = esp32dev
|
||||
@ -508,6 +529,8 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
|
||||
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
|
||||
board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = qio
|
||||
monitor_filters = esp32_exception_decoder
|
||||
@ -533,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
|
||||
|
@ -359,6 +359,8 @@ upload_speed = 115200
|
||||
lib_deps = ${esp32c3.lib_deps}
|
||||
board_build.partitions = tools/WLED_ESP32_2MB_noOTA.csv
|
||||
board_build.flash_mode = dio
|
||||
board_upload.flash_size = 2MB
|
||||
board_upload.maximum_size = 2097152
|
||||
|
||||
[env:wemos_shield_esp32]
|
||||
board = esp32dev
|
||||
|
@ -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 [ {
|
||||
//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
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');"));
|
||||
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
|
||||
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);
|
||||
|
@ -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');"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
*/
|
||||
@ -2516,9 +2502,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
|
||||
}
|
||||
@ -4027,7 +4013,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;
|
||||
@ -4042,7 +4028,7 @@ uint16_t mode_pacifica()
|
||||
sCIStart3 -= (deltams1 * beatsin88(501,5,7));
|
||||
sCIStart4 -= (deltams2 * beatsin88(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);
|
||||
@ -4920,8 +4906,8 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
|
||||
SEGMENT.fadeToBlackBy(40);
|
||||
for (size_t i = 0; i < numLines; i++) {
|
||||
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
|
||||
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1));
|
||||
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 24);
|
||||
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (rows - 1));
|
||||
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24);
|
||||
byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
|
||||
uint32_t color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
|
||||
|
||||
@ -4999,9 +4985,11 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
|
||||
// draw a gradient line between x and x1
|
||||
x = x / 2; x1 = x1 / 2;
|
||||
unsigned steps = abs8(x - x1) + 1;
|
||||
bool positive = (x1 >= x); // direction of drawing
|
||||
for (size_t k = 1; k <= steps; k++) {
|
||||
unsigned rate = k * 255 / steps;
|
||||
unsigned dx = lerp8by8(x, x1, rate);
|
||||
//unsigned dx = lerp8by8(x, x1, rate);
|
||||
unsigned dx = positive? (x + k-1) : (x - k+1); // behaves the same as "lerp8by8" but does not create holes
|
||||
//SEGMENT.setPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND).nscale8_video(rate));
|
||||
SEGMENT.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND)); // use setPixelColorXY for different look
|
||||
SEGMENT.fadePixelColorXY(dx, i, rate);
|
||||
@ -7516,8 +7504,9 @@ uint16_t mode_2DAkemi(void) {
|
||||
|
||||
//add geq left and right
|
||||
if (um_data && fftResult) {
|
||||
for (int x=0; x < cols/8; x++) {
|
||||
unsigned band = x * cols/8;
|
||||
int xMax = cols/8;
|
||||
for (int x=0; x < xMax; x++) {
|
||||
unsigned band = map(x, 0, max(xMax,4), 0, 15); // map 0..cols/8 to 16 GEQ bands
|
||||
band = constrain(band, 0, 15);
|
||||
int barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32);
|
||||
uint32_t color = SEGMENT.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0);
|
||||
@ -7734,7 +7723,7 @@ uint16_t mode_2Doctopus() {
|
||||
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
|
||||
for (int x = 0; x < cols; x++) {
|
||||
for (int y = 0; y < rows; y++) {
|
||||
rMap[XY(x, y)].angle = 40.7436f * atan2f((y - C_Y), (x - C_X)); // avoid 128*atan2()/PI
|
||||
rMap[XY(x, y)].angle = int(40.7436f * atan2f((y - C_Y), (x - C_X))); // avoid 128*atan2()/PI
|
||||
rMap[XY(x, y)].radius = hypotf((x - C_X), (y - C_Y)) * mapp; //thanks Sutaburosu
|
||||
}
|
||||
}
|
||||
|
68
wled00/FX.h
68
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
|
||||
*/
|
||||
@ -65,6 +51,15 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
|
||||
#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
|
||||
@ -556,12 +551,12 @@ typedef struct Segment {
|
||||
|
||||
void beginDraw(); // set up parameters for current effect
|
||||
void setGeometry(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, uint8_t m12=0);
|
||||
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(const Segment& b) const;
|
||||
void refreshLightCapabilities();
|
||||
|
||||
@ -576,7 +571,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
|
||||
@ -627,9 +622,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
|
||||
@ -731,7 +732,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),
|
||||
// true private variables
|
||||
@ -741,7 +746,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),
|
||||
@ -793,7 +798,8 @@ class WS2812FX { // 96 bytes
|
||||
setTargetFps(unsigned 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 setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
|
||||
@ -841,7 +847,7 @@ class WS2812FX { // 96 bytes
|
||||
getLengthPhysical() const,
|
||||
getLengthTotal() const; // will include virtual/nonexistent pixels in matrix
|
||||
|
||||
inline uint16_t getFps() const { return (millis() - _lastShow > 2000) ? 0 : _cumulativeFps +1; } // Returns the refresh rate of the LED strip
|
||||
inline uint16_t getFps() const { return (millis() - _lastShow > 2000) ? 0 : (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; } // Returns the refresh rate of the LED strip (_cumulativeFps is stored in fixed point)
|
||||
inline uint16_t getFrameTime() const { return _frametime; } // returns amount of time a frame should take (in ms)
|
||||
inline uint16_t getMinShowDelay() const { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
|
||||
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
@ -851,7 +857,7 @@ class WS2812FX { // 96 bytes
|
||||
return index;
|
||||
};
|
||||
|
||||
uint32_t now, timebase;
|
||||
unsigned long now, timebase;
|
||||
uint32_t getPixelColor(unsigned) const;
|
||||
|
||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
|
@ -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
|
||||
*/
|
||||
@ -273,8 +258,8 @@ 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
|
||||
int vW = vWidth();
|
||||
int vH = vHeight();
|
||||
const int vW = vWidth();
|
||||
const int vH = vHeight();
|
||||
if (unsigned(x) >= unsigned(vW) || unsigned(y) >= unsigned(vH)) return 0; // if pixel would fall out of virtual segment just exit
|
||||
if (reverse ) x = vW - x - 1;
|
||||
if (reverse_y) y = vH - y - 1;
|
||||
@ -684,11 +669,14 @@ void Segment::wu_pixel(uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel
|
||||
WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)};
|
||||
// multiply the intensities by the colour, and saturating-add them to the pixels
|
||||
for (int i = 0; i < 4; i++) {
|
||||
CRGB led = getPixelColorXY((x >> 8) + (i & 1), (y >> 8) + ((i >> 1) & 1));
|
||||
int wu_x = (x >> 8) + (i & 1); // precalculate x
|
||||
int wu_y = (y >> 8) + ((i >> 1) & 1); // precalculate y
|
||||
CRGB led = getPixelColorXY(wu_x, wu_y);
|
||||
CRGB oldLed = led;
|
||||
led.r = qadd8(led.r, c.r * wu[i] >> 8);
|
||||
led.g = qadd8(led.g, c.g * wu[i] >> 8);
|
||||
led.b = qadd8(led.b, c.b * wu[i] >> 8);
|
||||
setPixelColorXY(int((x >> 8) + (i & 1)), int((y >> 8) + ((i >> 1) & 1)), led);
|
||||
if (led != oldLed) setPixelColorXY(wu_x, wu_y, led); // don't repaint if same color
|
||||
}
|
||||
}
|
||||
#undef WU_WEIGHT
|
||||
|
@ -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
|
||||
*/
|
||||
@ -554,46 +540,53 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@ -625,9 +618,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) {
|
||||
@ -635,31 +629,24 @@ void Segment::setPalette(uint8_t pal) {
|
||||
palette = pal;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
uint16_t Segment::virtualWidth() const {
|
||||
unsigned 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 Segment::virtualHeight() const {
|
||||
unsigned 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 Segment::nrOfVStrips() const {
|
||||
unsigned vLen = 1;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D() && map1D2D == M12_pBar) vLen = virtualWidth();
|
||||
#endif
|
||||
return vLen;
|
||||
}
|
||||
|
||||
// Constants for mapping mode "Pinwheel"
|
||||
#ifndef WLED_DISABLE_2D
|
||||
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
|
||||
@ -1241,10 +1228,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
|
||||
@ -1391,7 +1375,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)
|
||||
@ -1407,7 +1391,7 @@ void WS2812FX::service() {
|
||||
// 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
|
||||
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||
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;
|
||||
@ -1416,16 +1400,16 @@ void WS2812FX::service() {
|
||||
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||
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++;
|
||||
}
|
||||
@ -1469,10 +1453,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;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setTargetFps(unsigned fps) {
|
||||
|
@ -766,47 +766,47 @@ class PolyBus {
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// RMT buses
|
||||
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_UCS_3: (static_cast<B_32_RN_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_FW6_5: (static_cast<B_32_RN_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_2805_5: (static_cast<B_32_RN_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM1914_3: (static_cast<B_32_RN_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_SM16825_5: (static_cast<B_32_RN_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_NEO_3: return (static_cast<B_32_RN_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_NEO_4: return (static_cast<B_32_RN_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_400_3: return (static_cast<B_32_RN_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM1_4: return (static_cast<B_32_RN_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM2_3: return (static_cast<B_32_RN_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_UCS_3: return (static_cast<B_32_RN_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_UCS_4: return (static_cast<B_32_RN_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_APA106_3: return (static_cast<B_32_RN_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_FW6_5: return (static_cast<B_32_RN_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_2805_5: return (static_cast<B_32_RN_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_TM1914_3: return (static_cast<B_32_RN_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_RN_SM16825_5: return (static_cast<B_32_RN_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
// I2S1 bus or paralell buses
|
||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) (static_cast<B_32_I1_NEO_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) (static_cast<B_32_I1_NEO_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) (static_cast<B_32_I1_400_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) (static_cast<B_32_I1_TM1_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) (static_cast<B_32_I1_TM2_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) (static_cast<B_32_I1_UCS_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) (static_cast<B_32_I1_UCS_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) (static_cast<B_32_I1_APA106_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) (static_cast<B_32_I1_FW6_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) (static_cast<B_32_I1_2805_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) (static_cast<B_32_I1_TM1914_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_NEO_3: if (useParallelI2S) return (static_cast<B_32_I1_NEO_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_NEO_4: if (useParallelI2S) return (static_cast<B_32_I1_NEO_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_400_3: if (useParallelI2S) return (static_cast<B_32_I1_400_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1_4: if (useParallelI2S) return (static_cast<B_32_I1_TM1_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM2_3: if (useParallelI2S) return (static_cast<B_32_I1_TM2_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_3: if (useParallelI2S) return (static_cast<B_32_I1_UCS_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_UCS_4: if (useParallelI2S) return (static_cast<B_32_I1_UCS_4P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_APA106_3: if (useParallelI2S) return (static_cast<B_32_I1_APA106_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_FW6_5: if (useParallelI2S) return (static_cast<B_32_I1_FW6_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_2805_5: if (useParallelI2S) return (static_cast<B_32_I1_2805_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_TM1914_3: if (useParallelI2S) return (static_cast<B_32_I1_TM1914_3P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I1_SM16825_5: if (useParallelI2S) return (static_cast<B_32_I1_SM16825_5P*>(busPtr))->CanShow(); else return (static_cast<B_32_I1_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
#endif
|
||||
// I2S0 bus
|
||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1914_3: (static_cast<B_32_I0_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_SM16825_5: (static_cast<B_32_I0_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_NEO_3: return (static_cast<B_32_I0_NEO_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_NEO_4: return (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_400_3: return (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1_4: return (static_cast<B_32_I0_TM1_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM2_3: return (static_cast<B_32_I0_TM2_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_3: return (static_cast<B_32_I0_UCS_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_UCS_4: return (static_cast<B_32_I0_UCS_4*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_APA106_3: return (static_cast<B_32_I0_APA106_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_FW6_5: return (static_cast<B_32_I0_FW6_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_2805_5: return (static_cast<B_32_I0_2805_5*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_TM1914_3: return (static_cast<B_32_I0_TM1914_3*>(busPtr))->CanShow(); break;
|
||||
case I_32_I0_SM16825_5: return (static_cast<B_32_I0_SM16825_5*>(busPtr))->CanShow(); break;
|
||||
#endif
|
||||
#endif
|
||||
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -119,7 +119,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 +137,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 +212,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 +259,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 +304,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>
|
||||
|
@ -256,7 +256,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();
|
||||
@ -411,6 +410,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 {
|
||||
|
@ -123,6 +123,7 @@ void handleImprovPacket() {
|
||||
}
|
||||
|
||||
checksum += next;
|
||||
checksum &= 0xFF;
|
||||
packetByte++;
|
||||
}
|
||||
}
|
||||
@ -193,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);
|
||||
|
@ -340,7 +340,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) {
|
||||
@ -357,7 +357,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);
|
||||
@ -448,21 +448,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;
|
||||
@ -123,7 +118,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) {
|
||||
|
@ -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
|
||||
|
@ -219,6 +219,7 @@ void WLED::loop()
|
||||
busConfigs[i] = nullptr;
|
||||
}
|
||||
strip.finalizeInit(); // also loads default ledmap if present
|
||||
BusManager::setBrightness(bri); // fix re-initialised bus' brightness #4005
|
||||
if (aligned) strip.makeAutoSegments();
|
||||
else strip.fixInvalidSegments();
|
||||
BusManager::setBrightness(bri); // fix re-initialised bus' brightness
|
||||
@ -380,6 +381,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
|
||||
@ -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
|
||||
|
@ -173,7 +173,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
|
||||
@ -228,7 +228,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
|
||||
@ -499,7 +499,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