mirror of
https://github.com/wled/WLED.git
synced 2025-07-16 23:36:35 +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
|
## 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
|
#### Build 2409140
|
||||||
- Configure different kinds of busses at compile (#4107 by @PaoloTK)
|
- Configure different kinds of busses at compile (#4107 by @PaoloTK)
|
||||||
- BREAKING: removes LEDPIN and DEFAULT_LED_TYPE compile overrides
|
- BREAKING: removes LEDPIN and DEFAULT_LED_TYPE compile overrides
|
||||||
- Fetch LED types from Bus classes (dynamic UI) (#4129 by @netmindz, @blazoncek, @dedehai)
|
- 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
|
#### Build 2409100
|
||||||
- WLED 0.15.0-b5 release
|
- 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
|
This European Union Public Licence (the ‘EUPL’) applies to the Work (as
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
defined below) which is provided under the terms of this Licence. Any use of
|
||||||
in the Software without restriction, including without limitation the rights
|
the Work, other than as authorised under this Licence is prohibited (to the
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
extent such use is covered by a right of the copyright holder of the Work).
|
||||||
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
|
The Work is provided under the terms of this Licence when the Licensor (as
|
||||||
copies or substantial portions of the Software.
|
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
|
Licensed under the EUPL
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
or has expressed by any other means his willingness to license under the EUPL.
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
1. Definitions
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
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",
|
"name": "wled",
|
||||||
"version": "0.15.0-b5",
|
"version": "0.15.0-b7",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.15.0-b5",
|
"version": "0.15.0-b7",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clean-css": "^5.3.3",
|
"clean-css": "^5.3.3",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.15.0-b5",
|
"version": "0.15.0-b7",
|
||||||
"description": "Tools for WLED project",
|
"description": "Tools for WLED project",
|
||||||
"main": "tools/cdata.js",
|
"main": "tools/cdata.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -197,6 +197,7 @@ build_flags =
|
|||||||
; decrease code cache size and increase IRAM to fit all pixel functions
|
; 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 ;; 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 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 =
|
lib_deps =
|
||||||
#https://github.com/lorol/LITTLEFS.git
|
#https://github.com/lorol/LITTLEFS.git
|
||||||
@ -259,7 +260,8 @@ lib_deps =
|
|||||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
# additional build flags for audioreactive
|
# 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
|
AR_lib_deps = kosme/arduinoFFT @ 2.0.1
|
||||||
|
|
||||||
[esp32_idf_V4]
|
[esp32_idf_V4]
|
||||||
@ -430,7 +432,26 @@ lib_deps = ${esp32_idf_V4.lib_deps}
|
|||||||
${esp32.AR_lib_deps}
|
${esp32.AR_lib_deps}
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
board_build.partitions = ${esp32.large_partitions}
|
board_build.partitions = ${esp32.large_partitions}
|
||||||
|
board_upload.flash_size = 8MB
|
||||||
|
board_upload.maximum_size = 8388608
|
||||||
; board_build.f_flash = 80000000L
|
; 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]
|
;[env:esp32dev_audioreactive]
|
||||||
;board = esp32dev
|
;board = esp32dev
|
||||||
@ -508,6 +529,8 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=
|
|||||||
lib_deps = ${esp32s3.lib_deps}
|
lib_deps = ${esp32s3.lib_deps}
|
||||||
${esp32.AR_lib_deps}
|
${esp32.AR_lib_deps}
|
||||||
board_build.partitions = ${esp32.extreme_partitions}
|
board_build.partitions = ${esp32.extreme_partitions}
|
||||||
|
board_upload.flash_size = 16MB
|
||||||
|
board_upload.maximum_size = 16777216
|
||||||
board_build.f_flash = 80000000L
|
board_build.f_flash = 80000000L
|
||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
@ -533,6 +556,33 @@ board_build.f_flash = 80000000L
|
|||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
monitor_filters = esp32_exception_decoder
|
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]
|
[env:esp32s3_4M_qspi]
|
||||||
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
|
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
|
||||||
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
|
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
|
||||||
|
@ -359,6 +359,8 @@ upload_speed = 115200
|
|||||||
lib_deps = ${esp32c3.lib_deps}
|
lib_deps = ${esp32c3.lib_deps}
|
||||||
board_build.partitions = tools/WLED_ESP32_2MB_noOTA.csv
|
board_build.partitions = tools/WLED_ESP32_2MB_noOTA.csv
|
||||||
board_build.flash_mode = dio
|
board_build.flash_mode = dio
|
||||||
|
board_upload.flash_size = 2MB
|
||||||
|
board_upload.maximum_size = 2097152
|
||||||
|
|
||||||
[env:wemos_shield_esp32]
|
[env:wemos_shield_esp32]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
|
@ -61,7 +61,7 @@ See [here](https://kno.wled.ge/basics/compatible-hardware)!
|
|||||||
|
|
||||||
## ✌️ Other
|
## ✌️ Other
|
||||||
|
|
||||||
Licensed under the MIT license
|
Licensed under the EUPL v1.2 license
|
||||||
Credits [here](https://kno.wled.ge/about/contributors/)!
|
Credits [here](https://kno.wled.ge/about/contributors/)!
|
||||||
|
|
||||||
Join the Discord server to discuss everything about WLED!
|
Join the Discord server to discuss everything about WLED!
|
||||||
@ -80,5 +80,5 @@ If WLED really brightens up your day, you can [ {
|
void appendConfigData() {
|
||||||
//oappend(SET_F("dd=addDropdown('staircase','selectfield');"));
|
//oappend(F("dd=addDropdown('staircase','selectfield');"));
|
||||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
//oappend(F("addOption(dd,'1st value',0);"));
|
||||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
//oappend(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("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);
|
// 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*/
|
/* Dropdown for Celsius/Fahrenheit*/
|
||||||
oappend(SET_F("dd=addDropdown('"));
|
oappend(F("dd=addDropdown('"));
|
||||||
oappend(UMOD_NAME);
|
oappend(UMOD_NAME);
|
||||||
oappend(SET_F("','"));
|
oappend(F("','"));
|
||||||
oappend(_nameTempScale);
|
oappend(_nameTempScale);
|
||||||
oappend(SET_F("');"));
|
oappend(F("');"));
|
||||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
oappend(F("addOption(dd,'Celsius',0);"));
|
||||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||||
|
|
||||||
/* i²C Address*/
|
/* i²C Address*/
|
||||||
oappend(SET_F("dd=addDropdown('"));
|
oappend(F("dd=addDropdown('"));
|
||||||
oappend(UMOD_NAME);
|
oappend(UMOD_NAME);
|
||||||
oappend(SET_F("','"));
|
oappend(F("','"));
|
||||||
oappend(_nameI2CAdr);
|
oappend(_nameI2CAdr);
|
||||||
oappend(SET_F("');"));
|
oappend(F("');"));
|
||||||
oappend(SET_F("addOption(dd,'0x76',0x76);"));
|
oappend(F("addOption(dd,'0x76',0x76);"));
|
||||||
oappend(SET_F("addOption(dd,'0x77',0x77);"));
|
oappend(F("addOption(dd,'0x77',0x77);"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -478,29 +478,29 @@ class UsermodBattery : public Usermod
|
|||||||
void appendConfigData()
|
void appendConfigData()
|
||||||
{
|
{
|
||||||
// Total: 462 Bytes
|
// Total: 462 Bytes
|
||||||
oappend(SET_F("td=addDropdown('Battery','type');")); // 34 Bytes
|
oappend(F("td=addDropdown('Battery','type');")); // 34 Bytes
|
||||||
oappend(SET_F("addOption(td,'Unkown','0');")); // 28 Bytes
|
oappend(F("addOption(td,'Unkown','0');")); // 28 Bytes
|
||||||
oappend(SET_F("addOption(td,'LiPo','1');")); // 26 Bytes
|
oappend(F("addOption(td,'LiPo','1');")); // 26 Bytes
|
||||||
oappend(SET_F("addOption(td,'LiOn','2');")); // 26 Bytes
|
oappend(F("addOption(td,'LiOn','2');")); // 26 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
oappend(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(F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
oappend(F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
oappend(F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
oappend(F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
oappend(F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
oappend(F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
|
||||||
oappend(SET_F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
oappend(F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
|
||||||
|
|
||||||
// this option list would exeed the oappend() buffer
|
// this option list would exeed the oappend() buffer
|
||||||
// a list of all presets to select one from
|
// a list of all presets to select one from
|
||||||
// oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
// oappend(F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||||
// the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);"));
|
// the loop generates: oappend(F("addOption(bd, 'preset name', preset id);"));
|
||||||
// for(int8_t i=1; i < 42; i++) {
|
// for(int8_t i=1; i < 42; i++) {
|
||||||
// oappend(SET_F("addOption(bd, 'Preset#"));
|
// oappend(F("addOption(bd, 'Preset#"));
|
||||||
// oappendi(i);
|
// oappendi(i);
|
||||||
// oappend(SET_F("',"));
|
// oappend(F("',"));
|
||||||
// oappendi(i);
|
// oappendi(i);
|
||||||
// oappend(SET_F(");"));
|
// oappend(F(");"));
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,11 +287,11 @@ class MyExampleUsermod : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void appendConfigData() override
|
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(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":great")); oappend(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(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":testString")); oappend(F("',1,'enter any string you want');"));
|
||||||
oappend(SET_F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F("','testInt');"));
|
oappend(F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(F("','testInt');"));
|
||||||
oappend(SET_F("addOption(dd,'Nothing',0);"));
|
oappend(F("addOption(dd,'Nothing',0);"));
|
||||||
oappend(SET_F("addOption(dd,'Everything',42);"));
|
oappend(F("addOption(dd,'Everything',42);"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,11 +149,11 @@ public:
|
|||||||
void appendConfigData()
|
void appendConfigData()
|
||||||
{
|
{
|
||||||
// Display 'ms' next to the 'Loop Interval' setting
|
// 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
|
// 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
|
// 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)
|
bool readFromConfig(JsonObject &root)
|
||||||
|
@ -511,8 +511,8 @@ void PIRsensorSwitch::addToConfig(JsonObject &root)
|
|||||||
|
|
||||||
void PIRsensorSwitch::appendConfigData()
|
void PIRsensorSwitch::appendConfigData()
|
||||||
{
|
{
|
||||||
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 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(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 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++) {
|
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
|
||||||
char str[128];
|
char str[128];
|
||||||
sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i);
|
sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i);
|
||||||
|
@ -377,10 +377,10 @@ class St7789DisplayUsermod : public Usermod {
|
|||||||
|
|
||||||
|
|
||||||
void appendConfigData() override {
|
void appendConfigData() override {
|
||||||
oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
oappend(F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||||
oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
oappend(F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||||
oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
oappend(F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||||
oappend(SET_F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
oappend(F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -435,10 +435,10 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UsermodTemperature::appendConfigData() {
|
void UsermodTemperature::appendConfigData() {
|
||||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
|
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(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(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(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(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("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||||
}
|
}
|
||||||
|
|
||||||
float UsermodTemperature::getTemperature() {
|
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)
|
#define LOG_256 5.54517744f // log(256)
|
||||||
|
|
||||||
// These are the input and output vectors. Input vectors receive computed results from FFT.
|
// 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* vReal = nullptr; // FFT sample inputs / freq output - these are our raw result bins
|
||||||
static float vImag[samplesFFT] = {0.0f}; // imaginary parts
|
static float* vImag = nullptr; // imaginary parts
|
||||||
|
|
||||||
// Create FFT object
|
// Create FFT object
|
||||||
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
// 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_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
|
// #define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - slower on ESP32
|
||||||
// Below options are forcing ArduinoFFT to use sqrtf() instead of sqrt()
|
// 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 - since v2.0.0 this must be done in build_flags
|
||||||
#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);
|
|
||||||
|
|
||||||
|
#include <arduinoFFT.h> // FFT object is created in FFTcode
|
||||||
// Helper functions
|
// Helper functions
|
||||||
|
|
||||||
// compute average of several FFT result bins
|
// compute average of several FFT result bins
|
||||||
@ -226,6 +221,18 @@ void FFTcode(void * parameter)
|
|||||||
{
|
{
|
||||||
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
|
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
|
// see https://www.freertos.org/vtaskdelayuntil.html
|
||||||
const TickType_t xFrequency = FFT_MIN_CYCLE * portTICK_PERIOD_MS;
|
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
|
// get a fresh batch of samples from I2S
|
||||||
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
|
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 defined(WLED_DEBUG) || defined(SR_DEBUG)
|
||||||
if (start < esp_timer_get_time()) { // filter out overflows
|
if (start < esp_timer_get_time()) { // filter out overflows
|
||||||
@ -265,8 +273,6 @@ void FFTcode(void * parameter)
|
|||||||
// find highest sample in the batch
|
// find highest sample in the batch
|
||||||
float maxSample = 0.0f; // max sample from FFT batch
|
float maxSample = 0.0f; // max sample from FFT batch
|
||||||
for (int i=0; i < samplesFFT; i++) {
|
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
|
// 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 ((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]);
|
if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]);
|
||||||
@ -297,7 +303,7 @@ void FFTcode(void * parameter)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else { // noise gate closed - only clear results as FFT was skipped. MIC samples are still valid when we do this.
|
} 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_MajorPeak = 1;
|
||||||
FFT_Magnitude = 0.001;
|
FFT_Magnitude = 0.001;
|
||||||
}
|
}
|
||||||
@ -1879,57 +1885,59 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void appendConfigData() override
|
void appendConfigData(Print& uiScript) override
|
||||||
{
|
{
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
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
|
||||||
oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');"));
|
#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)
|
#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
|
#endif
|
||||||
oappend(SET_F("addOption(dd,'Generic I2S',1);"));
|
uiScript.print(F("addOption(dd,'Generic I2S',1);"));
|
||||||
oappend(SET_F("addOption(dd,'ES7243',2);"));
|
uiScript.print(F("addOption(dd,'ES7243',2);"));
|
||||||
oappend(SET_F("addOption(dd,'SPH0654',3);"));
|
uiScript.print(F("addOption(dd,'SPH0654',3);"));
|
||||||
oappend(SET_F("addOption(dd,'Generic I2S with Mclk',4);"));
|
uiScript.print(F("addOption(dd,'Generic I2S with Mclk',4);"));
|
||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#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
|
#endif
|
||||||
oappend(SET_F("addOption(dd,'ES8388',6);"));
|
uiScript.print(F("addOption(dd,'ES8388',6);"));
|
||||||
|
|
||||||
oappend(SET_F("dd=addDropdown('AudioReactive','config:AGC');"));
|
uiScript.print(F("dd=addDropdown(ux,'config:AGC');"));
|
||||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||||
oappend(SET_F("addOption(dd,'Normal',1);"));
|
uiScript.print(F("addOption(dd,'Normal',1);"));
|
||||||
oappend(SET_F("addOption(dd,'Vivid',2);"));
|
uiScript.print(F("addOption(dd,'Vivid',2);"));
|
||||||
oappend(SET_F("addOption(dd,'Lazy',3);"));
|
uiScript.print(F("addOption(dd,'Lazy',3);"));
|
||||||
|
|
||||||
oappend(SET_F("dd=addDropdown('AudioReactive','dynamics:limiter');"));
|
uiScript.print(F("dd=addDropdown(ux,'dynamics:limiter');"));
|
||||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||||
oappend(SET_F("addOption(dd,'On',1);"));
|
uiScript.print(F("addOption(dd,'On',1);"));
|
||||||
oappend(SET_F("addInfo('AudioReactive:dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field
|
uiScript.print(F("addInfo(ux+':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>');"));
|
uiScript.print(F("addInfo(ux+':dynamics:rise',1,'ms <i>(♪ effects only)</i>');"));
|
||||||
oappend(SET_F("addInfo('AudioReactive:dynamics:fall',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');"));
|
uiScript.print(F("dd=addDropdown(ux,'frequency:scale');"));
|
||||||
oappend(SET_F("addOption(dd,'None',0);"));
|
uiScript.print(F("addOption(dd,'None',0);"));
|
||||||
oappend(SET_F("addOption(dd,'Linear (Amplitude)',2);"));
|
uiScript.print(F("addOption(dd,'Linear (Amplitude)',2);"));
|
||||||
oappend(SET_F("addOption(dd,'Square Root (Energy)',3);"));
|
uiScript.print(F("addOption(dd,'Square Root (Energy)',3);"));
|
||||||
oappend(SET_F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
uiScript.print(F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');"));
|
uiScript.print(F("dd=addDropdown(ux,'sync:mode');"));
|
||||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
uiScript.print(F("addOption(dd,'Off',0);"));
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
oappend(SET_F("addOption(dd,'Send',1);"));
|
uiScript.print(F("addOption(dd,'Send',1);"));
|
||||||
#endif
|
#endif
|
||||||
oappend(SET_F("addOption(dd,'Receive',2);"));
|
uiScript.print(F("addOption(dd,'Receive',2);"));
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
uiScript.print(F("addInfo(ux+':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');"));
|
uiScript.print(F("addInfo(uxp,0,'<i>sd/data/dout</i>','I2S SD');"));
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',1,'<i>ws/clk/lrck</i>','I2S WS');"));
|
uiScript.print(F("addInfo(uxp,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(uxp,2,'<i>sck/bclk</i>','I2S SCK');"));
|
||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
#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
|
#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
|
||||||
#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
|
### using latest _arduinoFFT_ library version 2.x
|
||||||
The latest arduinoFFT release version should be used for audioreactive.
|
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`
|
* `lib_deps`= `kosme/arduinoFFT @ 2.0.1`
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
@ -305,14 +305,14 @@ class BobLightUsermod : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void appendConfigData() override {
|
void appendConfigData() override {
|
||||||
//oappend(SET_F("dd=addDropdown('usermod','selectfield');"));
|
//oappend(F("dd=addDropdown('usermod','selectfield');"));
|
||||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
//oappend(F("addOption(dd,'1st value',0);"));
|
||||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
//oappend(F("addOption(dd,'2nd value',1);"));
|
||||||
oappend(SET_F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field
|
oappend(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(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(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(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("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||||
}
|
}
|
||||||
|
|
||||||
void addToConfig(JsonObject& root) override {
|
void addToConfig(JsonObject& root) override {
|
||||||
|
@ -264,7 +264,7 @@ void MultiRelay::handleOffTimer() {
|
|||||||
void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer
|
void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer
|
||||||
DEBUG_PRINTLN(F("Relays: Initialize HTML API"));
|
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"));
|
DEBUG_PRINTLN(F("Relays: HTML API"));
|
||||||
String janswer;
|
String janswer;
|
||||||
String error = "";
|
String error = "";
|
||||||
@ -765,10 +765,10 @@ void MultiRelay::addToConfig(JsonObject &root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MultiRelay::appendConfigData() {
|
void MultiRelay::appendConfigData() {
|
||||||
oappend(SET_F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
oappend(F("addInfo('MultiRelay:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
||||||
oappend(SET_F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
oappend(F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');"));
|
||||||
//oappend(SET_F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');"));
|
//oappend(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("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.
|
// 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.
|
// 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 "
|
"addInfo('DiceTray:ble_scan_duration',1,'<br><br><i>Set to \"*\" to "
|
||||||
"connect to any die.<br>Leave Blank to disable.</i><br><i "
|
"connect to any die.<br>Leave Blank to disable.</i><br><i "
|
||||||
"class=\"warn\">Saving will replace \"*\" with die names.</i>','');"));
|
"class=\"warn\">Saving will replace \"*\" with die names.</i>','');"));
|
||||||
#if USING_TFT_DISPLAY
|
#if USING_TFT_DISPLAY
|
||||||
oappend(SET_F("ddr=addDropdown('DiceTray','rotation');"));
|
oappend(F("ddr=addDropdown('DiceTray','rotation');"));
|
||||||
oappend(SET_F("addOption(ddr,'0 deg',0);"));
|
oappend(F("addOption(ddr,'0 deg',0);"));
|
||||||
oappend(SET_F("addOption(ddr,'90 deg',1);"));
|
oappend(F("addOption(ddr,'90 deg',1);"));
|
||||||
oappend(SET_F("addOption(ddr,'180 deg',2);"));
|
oappend(F("addOption(ddr,'180 deg',2);"));
|
||||||
oappend(SET_F("addOption(ddr,'270 deg',3);"));
|
oappend(F("addOption(ddr,'270 deg',3);"));
|
||||||
oappend(SET_F(
|
oappend(F(
|
||||||
"addInfo('DiceTray:rotation',1,'<br><i class=\"warn\">DO NOT CHANGE "
|
"addInfo('DiceTray:rotation',1,'<br><i class=\"warn\">DO NOT CHANGE "
|
||||||
"SPI PINS.</i><br><i class=\"warn\">CHANGES ARE IGNORED.</i>','');"));
|
"SPI PINS.</i><br><i class=\"warn\">CHANGES ARE IGNORED.</i>','');"));
|
||||||
oappend(SET_F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
oappend(F("addInfo('TFT:pin[]',0,'','SPI CS');"));
|
||||||
oappend(SET_F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
oappend(F("addInfo('TFT:pin[]',1,'','SPI DC');"));
|
||||||
oappend(SET_F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
oappend(F("addInfo('TFT:pin[]',2,'','SPI RST');"));
|
||||||
oappend(SET_F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
oappend(F("addInfo('TFT:pin[]',3,'','SPI BL');"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,22 +310,22 @@ void ShtUsermod::onMqttConnect(bool sessionPresent) {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
void ShtUsermod::appendConfigData() {
|
void ShtUsermod::appendConfigData() {
|
||||||
oappend(SET_F("dd=addDropdown('"));
|
oappend(F("dd=addDropdown('"));
|
||||||
oappend(_name);
|
oappend(_name);
|
||||||
oappend(SET_F("','"));
|
oappend(F("','"));
|
||||||
oappend(_shtType);
|
oappend(_shtType);
|
||||||
oappend(SET_F("');"));
|
oappend(F("');"));
|
||||||
oappend(SET_F("addOption(dd,'SHT30',0);"));
|
oappend(F("addOption(dd,'SHT30',0);"));
|
||||||
oappend(SET_F("addOption(dd,'SHT31',1);"));
|
oappend(F("addOption(dd,'SHT31',1);"));
|
||||||
oappend(SET_F("addOption(dd,'SHT35',2);"));
|
oappend(F("addOption(dd,'SHT35',2);"));
|
||||||
oappend(SET_F("addOption(dd,'SHT85',3);"));
|
oappend(F("addOption(dd,'SHT85',3);"));
|
||||||
oappend(SET_F("dd=addDropdown('"));
|
oappend(F("dd=addDropdown('"));
|
||||||
oappend(_name);
|
oappend(_name);
|
||||||
oappend(SET_F("','"));
|
oappend(F("','"));
|
||||||
oappend(_unitOfTemp);
|
oappend(_unitOfTemp);
|
||||||
oappend(SET_F("');"));
|
oappend(F("');"));
|
||||||
oappend(SET_F("addOption(dd,'Celsius',0);"));
|
oappend(F("addOption(dd,'Celsius',0);"));
|
||||||
oappend(SET_F("addOption(dd,'Fahrenheit',1);"));
|
oappend(F("addOption(dd,'Fahrenheit',1);"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +96,7 @@ void setup() {
|
|||||||
jsonTransitionOnce = true;
|
jsonTransitionOnce = true;
|
||||||
strip.setTransition(0); //no transition
|
strip.setTransition(0); //no transition
|
||||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||||
resetTimebase(); //make sure wipe starts from beginning
|
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||||
|
|
||||||
//set wipe direction
|
//set wipe direction
|
||||||
Segment& seg = strip.getSegment(0);
|
Segment& seg = strip.getSegment(0);
|
||||||
|
@ -86,7 +86,7 @@ void startWipe()
|
|||||||
bri = briLast; //turn on
|
bri = briLast; //turn on
|
||||||
transitionDelayTemp = 0; //no transition
|
transitionDelayTemp = 0; //no transition
|
||||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||||
resetTimebase(); //make sure wipe starts from beginning
|
strip.resetTimebase(); //make sure wipe starts from beginning
|
||||||
|
|
||||||
//set wipe direction
|
//set wipe direction
|
||||||
Segment& seg = strip.getSegment(0);
|
Segment& seg = strip.getSegment(0);
|
||||||
|
@ -1202,21 +1202,21 @@ void FourLineDisplayUsermod::onUpdateBegin(bool init) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
void FourLineDisplayUsermod::appendConfigData() {
|
void FourLineDisplayUsermod::appendConfigData() {
|
||||||
oappend(SET_F("dd=addDropdown('4LineDisplay','type');"));
|
oappend(F("dd=addDropdown('4LineDisplay','type');"));
|
||||||
oappend(SET_F("addOption(dd,'None',0);"));
|
oappend(F("addOption(dd,'None',0);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306',1);"));
|
oappend(F("addOption(dd,'SSD1306',1);"));
|
||||||
oappend(SET_F("addOption(dd,'SH1106',2);"));
|
oappend(F("addOption(dd,'SH1106',2);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
|
oappend(F("addOption(dd,'SSD1306 128x64',3);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1305',4);"));
|
oappend(F("addOption(dd,'SSD1305',4);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
|
oappend(F("addOption(dd,'SSD1305 128x64',5);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1309 128x64',9);"));
|
oappend(F("addOption(dd,'SSD1309 128x64',9);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
|
oappend(F("addOption(dd,'SSD1306 SPI',6);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
oappend(F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
oappend(F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||||
oappend(SET_F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
oappend(F("addInfo('4LineDisplay:type',1,'<br><i class=\"warn\">Change may require reboot</i>','');"));
|
||||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
oappend(F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');"));
|
||||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
oappend(F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');"));
|
||||||
oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
oappend(F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1090,8 +1090,8 @@ void RotaryEncoderUIUsermod::addToConfig(JsonObject &root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RotaryEncoderUIUsermod::appendConfigData() {
|
void RotaryEncoderUIUsermod::appendConfigData() {
|
||||||
oappend(SET_F("addInfo('Rotary-Encoder:PCF8574-address',1,'<i>(not hex!)</i>');"));
|
oappend(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("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()
|
void appendConfigData()
|
||||||
{
|
{
|
||||||
oappend(SET_F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');"));
|
oappend(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:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -54,13 +54,13 @@ class WireguardUsermod : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void appendConfigData() {
|
void appendConfigData() {
|
||||||
oappend(SET_F("addInfo('WireGuard:host',1,'Server Hostname');")); // 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(SET_F("addInfo('WireGuard:port',1,'Server Port');")); // 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(SET_F("addInfo('WireGuard:ip',1,'Device IP');")); // 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(SET_F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 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(SET_F("addInfo('WireGuard:pem',1,'Private Key');")); // 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(SET_F("addInfo('WireGuard:pub',1,'Public 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(SET_F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 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) {
|
void addToConfig(JsonObject& root) {
|
||||||
|
@ -2,24 +2,10 @@
|
|||||||
WS2812FX.cpp contains all effect methods
|
WS2812FX.cpp contains all effect methods
|
||||||
Harm Aldick - 2016
|
Harm Aldick - 2016
|
||||||
www.aldick.org
|
www.aldick.org
|
||||||
LICENSE
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2016 Harm Aldick
|
Copyright (c) 2016 Harm Aldick
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Licensed under the EUPL v. 1.2 or later
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
Adapted from code originally licensed under the MIT license
|
||||||
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.
|
|
||||||
|
|
||||||
Modified heavily for WLED
|
Modified heavily for WLED
|
||||||
*/
|
*/
|
||||||
@ -2516,9 +2502,9 @@ static uint16_t ripple_base() {
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int left = rippleorigin - propI -1;
|
int left = rippleorigin - propI -1;
|
||||||
int right = rippleorigin + propI +3;
|
int right = rippleorigin + propI +2;
|
||||||
for (int v = 0; v < 4; v++) {
|
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(left + v, color_blend(SEGMENT.getPixelColor(left + v), col, mag)); // TODO
|
||||||
SEGMENT.setPixelColor(right - v, color_blend(SEGMENT.getPixelColor(right - 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.
|
// 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.
|
// 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);
|
uint32_t deltams = (FRAMETIME >> 2) + ((FRAMETIME * SEGMENT.speed) >> 7);
|
||||||
uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7);
|
uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7);
|
||||||
strip.now = deltat;
|
strip.now = deltat;
|
||||||
@ -4042,7 +4028,7 @@ uint16_t mode_pacifica()
|
|||||||
sCIStart3 -= (deltams1 * beatsin88(501,5,7));
|
sCIStart3 -= (deltams1 * beatsin88(501,5,7));
|
||||||
sCIStart4 -= (deltams2 * beatsin88(257,4,6));
|
sCIStart4 -= (deltams2 * beatsin88(257,4,6));
|
||||||
SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2;
|
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
|
// Clear out the LED array to a dim background blue-green
|
||||||
//SEGMENT.fill(132618);
|
//SEGMENT.fill(132618);
|
||||||
@ -4920,8 +4906,8 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
|
|||||||
SEGMENT.fadeToBlackBy(40);
|
SEGMENT.fadeToBlackBy(40);
|
||||||
for (size_t i = 0; i < numLines; i++) {
|
for (size_t i = 0; i < numLines; i++) {
|
||||||
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
|
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
|
||||||
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1));
|
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (rows - 1));
|
||||||
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 24);
|
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);
|
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);
|
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
|
// draw a gradient line between x and x1
|
||||||
x = x / 2; x1 = x1 / 2;
|
x = x / 2; x1 = x1 / 2;
|
||||||
unsigned steps = abs8(x - x1) + 1;
|
unsigned steps = abs8(x - x1) + 1;
|
||||||
|
bool positive = (x1 >= x); // direction of drawing
|
||||||
for (size_t k = 1; k <= steps; k++) {
|
for (size_t k = 1; k <= steps; k++) {
|
||||||
unsigned rate = k * 255 / steps;
|
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.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.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, hue, 255, LINEARBLEND)); // use setPixelColorXY for different look
|
||||||
SEGMENT.fadePixelColorXY(dx, i, rate);
|
SEGMENT.fadePixelColorXY(dx, i, rate);
|
||||||
@ -7516,8 +7504,9 @@ uint16_t mode_2DAkemi(void) {
|
|||||||
|
|
||||||
//add geq left and right
|
//add geq left and right
|
||||||
if (um_data && fftResult) {
|
if (um_data && fftResult) {
|
||||||
for (int x=0; x < cols/8; x++) {
|
int xMax = cols/8;
|
||||||
unsigned band = x * 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);
|
band = constrain(band, 0, 15);
|
||||||
int barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32);
|
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);
|
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;
|
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
|
||||||
for (int x = 0; x < cols; x++) {
|
for (int x = 0; x < cols; x++) {
|
||||||
for (int y = 0; y < rows; y++) {
|
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
|
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.
|
WS2812FX.h - Library for WS2812 LED effects.
|
||||||
Harm Aldick - 2016
|
Harm Aldick - 2016
|
||||||
www.aldick.org
|
www.aldick.org
|
||||||
LICENSE
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2016 Harm Aldick
|
Copyright (c) 2016 Harm Aldick
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Licensed under the EUPL v. 1.2 or later
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
Adapted from code originally licensed under the MIT license
|
||||||
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.
|
|
||||||
|
|
||||||
Modified for WLED
|
Modified for WLED
|
||||||
*/
|
*/
|
||||||
@ -65,6 +51,15 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
|
|||||||
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||||
#define FRAMETIME strip.getFrameTime()
|
#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
|
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -556,12 +551,12 @@ typedef struct Segment {
|
|||||||
|
|
||||||
void beginDraw(); // set up parameters for current effect
|
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);
|
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
|
Segment &setColor(uint8_t slot, uint32_t c);
|
||||||
void setCCT(uint16_t k);
|
Segment &setCCT(uint16_t k);
|
||||||
void setOpacity(uint8_t o);
|
Segment &setOpacity(uint8_t o);
|
||||||
void setOption(uint8_t n, bool val);
|
Segment &setOption(uint8_t n, bool val);
|
||||||
void setMode(uint8_t fx, bool loadDefaults = false);
|
Segment &setMode(uint8_t fx, bool loadDefaults = false);
|
||||||
void setPalette(uint8_t pal);
|
Segment &setPalette(uint8_t pal);
|
||||||
uint8_t differs(const Segment& b) const;
|
uint8_t differs(const Segment& b) const;
|
||||||
void refreshLightCapabilities();
|
void refreshLightCapabilities();
|
||||||
|
|
||||||
@ -576,7 +571,7 @@ typedef struct Segment {
|
|||||||
* Call resetIfRequired before calling the next effect function.
|
* Call resetIfRequired before calling the next effect function.
|
||||||
* Safe to call from interrupts and network requests.
|
* 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
|
// transition functions
|
||||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||||
@ -627,9 +622,15 @@ typedef struct Segment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2D matrix
|
// 2D matrix
|
||||||
[[gnu::hot]] uint16_t virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
[[gnu::hot]] unsigned 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)
|
[[gnu::hot]] unsigned 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)
|
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
|
#ifndef WLED_DISABLE_2D
|
||||||
[[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment
|
[[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
|
[[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
|
#ifndef WLED_DISABLE_2D
|
||||||
panels(1),
|
panels(1),
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WLED_AUTOSEGMENTS
|
||||||
|
autoSegments(true),
|
||||||
|
#else
|
||||||
autoSegments(false),
|
autoSegments(false),
|
||||||
|
#endif
|
||||||
correctWB(false),
|
correctWB(false),
|
||||||
cctFromRgb(false),
|
cctFromRgb(false),
|
||||||
// true private variables
|
// true private variables
|
||||||
@ -741,7 +746,7 @@ class WS2812FX { // 96 bytes
|
|||||||
_transitionDur(750),
|
_transitionDur(750),
|
||||||
_targetFps(WLED_FPS),
|
_targetFps(WLED_FPS),
|
||||||
_frametime(FRAMETIME_FIXED),
|
_frametime(FRAMETIME_FIXED),
|
||||||
_cumulativeFps(2),
|
_cumulativeFps(50 << FPS_CALC_SHIFT),
|
||||||
_isServicing(false),
|
_isServicing(false),
|
||||||
_isOffRefreshRequired(false),
|
_isOffRefreshRequired(false),
|
||||||
_hasWhiteChannel(false),
|
_hasWhiteChannel(false),
|
||||||
@ -793,7 +798,8 @@ class WS2812FX { // 96 bytes
|
|||||||
setTargetFps(unsigned fps),
|
setTargetFps(unsigned fps),
|
||||||
setupEffectData(); // add default effects to the list; defined in FX.cpp
|
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 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, 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); }
|
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,
|
getLengthPhysical() const,
|
||||||
getLengthTotal() const; // will include virtual/nonexistent pixels in matrix
|
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 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 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)
|
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;
|
return index;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t now, timebase;
|
unsigned long now, timebase;
|
||||||
uint32_t getPixelColor(unsigned) const;
|
uint32_t getPixelColor(unsigned) const;
|
||||||
|
|
||||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
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
|
FX_2Dfcn.cpp contains all 2D utility functions
|
||||||
|
|
||||||
LICENSE
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2022 Blaz Kristan (https://blaz.at/home)
|
Copyright (c) 2022 Blaz Kristan (https://blaz.at/home)
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Licensed under the EUPL v. 1.2 or later
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
Adapted from code originally licensed under the MIT license
|
||||||
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.
|
|
||||||
|
|
||||||
Parts of the code adapted from WLED Sound Reactive
|
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
|
// returns RGBW values of pixel
|
||||||
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
||||||
if (!isActive()) return 0; // not active
|
if (!isActive()) return 0; // not active
|
||||||
int vW = vWidth();
|
const int vW = vWidth();
|
||||||
int vH = vHeight();
|
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 (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 ) x = vW - x - 1;
|
||||||
if (reverse_y) y = vH - y - 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)};
|
WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)};
|
||||||
// multiply the intensities by the colour, and saturating-add them to the pixels
|
// multiply the intensities by the colour, and saturating-add them to the pixels
|
||||||
for (int i = 0; i < 4; i++) {
|
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.r = qadd8(led.r, c.r * wu[i] >> 8);
|
||||||
led.g = qadd8(led.g, c.g * wu[i] >> 8);
|
led.g = qadd8(led.g, c.g * wu[i] >> 8);
|
||||||
led.b = qadd8(led.b, c.b * 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
|
#undef WU_WEIGHT
|
||||||
|
@ -2,24 +2,10 @@
|
|||||||
WS2812FX_fcn.cpp contains all utility functions
|
WS2812FX_fcn.cpp contains all utility functions
|
||||||
Harm Aldick - 2016
|
Harm Aldick - 2016
|
||||||
www.aldick.org
|
www.aldick.org
|
||||||
LICENSE
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2016 Harm Aldick
|
Copyright (c) 2016 Harm Aldick
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Licensed under the EUPL v. 1.2 or later
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
Adapted from code originally licensed under the MIT license
|
||||||
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.
|
|
||||||
|
|
||||||
Modified heavily for WLED
|
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
|
Segment &Segment::setColor(uint8_t slot, uint32_t c) {
|
||||||
if (slot >= NUM_COLORS || c == colors[slot]) return false;
|
if (slot >= NUM_COLORS || c == colors[slot]) return *this;
|
||||||
if (!_isRGB && !_hasW) {
|
if (!_isRGB && !_hasW) {
|
||||||
if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black
|
if (slot == 0 && c == BLACK) return *this; // 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 == 1 && c != BLACK) return *this; // on/off segment cannot have secondary color non black
|
||||||
}
|
}
|
||||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||||
colors[slot] = c;
|
colors[slot] = c;
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
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 > 255) { //kelvin value, convert to 0-255
|
||||||
if (k < 1900) k = 1900;
|
if (k < 1900) k = 1900;
|
||||||
if (k > 10091) k = 10091;
|
if (k > 10091) k = 10091;
|
||||||
k = (k - 1900) >> 5;
|
k = (k - 1900) >> 5;
|
||||||
}
|
}
|
||||||
if (cct == k) return;
|
if (cct != k) {
|
||||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
//DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k);
|
||||||
cct = k;
|
startTransition(strip.getTransition()); // start transition prior to change
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
cct = k;
|
||||||
|
stateChanged = true; // send UDP/WS broadcast
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::setOpacity(uint8_t o) {
|
Segment &Segment::setOpacity(uint8_t o) {
|
||||||
if (opacity == o) return;
|
if (opacity != o) {
|
||||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
//DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o);
|
||||||
opacity = o;
|
startTransition(strip.getTransition()); // start transition prior to change
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
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;
|
bool prevOn = on;
|
||||||
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||||
if (val) options |= 0x01 << n;
|
if (val) options |= 0x01 << n;
|
||||||
else options &= ~(0x01 << n);
|
else options &= ~(0x01 << n);
|
||||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast
|
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
|
// skip reserved
|
||||||
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
||||||
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
||||||
@ -625,9 +618,10 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
|||||||
markForReset();
|
markForReset();
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
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 && 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 > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes
|
||||||
if (pal != palette) {
|
if (pal != palette) {
|
||||||
@ -635,31 +629,24 @@ void Segment::setPalette(uint8_t pal) {
|
|||||||
palette = pal;
|
palette = pal;
|
||||||
stateChanged = true; // send UDP/WS broadcast
|
stateChanged = true; // send UDP/WS broadcast
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2D matrix
|
// 2D matrix
|
||||||
uint16_t Segment::virtualWidth() const {
|
unsigned Segment::virtualWidth() const {
|
||||||
unsigned groupLen = groupLength();
|
unsigned groupLen = groupLength();
|
||||||
unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
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
|
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
return vWidth;
|
return vWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Segment::virtualHeight() const {
|
unsigned Segment::virtualHeight() const {
|
||||||
unsigned groupLen = groupLength();
|
unsigned groupLen = groupLength();
|
||||||
unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
|
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
|
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
return vHeight;
|
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"
|
// Constants for mapping mode "Pinwheel"
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
|
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)
|
//do not call this method from system context (network callback)
|
||||||
void WS2812FX::finalizeInit() {
|
void WS2812FX::finalizeInit() {
|
||||||
//reset segment runtimes
|
//reset segment runtimes
|
||||||
for (segment &seg : _segments) {
|
restartRuntime();
|
||||||
seg.markForReset();
|
|
||||||
seg.resetIfRequired();
|
|
||||||
}
|
|
||||||
|
|
||||||
// for the lack of better place enumerate ledmaps here
|
// for the lack of better place enumerate ledmaps here
|
||||||
// if we do it in json.cpp (serializeInfo()) we are getting flashes on LEDs
|
// 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))
|
if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
||||||
{
|
{
|
||||||
doShow = true;
|
doShow = true;
|
||||||
unsigned delay = FRAMETIME;
|
unsigned frameDelay = FRAMETIME;
|
||||||
|
|
||||||
if (!seg.freeze) { //only run effect function if not frozen
|
if (!seg.freeze) { //only run effect function if not frozen
|
||||||
int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based)
|
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.
|
// 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
|
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||||
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
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
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
if (modeBlending && seg.mode != tmpMode) {
|
if (modeBlending && seg.mode != tmpMode) {
|
||||||
Segment::tmpsegd_t _tmpSegData;
|
Segment::tmpsegd_t _tmpSegData;
|
||||||
@ -1416,16 +1400,16 @@ void WS2812FX::service() {
|
|||||||
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
||||||
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
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
|
Segment::modeBlend(false); // unset semaphore
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
seg.call++;
|
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
|
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||||
}
|
}
|
||||||
|
|
||||||
seg.next_time = nowUp + delay;
|
seg.next_time = nowUp + frameDelay;
|
||||||
}
|
}
|
||||||
_segment_index++;
|
_segment_index++;
|
||||||
}
|
}
|
||||||
@ -1469,10 +1453,12 @@ void WS2812FX::show() {
|
|||||||
|
|
||||||
unsigned long showNow = millis();
|
unsigned long showNow = millis();
|
||||||
size_t diff = showNow - _lastShow;
|
size_t diff = showNow - _lastShow;
|
||||||
size_t fpsCurr = 200;
|
|
||||||
if (diff > 0) fpsCurr = 1000 / diff;
|
if (diff > 0) { // skip calculation if no time has passed
|
||||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
|
size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math
|
||||||
_lastShow = showNow;
|
_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) {
|
void WS2812FX::setTargetFps(unsigned fps) {
|
||||||
|
@ -766,47 +766,47 @@ class PolyBus {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
// RMT buses
|
// RMT buses
|
||||||
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(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: (static_cast<B_32_RN_NEO_4*>(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: (static_cast<B_32_RN_400_3*>(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: (static_cast<B_32_RN_TM1_4*>(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: (static_cast<B_32_RN_TM2_3*>(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: (static_cast<B_32_RN_UCS_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: (static_cast<B_32_RN_UCS_4*>(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: (static_cast<B_32_RN_APA106_3*>(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: (static_cast<B_32_RN_FW6_5*>(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: (static_cast<B_32_RN_2805_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: (static_cast<B_32_RN_TM1914_3*>(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: (static_cast<B_32_RN_SM16825_5*>(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
|
// I2S1 bus or paralell buses
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#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_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) (static_cast<B_32_I1_NEO_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_NEO_4*>(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) (static_cast<B_32_I1_400_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_400_3*>(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) (static_cast<B_32_I1_TM1_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM1_4*>(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) (static_cast<B_32_I1_TM2_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM2_3*>(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) (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_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) (static_cast<B_32_I1_UCS_4P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_UCS_4*>(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) (static_cast<B_32_I1_APA106_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_APA106_3*>(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) (static_cast<B_32_I1_FW6_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_FW6_5*>(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) (static_cast<B_32_I1_2805_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_2805_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) (static_cast<B_32_I1_TM1914_3P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_TM1914_3*>(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) (static_cast<B_32_I1_SM16825_5P*>(busPtr))->CanShow(); else (static_cast<B_32_I1_SM16825_5*>(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
|
#endif
|
||||||
// I2S0 bus
|
// I2S0 bus
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#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_3: return (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_NEO_4: return (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_400_3: return (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_TM1_4: return (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_TM2_3: return (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_3: return (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_UCS_4: return (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_APA106_3: return (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_FW6_5: return (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_2805_5: return (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_TM1914_3: return (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_SM16825_5: return (static_cast<B_32_I0_SM16825_5*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
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;
|
briLast = bri;
|
||||||
bri = 0;
|
bri = 0;
|
||||||
} else {
|
} else {
|
||||||
|
if (bri == 0) strip.restartRuntime();
|
||||||
bri = aRead;
|
bri = aRead;
|
||||||
}
|
}
|
||||||
} else if (macroDoublePress[b] == 249) {
|
} else if (macroDoublePress[b] == 249) {
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
#else
|
#else
|
||||||
#define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX)
|
#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
|
#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_DIGITAL_CHANNELS 2
|
||||||
//#define WLED_MAX_ANALOG_CHANNELS 6
|
//#define WLED_MAX_ANALOG_CHANNELS 6
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||||
|
@ -144,7 +144,7 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.huge {
|
.huge {
|
||||||
font-size: 42px;
|
font-size: 60px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.segt, .plentry TABLE {
|
.segt, .plentry TABLE {
|
||||||
@ -584,6 +584,10 @@ button {
|
|||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#rover .ibtn {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#ndlt {
|
#ndlt {
|
||||||
margin: 12px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
@ -624,7 +628,7 @@ button {
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.infobtn {
|
#info .ibtn {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -848,7 +852,7 @@ input[type=range]::-moz-range-thumb {
|
|||||||
width: 135px;
|
width: 135px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nodes .infobtn {
|
#nodes .ibtn {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1036,7 +1040,7 @@ textarea {
|
|||||||
|
|
||||||
.segname .flr, .pname .flr {
|
.segname .flr, .pname .flr {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
right: -6px;
|
/*right: -6px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* segment power wrapper */
|
/* segment power wrapper */
|
||||||
@ -1331,6 +1335,11 @@ TD .checkmark, TD .radiomark {
|
|||||||
box-shadow: 0 0 10px 4px var(--c-1);
|
box-shadow: 0 0 10px 4px var(--c-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lstI .flr:hover {
|
||||||
|
background: var(--c-6);
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#pcont .selected:not([class*="expanded"]) {
|
#pcont .selected:not([class*="expanded"]) {
|
||||||
bottom: 52px;
|
bottom: 52px;
|
||||||
top: 42px;
|
top: 42px;
|
||||||
@ -1524,7 +1533,7 @@ dialog {
|
|||||||
#info table .btn, #nodes table .btn {
|
#info table .btn, #nodes table .btn {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
#info .infobtn, #nodes .infobtn {
|
#info .ibtn, #nodes .ibtn {
|
||||||
width: 145px;
|
width: 145px;
|
||||||
}
|
}
|
||||||
#info div, #nodes div, #nodes a.btn {
|
#info div, #nodes div, #nodes a.btn {
|
||||||
|
@ -304,10 +304,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="kv">Loading...</div><br>
|
<div id="kv">Loading...</div><br>
|
||||||
<div>
|
<div>
|
||||||
<button class="btn infobtn" onclick="requestJson()">Refresh</button>
|
<button class="btn ibtn" onclick="requestJson()">Refresh</button>
|
||||||
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
<button class="btn ibtn" onclick="toggleNodes()">Instance List</button>
|
||||||
<button class="btn infobtn" onclick="window.open(getURL('/update'),'_self');">Update WLED</button>
|
<button class="btn ibtn" onclick="window.open(getURL('/update'),'_self');">Update WLED</button>
|
||||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
<button class="btn ibtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<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>
|
<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="ndlt">WLED instances</div>
|
||||||
<div id="kn">Loading...</div>
|
<div id="kn">Loading...</div>
|
||||||
<div style="position:sticky;bottom:0;">
|
<div style="position:sticky;bottom:0;">
|
||||||
<button class="btn infobtn" onclick="loadNodes()">Refresh</button>
|
<button class="btn ibtn" onclick="loadNodes()">Refresh</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -331,8 +331,8 @@
|
|||||||
<div id="lv">?</div><br><br>
|
<div id="lv">?</div><br><br>
|
||||||
To use built-in effects, use an override button below.<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>
|
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 ibtn" onclick="setLor(1)">Override once</button>
|
||||||
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
<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>
|
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -119,7 +119,12 @@
|
|||||||
var en = d.Sf.ABL.checked;
|
var en = d.Sf.ABL.checked;
|
||||||
gId('abl').style.display = (en) ? 'inline':'none';
|
gId('abl').style.display = (en) ? 'inline':'none';
|
||||||
gId('psu2').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();
|
UI();
|
||||||
}
|
}
|
||||||
// enable per port limiter and calculate current
|
// enable per port limiter and calculate current
|
||||||
@ -132,46 +137,51 @@
|
|||||||
d.Sf.MA.min = abl && !ppl ? 250 : 0;
|
d.Sf.MA.min = abl && !ppl ? 250 : 0;
|
||||||
gId("psuMA").style.display = ppl ? 'none' : 'inline';
|
gId("psuMA").style.display = ppl ? 'none' : 'inline';
|
||||||
gId("ppldis").style.display = ppl ? 'inline' : 'none';
|
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)=>{
|
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,x)=>{
|
||||||
var n = String.fromCharCode((x<10?48:55)+x);
|
var n = String.fromCharCode((x<10?48:55)+x);
|
||||||
gId("PSU"+n).style.display = ppl ? "inline" : "none";
|
gId("PSU"+n).style.display = ppl ? "inline" : "none";
|
||||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||||
const c = parseInt(d.Sf["LC"+n].value); //get LED count
|
const c = parseInt(d.Sf["LC"+n].value); //get LED count
|
||||||
i.min = ppl && !(isVir(t) || isAna(t)) ? 250 : 0;
|
i.min = ppl && isDig(t) ? 250 : 0;
|
||||||
if (!abl || isVir(t) || isAna(t)) i.value = 0;
|
if (!abl || !isDig(t)) i.value = 0;
|
||||||
else if (ppl) sumMA += parseInt(i.value,10);
|
else if (ppl) sumMA += parseInt(i.value,10);
|
||||||
else if (sDI) i.value = Math.round(parseInt(d.Sf.MA.value,10)*c/sDI);
|
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
|
if (ppl) d.Sf.MA.value = sumMA; // populate UI ABL value if PPL used
|
||||||
}
|
}
|
||||||
|
// enable and update LED Amps
|
||||||
function enLA(s,n)
|
function enLA(s,n)
|
||||||
{
|
{
|
||||||
|
const abl = d.Sf.ABL.checked;
|
||||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||||
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none";
|
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;
|
if (s.value!=="0") d.Sf["LA"+n].value = s.value; // set value from select object
|
||||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
d.Sf["LA"+n].min = (!isDig(t) || !abl) ? 0 : 1; // set minimum value for validation
|
||||||
}
|
}
|
||||||
function setABL()
|
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)
|
// check if ABL is enabled (max mA entered per output)
|
||||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,n)=>{
|
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
|
// select appropriate LED current
|
||||||
d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((sel,x)=>{
|
d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((sel,x)=>{
|
||||||
sel.value = 0; // set custom
|
sel.value = 0; // set custom
|
||||||
var n = String.fromCharCode((x<10?48:55)+x);
|
var n = String.fromCharCode((x<10?48:55)+x);
|
||||||
switch (parseInt(d.Sf["LA"+n].value)) {
|
if (en)
|
||||||
case 0: break; // disable ABL
|
switch (parseInt(d.Sf["LA"+n].value)) {
|
||||||
case 15: sel.value = 15; break;
|
case 0: break; // disable ABL
|
||||||
case 30: sel.value = 30; break;
|
case 15: sel.value = 15; break;
|
||||||
case 35: sel.value = 35; break;
|
case 30: sel.value = 30; break;
|
||||||
case 55: sel.value = 55; break;
|
case 35: sel.value = 35; break;
|
||||||
case 255: sel.value = 255; break;
|
case 55: sel.value = 55; break;
|
||||||
}
|
case 255: sel.value = 255; break;
|
||||||
enLA(sel,n);
|
}
|
||||||
|
else sel.value = 0;
|
||||||
|
enLA(sel,n); // configure individual limiter
|
||||||
});
|
});
|
||||||
enABL();
|
enABL();
|
||||||
gId('m1').innerHTML = maxM;
|
gId('m1').innerHTML = maxM;
|
||||||
@ -202,7 +212,7 @@
|
|||||||
let gRGBW = false, memu = 0;
|
let gRGBW = false, memu = 0;
|
||||||
let busMA = 0;
|
let busMA = 0;
|
||||||
let sLC = 0, sPC = 0, sDI = 0, maxLC = 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
|
maxB = oMaxB; // TODO make sure we start with all possible buses
|
||||||
let setPinConfig = (n,t) => {
|
let setPinConfig = (n,t) => {
|
||||||
let p0d = "GPIO:";
|
let p0d = "GPIO:";
|
||||||
@ -249,12 +259,12 @@
|
|||||||
var t = parseInt(s.value);
|
var t = parseInt(s.value);
|
||||||
memu += getMem(t, n); // calc memory
|
memu += getMem(t, n); // calc memory
|
||||||
setPinConfig(n,t);
|
setPinConfig(n,t);
|
||||||
gId("abl"+n).style.display = (!ablEN || isVir(t) || isAna(t)) ? "none" : "inline";
|
gId("abl"+n).style.display = (!abl || !isDig(t)) ? "none" : "inline"; // show/hide individual ABL settings
|
||||||
if (change) {
|
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)
|
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
|
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["LA"+n].min = (!isDig(t) || !abl) ? 0 : 1; // set minimum value for LED mA
|
||||||
d.Sf["MA"+n].min = (isVir(t) || isAna(t)) ? 0 : 250;
|
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
|
gId("rf"+n).onclick = mustR(t) ? (()=>{return false}) : (()=>{}); // prevent change change of "Refresh" checkmark when mandatory
|
||||||
gRGBW |= hasW(t); // RGBW checkbox
|
gRGBW |= hasW(t); // RGBW checkbox
|
||||||
@ -294,7 +304,7 @@
|
|||||||
if (s+c > sLC) sLC = s+c; //update total count
|
if (s+c > sLC) sLC = s+c; //update total count
|
||||||
if (c > maxLC) maxLC = c; //max per output
|
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)) 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
|
sDI += c; // summarize digital LED count
|
||||||
let maPL = parseInt(d.Sf["LA"+n].value);
|
let maPL = parseInt(d.Sf["LA"+n].value);
|
||||||
if (maPL == 255) maPL = 12;
|
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 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>
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||||
(c) 2016-2024 Christian Schwinne <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>
|
Server message: <span class="sip"> Response error! </span><hr>
|
||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<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="20">AKST/AKDT (Anchorage)</option>
|
||||||
<option value="21">MX-CST</option>
|
<option value="21">MX-CST</option>
|
||||||
<option value="22">PKT (Pakistan)</option>
|
<option value="22">PKT (Pakistan)</option>
|
||||||
|
<option value="23">BRT (Brasília)</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<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>
|
Current local time is <span class="times">unknown</span>.<br>
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
<h2>WLED Software Update</h2>
|
<h2>WLED Software Update</h2>
|
||||||
<form method='POST' action='./update' id='uf' enctype='multipart/form-data' onsubmit="U()">
|
<form method='POST' action='./update' id='uf' enctype='multipart/form-data' onsubmit="U()">
|
||||||
Installed version: <span class="sip">##VERSION##</span><br>
|
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>
|
<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-->
|
<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>
|
<button type="submit">Update!</button><br>
|
||||||
|
@ -256,7 +256,6 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
|||||||
void setValuesFromSegment(uint8_t s);
|
void setValuesFromSegment(uint8_t s);
|
||||||
void setValuesFromMainSeg();
|
void setValuesFromMainSeg();
|
||||||
void setValuesFromFirstSelectedSeg();
|
void setValuesFromFirstSelectedSeg();
|
||||||
void resetTimebase();
|
|
||||||
void toggleOnOff();
|
void toggleOnOff();
|
||||||
void applyBri();
|
void applyBri();
|
||||||
void applyFinalBri();
|
void applyFinalBri();
|
||||||
@ -411,6 +410,10 @@ class Usermod {
|
|||||||
protected:
|
protected:
|
||||||
// Shim for oappend(), which used to exist in utils.cpp
|
// Shim for oappend(), which used to exist in utils.cpp
|
||||||
template<typename T> static inline void oappend(const T& t) { oappend_shim->print(t); };
|
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 {
|
class UsermodManager {
|
||||||
|
@ -123,6 +123,7 @@ void handleImprovPacket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checksum += next;
|
checksum += next;
|
||||||
|
checksum &= 0xFF;
|
||||||
packetByte++;
|
packetByte++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,24 +194,22 @@ void sendImprovIPRPCResult(ImprovRPCType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendImprovInfoResponse() {
|
void sendImprovInfoResponse() {
|
||||||
const char* bString =
|
char bString[32];
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
"esp8266"
|
strcpy(bString, "esp8266");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#else // ESP32
|
||||||
"esp32-c3"
|
strncpy(bString, ESP.getChipModel(), 31);
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
"esp32-s2"
|
bString[5] = '\0'; // disregard chip revision for classic ESP32
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#else
|
||||||
"esp32-s3";
|
bString[31] = '\0'; // just in case
|
||||||
#else // ESP32
|
#endif
|
||||||
"esp32";
|
strlwr(bString);
|
||||||
#endif
|
#endif
|
||||||
;
|
|
||||||
|
|
||||||
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||||
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||||
char vString[20];
|
char vString[32];
|
||||||
sprintf_P(vString, PSTR("0.15.0-b5/%i"), VERSION);
|
sprintf_P(vString, PSTR("%s/%i"), versionString, VERSION);
|
||||||
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
||||||
|
|
||||||
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
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
|
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;
|
tr = root[F("transition")] | -1;
|
||||||
if (tr >= 0) {
|
if (tr >= 0) {
|
||||||
@ -357,7 +357,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr = root[F("tb")] | -1;
|
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"];
|
JsonObject nl = root["nl"];
|
||||||
nightlightActive = getBoolVal(nl["on"], nightlightActive);
|
nightlightActive = getBoolVal(nl["on"], nightlightActive);
|
||||||
@ -448,21 +448,25 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
handleSet(nullptr, apireq, false); // may set stateChanged
|
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;
|
byte presetToRestore = 0;
|
||||||
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
|
||||||
if (!root[F("pd")].isNull() && stateChanged) {
|
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;
|
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
|
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()) {
|
} else if (!root["ps"].isNull()) {
|
||||||
ps = presetCycCurr;
|
// 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"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
|
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())
|
// b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
|
||||||
presetCycCurr = ps;
|
applyPreset(presetCycCurr, callMode); // async load from file system (only preset ID was specified)
|
||||||
applyPreset(ps, callMode); // async load from file system (only preset ID was specified)
|
|
||||||
return stateResponse;
|
return stateResponse;
|
||||||
}
|
} else presetCycCurr = currentPreset; // restore presetCycCurr
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject playlist = root[F("playlist")];
|
JsonObject playlist = root[F("playlist")];
|
||||||
|
@ -47,17 +47,12 @@ void applyValuesToSelectedSegs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void resetTimebase()
|
|
||||||
{
|
|
||||||
strip.timebase = 0 - millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void toggleOnOff()
|
void toggleOnOff()
|
||||||
{
|
{
|
||||||
if (bri == 0)
|
if (bri == 0)
|
||||||
{
|
{
|
||||||
bri = briLast;
|
bri = briLast;
|
||||||
|
strip.restartRuntime();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
briLast = bri;
|
briLast = bri;
|
||||||
@ -123,7 +118,7 @@ void stateUpdated(byte callMode) {
|
|||||||
nightlightStartTime = millis();
|
nightlightStartTime = millis();
|
||||||
}
|
}
|
||||||
if (briT == 0) {
|
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;
|
if (bri > 0) briLast = bri;
|
||||||
|
@ -36,8 +36,9 @@ Timezone* tz;
|
|||||||
#define TZ_ANCHORAGE 20
|
#define TZ_ANCHORAGE 20
|
||||||
#define TZ_MX_CENTRAL 21
|
#define TZ_MX_CENTRAL 21
|
||||||
#define TZ_PAKISTAN 22
|
#define TZ_PAKISTAN 22
|
||||||
|
#define TZ_BRASILIA 23
|
||||||
|
|
||||||
#define TZ_COUNT 23
|
#define TZ_COUNT 24
|
||||||
#define TZ_INIT 255
|
#define TZ_INIT 255
|
||||||
|
|
||||||
byte tzCurrent = TZ_INIT; //uninitialized
|
byte tzCurrent = TZ_INIT; //uninitialized
|
||||||
@ -135,6 +136,10 @@ static const std::pair<TimeChangeRule, TimeChangeRule> TZ_TABLE[] PROGMEM = {
|
|||||||
/* TZ_PAKISTAN */ {
|
/* TZ_PAKISTAN */ {
|
||||||
{Last, Sun, Mar, 1, 300}, //Pakistan Standard Time = UTC + 5 hours
|
{Last, Sun, Mar, 1, 300}, //Pakistan Standard Time = UTC + 5 hours
|
||||||
{Last, Sun, Mar, 1, 300}
|
{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.
|
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
|
||||||
#endif
|
#endif
|
||||||
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
|
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.
|
// 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)
|
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
// strapping pins: 0, 45 & 46
|
// strapping pins: 0, 45 & 46
|
||||||
|
@ -143,6 +143,7 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID,
|
|||||||
|
|
||||||
void handlePresets()
|
void handlePresets()
|
||||||
{
|
{
|
||||||
|
byte presetErrFlag = ERR_NONE;
|
||||||
if (presetToSave) {
|
if (presetToSave) {
|
||||||
strip.suspend();
|
strip.suspend();
|
||||||
doSaveState();
|
doSaveState();
|
||||||
@ -166,14 +167,16 @@ void handlePresets()
|
|||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
||||||
deserializeJson(*pDoc,tmpRAMbuffer);
|
deserializeJson(*pDoc,tmpRAMbuffer);
|
||||||
errorFlag = ERR_NONE;
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#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>();
|
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
|
//HTTP API commands
|
||||||
const char* httpwin = fdo["win"];
|
const char* httpwin = fdo["win"];
|
||||||
if (httpwin) {
|
if (httpwin) {
|
||||||
|
@ -120,10 +120,8 @@ private:
|
|||||||
|
|
||||||
void encodeLightId(uint8_t idx, char* out)
|
void encodeLightId(uint8_t idx, char* out)
|
||||||
{
|
{
|
||||||
uint8_t mac[6];
|
String mymac = WiFi.macAddress();
|
||||||
WiFi.macAddress(mac);
|
sprintf_P(out, PSTR("%02X:%s:AB-%02X"), idx, mymac.c_str(), idx);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct 'globally unique' Json dict key fitting into signed int
|
// construct 'globally unique' Json dict key fitting into signed int
|
||||||
|
@ -219,6 +219,7 @@ void WLED::loop()
|
|||||||
busConfigs[i] = nullptr;
|
busConfigs[i] = nullptr;
|
||||||
}
|
}
|
||||||
strip.finalizeInit(); // also loads default ledmap if present
|
strip.finalizeInit(); // also loads default ledmap if present
|
||||||
|
BusManager::setBrightness(bri); // fix re-initialised bus' brightness #4005
|
||||||
if (aligned) strip.makeAutoSegments();
|
if (aligned) strip.makeAutoSegments();
|
||||||
else strip.fixInvalidSegments();
|
else strip.fixInvalidSegments();
|
||||||
BusManager::setBrightness(bri); // fix re-initialised bus' brightness
|
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_QOUT: DEBUG_PRINT(F("(QOUT)"));break;
|
||||||
case FM_DIO: DEBUG_PRINT(F("(DIO)")); break;
|
case FM_DIO: DEBUG_PRINT(F("(DIO)")); break;
|
||||||
case FM_DOUT: DEBUG_PRINT(F("(DOUT)"));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;
|
default: break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
/*
|
/*
|
||||||
Main sketch, global variable declarations
|
Main sketch, global variable declarations
|
||||||
@title WLED project sketch
|
@title WLED project sketch
|
||||||
@version 0.15.0-b5
|
@version 0.15.0-b7
|
||||||
@author Christian Schwinne
|
@author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// 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
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -36,12 +36,13 @@
|
|||||||
#undef WLED_ENABLE_ADALIGHT // disable has priority over enable
|
#undef WLED_ENABLE_ADALIGHT // disable has priority over enable
|
||||||
#endif
|
#endif
|
||||||
//#define WLED_ENABLE_DMX // uses 3.5kb
|
//#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
|
#ifndef WLED_DISABLE_LOXONE
|
||||||
#define WLED_ENABLE_LOXONE // uses 1.2kb
|
#define WLED_ENABLE_LOXONE // uses 1.2kb
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_DISABLE_WEBSOCKETS
|
#ifndef WLED_DISABLE_WEBSOCKETS
|
||||||
#define WLED_ENABLE_WEBSOCKETS
|
#define WLED_ENABLE_WEBSOCKETS
|
||||||
|
#else
|
||||||
|
#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
||||||
@ -316,8 +317,6 @@ WLED_GLOBAL bool rlyOpenDrain _INIT(RLYODRAIN);
|
|||||||
constexpr uint8_t hardwareTX = 1;
|
constexpr uint8_t hardwareTX = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//WLED_GLOBAL byte presetToApply _INIT(0);
|
|
||||||
|
|
||||||
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
|
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)
|
// 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));
|
editHandler = &server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
|
||||||
#endif
|
#endif
|
||||||
#else
|
#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);
|
serveMessage(request, 501, FPSTR(s_notimplemented), F("The FS editor is disabled in this build."), 254);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} 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);
|
serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_cfg), 254);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -427,11 +427,11 @@ void initServer()
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#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);
|
request->send_P(200, FPSTR(CONTENT_TYPE_HTML), PAGE_dmxmap , dmxProcessor);
|
||||||
});
|
});
|
||||||
#else
|
#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);
|
serveMessage(request, 501, FPSTR(s_notimplemented), F("DMX support is not enabled in this build."), 254);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
@ -173,7 +173,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
|||||||
char fpass[l+1]; //fill password field with ***
|
char fpass[l+1]; //fill password field with ***
|
||||||
fpass[l] = 0;
|
fpass[l] = 0;
|
||||||
memset(fpass,'*',l);
|
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,
|
multiWiFi[n].clientSSID,
|
||||||
fpass,
|
fpass,
|
||||||
(uint32_t) multiWiFi[n].staticIP, // explicit cast required as this is a struct
|
(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]);
|
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
#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
|
#endif
|
||||||
printSetClassElementHTML(settingsScript,PSTR("sip"),0,s);
|
printSetClassElementHTML(settingsScript,PSTR("sip"),0,s);
|
||||||
} else
|
} else
|
||||||
@ -499,7 +499,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
|||||||
#endif
|
#endif
|
||||||
printSetFormValue(settingsScript,PSTR("BD"),serialBaud);
|
printSetFormValue(settingsScript,PSTR("BD"),serialBaud);
|
||||||
#ifndef WLED_ENABLE_ADALIGHT
|
#ifndef WLED_ENABLE_ADALIGHT
|
||||||
settingsScript.print(F("toggle('Serial);"));
|
settingsScript.print(F("toggle('Serial');"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user