Compare commits

..

104 Commits

Author SHA1 Message Date
Will Tatam
faadb67eb0 update changelog for 2412100 2024-12-10 20:20:28 +00:00
Will Tatam
a111a2e7a1 update version to 0.15.0 2024-12-10 20:13:12 +00:00
netmindz
32864d8986 update version to 0.15.0 2024-12-10 18:54:39 +00:00
netmindz
d7bebc2659 Merge pull request #4360 from euphi/patch-1
Usermod BME280: Fix "Unit of Measurement" for temperature
2024-12-10 08:07:24 +00:00
Blaž Kristan
af410ae2d0 WiFi reconnect bugfix
- additional debug info
2024-12-09 23:06:21 +00:00
Will Tatam
1891cc816f Merge branch '0_15_0' of https://github.com/Aircoookie/WLED into 0_15_0 2024-12-09 09:33:33 +00:00
Ian Hubbertz
9a4073e606 Fix "Unit of Measurement" for BME280 temperature
The Unit of Measurement ("tempScale") of the MQTT message is set for each published measurement - but not for the homeassistant discovery.

Thus, openhab (and mabye other systems?) don't recognize the value as "Number" - so it uses String instead. This is somehow annoying when trying to configure the sensor channel to be linked to an existing item in OpenHAB.
(Items that are created automatically or with "Add point to model" can be configured in a way that the String is transformed to Number or Number:Temperature, but existing Items cannot be linked).

When a "Unit of Measurement" is set in HomeAssistant discovery, the HA binding of OpenHAB notices that the MQTT String is a number and automatically converts it.
2024-12-07 21:33:46 +01:00
Damian Schneider
b78229d1e2 Fix update for #4193 (twinkle fox & cat)
- previous fix worked but there was still an overflow after some time passed. there were still missing roll-overs apparently: reverting these two variables back to 16bit/8bit should fix it for good.
2024-12-05 06:49:17 +01:00
Damian Schneider
71b242874f Fix for #4193 (twinkle fox & cat) 2024-12-04 20:39:19 +01:00
Will Tatam
9328e6faca Merge branch '0_15_0' of https://github.com/Aircoookie/WLED into 0_15_0 2024-11-30 12:07:46 +00:00
netmindz
bbacc2daae Merge pull request #4287 from netmindz/v0.15.0-rcX
0.15.0-rc1
2024-11-30 11:42:46 +00:00
Will Tatam
3e22f9cabb Merge branch '0_15' into 0_15_0 2024-11-30 11:39:13 +00:00
Will Miles
a121f5b61b Merge pull request #4286 from blazoncek/xml-bugfix
xml comma bugfix + few string optimisations
2024-11-28 09:48:29 -05:00
Frank
251062170e Merge pull request #4324 from dosipod/0_15
Update settings_sec.htm [Fix the  warning text and Backup presets button misalignment]
2024-11-28 12:22:46 +01:00
Damian Schneider
92e59af4d8 Merge pull request #4181 from DedeHai/0_15_trig_math
Added integer based `sin()/cos()` functions, changed all trig functions to wled_math
2024-11-27 22:27:56 +01:00
Damian Schneider
fa4c23b76e minor improvement 2024-11-27 22:23:48 +01:00
Damian Schneider
a0a46850f5 Merge remote-tracking branch 'upstream/0_15' into 0_15_trig_math 2024-11-27 22:22:50 +01:00
Damian Schneider
4cd0563a93 changed 90° offset to hex, fixed potential bug in FX using sin/cos with incrementing number
- sin/cos calls with incrementing numbers can lead to bad outcomes, the functions (_approx or original sinf/cosf) return bad values for very large float inputs
2024-11-27 21:53:32 +01:00
netmindz
b83f0f461c Merge pull request #4263 from DedeHai/palette_FX_fix
fixed palette FX to more closely match original 1D version
2024-11-27 19:48:00 +00:00
Will Miles
685ad83d4b PolyBus: Clarify use of clock_kHz
While not used by most bus types, it's not an optional parameter.
2024-11-27 19:36:16 +00:00
Will Miles
62ddb18a1a BusDigital::begin: Pass clock rate argument
Fixes bug introduced by #4312.
2024-11-27 19:36:01 +00:00
netmindz
3668ede0ff Merge pull request #4327 from willmmiles/4312-missing-clock
Fix missing clock setting introduce by #4312
2024-11-27 19:35:19 +00:00
Blaž Kristan
6a12378475 Fix for #4321 2024-11-27 19:33:29 +00:00
netmindz
945584384a Merge pull request #4328 from blazoncek/clarify
Fix for #4321 - unclear use of comma operator
2024-11-27 19:31:53 +00:00
Blaž Kristan
b1dd27b516 Fix for #4321 2024-11-27 16:08:10 +01:00
Will Miles
dcba1aad10 PolyBus: Clarify use of clock_kHz
While not used by most bus types, it's not an optional parameter.
2024-11-27 09:05:10 -05:00
Will Miles
acc8b9cdbc BusDigital::begin: Pass clock rate argument
Fixes bug introduced by #4312.
2024-11-27 09:00:25 -05:00
Blaž Kristan
d26b3108da Fix for #4300 2024-11-27 11:04:52 +00:00
Will Tatam
6cbdd825eb Revert "Cache always misses for tags, so save space and do not save back"
This reverts commit cc55f6015d.
2024-11-27 10:59:23 +00:00
Will Tatam
cc55f6015d Cache always misses for tags, so save space and do not save back 2024-11-27 10:56:53 +00:00
Will Tatam
c89e4576b4 Dedicated release workflow 2024-11-27 10:42:38 +00:00
Will Tatam
bc79f44a26 workflow refactor to used shared build file 2024-11-27 10:42:29 +00:00
Will Tatam
7ece14ff3f rename workflow ready for workflow refactor 2024-11-27 10:42:19 +00:00
Will Tatam
95718ab6ec Dedicated release workflow 2024-11-27 10:36:18 +00:00
Will Tatam
feab27295d workflow refactor to used shared build file 2024-11-27 10:36:18 +00:00
Will Tatam
ca176c7549 rename workflow ready for workflow refactor 2024-11-27 10:36:18 +00:00
netmindz
f8a7a0d6e8 Merge pull request #4326 from blazoncek/com-fix
Fix for #4300 - removal of color order override
2024-11-27 10:01:22 +00:00
Damian Schneider
1a8aaa3b26 Speed improvements, commented legacy _t trig functions
- speed improvement: by default M_TWOPI is treated as a double float
- directly calling sin16_t in cos_approx() saves a lot of overhead
2024-11-26 20:32:39 +01:00
Blaž Kristan
cd1c13b4b1 Fix for #4300 2024-11-26 19:35:15 +01:00
AlDIY
d87c5035dd Update settings_sec.htm 2024-11-26 19:33:22 +03:00
netmindz
77967731d5 Merge pull request #4227 from ingDIY/pr_branch
fixed refs to removed usermod USERMOD_FOUR_LINE_DISPLAY
2024-11-26 09:15:31 +00:00
netmindz
0b54034470 Merge pull request #4284 from blazoncek/search-keep
Keep selected FX visible while searching
2024-11-26 09:10:14 +00:00
Will Tatam
0b3643132b Update to 2411250 2024-11-25 23:47:41 +00:00
Will Tatam
a5693fbf8d Merge branch '0_15_0' into v0.15.0-rcX 2024-11-25 23:45:34 +00:00
maxi4329
5c5b70f52b version changed to 20 2024-11-25 23:34:27 +00:00
maxi4329
ae97e388a6 indened formating 2024-11-25 23:34:20 +00:00
maxi4329
37cddcaacc specified required nodejs ver 2024-11-25 23:34:13 +00:00
Will Miles
a1b332fc78 handleSet: Fix incorrect response generation
Don't generate a response if there's no HTTP request.

Fixes #4269
2024-11-25 23:33:53 +00:00
Frank
86d7c24513 rename delay -> frameDelay
Avoiding name collisions with the 'delay' function.
2024-11-25 23:32:27 +00:00
Damian Schneider
b28add3b8b Added define for bitshift, removed dithering
dithering is not really needed, the FPS_MULTIPLIER is a much better option.
2024-11-25 23:31:17 +00:00
Damian Schneider
5fd3a513a4 bugfix
bitshift was still set from testing, forgot to update
2024-11-25 23:31:08 +00:00
Damian Schneider
b98a8a10b0 improved FPS calc resolution, added averaging & multiplier compileflags
Fixed point calculation for improved accuracy, dithering in debug builds only.
Averaging and optional multiplier can be set as compile flags, example for speed testing with long averaging and a 10x multiplier:

-D FPS_CALC_AVG=200
-D FPS_MULTIPLIER=10

The calculation resolution is limited (9.7bit fixed point) so values larger than 200 can hit resolution limit and get stuck before reaching the final value.

If WLED_DEBUG is defined, dithering is added to the returned value so sub-frame accuracy is possible in post-processingwithout enabling the multiplier.
2024-11-25 23:30:59 +00:00
netmindz
2bee2793ef Merge pull request #4309 from netmindz/release-name-fix
Fix release name macro expansion
2024-11-25 23:12:04 +00:00
netmindz
2f6fa66f4d Merge pull request #4309 from netmindz/release-name-fix
Fix release name macro expansion
2024-11-25 23:04:22 +00:00
netmindz
8ad2583785 Merge pull request #4309 from netmindz/release-name-fix
Fix release name macro expansion
2024-11-25 23:00:56 +00:00
Will Tatam
dd533a9ab4 Update sample WLED_RELEASE_NAME 2024-11-25 23:00:31 +00:00
Frank
5b989adebc Allow TV Simulator on single LED segments
I've checked the code - nothing preventing the effect to run with SEGLEN=1
2024-11-25 15:27:53 +01:00
Will Tatam
5d38acd787 Update CHANGELOG 2024-11-24 21:04:50 +00:00
Will Tatam
e607fcb5c5 Merge branch '0_15_0' into v0.15.0-rcX 2024-11-24 21:04:08 +00:00
Frank
8a18555ae4 Merge pull request #4243 from MoonModules/AC_0_15_S3-WROOM2
Add support for ESP32-S3 WROOM-2 (solves #4099)
2024-11-24 20:49:49 +00:00
netmindz
beb709dc8f Merge pull request #4312 from willmmiles/mixed-led-crash
Defer calling begin() on buses
2024-11-24 20:46:45 +00:00
Will Tatam
20f8d3c8a9 Builds without WLED_RELEASE_NAME should be called Custom 2024-11-24 15:26:30 +00:00
Will Tatam
0c77dbb7ea cleanup WLED_RELEASE_NAME only if present 2024-11-24 13:55:23 +00:00
netmindz
2448e2ae3b Merge pull request #4312 from willmmiles/mixed-led-crash
Defer calling begin() on buses
2024-11-24 13:45:26 +00:00
Will Miles
d53d7aa2e2 Defer calling begin() on digital buses
NeoPixelBus requires that all parallel I2S bus members be constructed
before any of them call Begin().  Implement this by deferring the
call to the end of bus construction.

Fixes #4301.
2024-11-23 12:34:06 -05:00
Will Tatam
7a58c69a80 Stip \" from WLED_RELEASE_NAME 2024-11-23 16:50:34 +00:00
Will Tatam
0be1df7ee8 Stip \" from WLED_RELEASE_NAME 2024-11-23 16:46:41 +00:00
Will Tatam
1082c85789 Fix WLED_RELEASE_NAME=ESP32-S3_WROOM-2 2024-11-23 16:37:54 +00:00
Will Tatam
568d2edd96 Remove TOSTRING for releaseString and add quotes to WLED_RELEASE_NAME 2024-11-23 16:37:03 +00:00
Will Tatam
6aef0e145c Remove TOSTRING for releaseString and add quotes to WLED_RELEASE_NAME 2024-11-23 16:31:07 +00:00
Damian Schneider
32dc54ce72 reverted rotation scale, offset only on static rotation, inverted shift direction
- inverting the shift direction in signed int is computationally safe as it is cast into an uint8_t and it matches the original FX in 1D
2024-11-22 08:43:45 +01:00
Frank
548736f432 SparkFunDMX fix for possible array bounds violation in DMX.write
Align with code in espdmx.cpp
2024-11-21 22:50:55 +01:00
netmindz
89d587e7dd Merge pull request #4296 from WouterGritter/mqtt-fix-settings-input-maxlength
Introduce printSetInputMaxlength to properly set an inputs maxlength …
2024-11-21 18:25:26 +00:00
Wouter Gritter
5c8b2ebf7a maxlength -> maxLength to fix this attribute not being modified correctly 2024-11-21 12:04:01 +01:00
Wouter Gritter
5ac8ba9bae Revert "Introduce printSetInputMaxlength to properly set an inputs maxlength variable"
This reverts commit 49fb16e2c6.
2024-11-21 12:02:55 +01:00
Wouter Gritter
49fb16e2c6 Introduce printSetInputMaxlength to properly set an inputs maxlength variable 2024-11-21 10:52:22 +01:00
Frank
545bfa6ef9 Merge pull request #4289 from willmmiles/exploding_fireworks_overrun
Fix array overflow in exploding_fireworks
2024-11-18 22:18:19 +01:00
Blaž Kristan
c596b5a17d Bugfix 2024-11-17 14:31:23 +01:00
Blaž Kristan
84dd26c1b7 Some more optimisations. 2024-11-17 10:47:09 +01:00
Will Miles
a765903a41 Fix array overflow in exploding_fireworks
Attempt to allocate enough room for the "minimum" sparks; and ensure
that we never overrun the allocated array size.

Fixes #4120
2024-11-16 17:10:30 -05:00
Blaž Kristan
25ab381916 Merge pull request #46 from w00000dy/search-keep-mod
Move selected to the bottom in search result
2024-11-16 22:54:11 +01:00
Woody
4d3df5d98f Fix default/solid not being first 2024-11-16 20:12:29 +01:00
Woody
6fe2024542 move selected to the bottom in search result 2024-11-16 19:53:10 +01:00
netmindz
4cd4c13b2d Merge pull request #4267 from w00000dy/space
Fix problem with spaces
2024-11-16 07:14:34 +00:00
Will Tatam
d2d56ebbd2 0.15.0-rc1 2024-11-15 20:27:30 +00:00
Blaž Kristan
86be5df475 xml comma bugfix + few optimisations 2024-11-15 19:03:46 +01:00
Blaž Kristan
8c5e0cd4e9 Keep selected FX while searching 2024-11-15 16:01:58 +01:00
netmindz
a9b0b8adc8 Merge pull request #4229 from maxi4329/snodejsversion
specified required nodejs version
2024-11-13 09:20:27 +00:00
Will Miles
ba01cb82f7 Merge pull request #4271 from Aircoookie/4269-crashes-when-using-http-api-within-mqtt
Fix for #4269
2024-11-11 19:53:06 -05:00
Woody
5de86d3d91 fix problem with spaces 2024-11-09 23:55:09 +01:00
Damian Schneider
536444f9d1 fixed palette FX to more closely match original 1D version
- rotation scale is now exactly 180° (divide slider input by 255 instead of 256)
- removed shift offset: offset is now zero at slider 0, to hit 128 on touch input devices is really hard
- added a 90° shift to input rotation, enabling to rotate from 0 to 180° instead of +90 to -90 (which is not useful in 1D)
- changed default settings values to more closely match the old 1D effect
2024-11-09 16:38:18 +01:00
Damian Schneider
271a07a7d6 Merge pull request #4250 from DedeHai/FPS_calc_averaging
Fixed & improved FPS calculation
2024-11-05 08:52:42 +01:00
Damian Schneider
4634ace74e Added define for bitshift, removed dithering
dithering is not really needed, the FPS_MULTIPLIER is a much better option.
2024-11-04 19:33:42 +01:00
Damian Schneider
3733715184 bugfix
bitshift was still set from testing, forgot to update
2024-11-04 17:38:45 +01:00
Damian Schneider
bf37ac53a3 improved FPS calc resolution, added averaging & multiplier compileflags
Fixed point calculation for improved accuracy, dithering in debug builds only.
Averaging and optional multiplier can be set as compile flags, example for speed testing with long averaging and a 10x multiplier:

-D FPS_CALC_AVG=200
-D FPS_MULTIPLIER=10

The calculation resolution is limited (9.7bit fixed point) so values larger than 200 can hit resolution limit and get stuck before reaching the final value.

If WLED_DEBUG is defined, dithering is added to the returned value so sub-frame accuracy is possible in post-processingwithout enabling the multiplier.
2024-11-04 08:10:05 +01:00
ingDIY
fa053b7e60 Update platformio_override.sample.ini
fixed back U8g2 version
2024-10-29 01:14:02 +01:00
maxi4329
d05c358fd2 version changed to 20 2024-10-27 11:13:56 +01:00
maxi4329
7c6bc5c421 indened formating 2024-10-26 21:07:17 +02:00
maxi4329
798c398f23 specified required nodejs ver 2024-10-26 20:33:38 +02:00
ingDIY
dcfdca6351 cleaned up old references to USE_ALT_DISPlAY that aren't used anymore in the code/source files; fixed readme.md documents and updated instructions; removed referencies to old usermods; fixed invalid filenames; removed referencies to old usermods; checked cycle options; splitted and fixed platformio_override.sample.ini; 2024-10-25 12:14:37 +02:00
Damian Schneider
98a6907976 cleanup and improvement to sin_appros()
-replaced all PI references with M_PI version
-there is no need to do the angle-modulo in float, casting it to an integer does the same BUT it has to be cast to an `int` first, see comment.
2024-10-16 19:53:58 +02:00
Damian Schneider
5e29f2c1b7 fixed atan2_t
approximation was incorrect, now doing it right.
also removed hypotf() from octopus, saving a little flash.
2024-10-15 20:11:33 +02:00
Damian Schneider
f301296f1e added rounding to sin8_t
thx to @softhack007
2024-10-06 21:27:58 +02:00
Damian Schneider
7b855c851d Added integer based sin()/cos() functions, changed all trig functions to wled_math
- `sin16_t() / cos16_t()` are faster and more accurate than fastled versions
- `sin_approx() / cos_approx()` are float wrappers for `sin16_t() / cos16_t()` and are accurate enough to replace `sinf()/cosf()`
- `atan2()` is used only in octopus to calculate center offset, new approximated version saves flash
- `tan(), atan(), asin(), acos(), floor(), fmod()` are used only for sunrise/sunset calculation, using wled_math version saves flash
- `beatsinx()` replacements are to make use of new `sin16_t()/sin8_t()` functions to reduce flash size
- Extensively tested surnise/sunset calculation: deviation is 1min. max
- Tested some of the relevant FX and found no visual difference: Julia, 2D Drift, Drift Rose, Ghost rider, Rotozoomer, Palette, Arc 1D expansion
- total flash savings: 7.4k
2024-10-05 12:32:41 +02:00
34 changed files with 614 additions and 437 deletions

80
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
name: WLED Build
# Only included into other workflows
on:
workflow_call:
jobs:
get_default_envs:
name: Gather Environments
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Get default environments
id: envs
run: |
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
outputs:
environments: ${{ steps.envs.outputs.environments }}
build:
name: Build Enviornments
runs-on: ubuntu-latest
needs: get_default_envs
strategy:
fail-fast: false
matrix:
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
cache: 'npm'
- run: npm ci
- name: Cache PlatformIO
uses: actions/cache@v4
with:
path: |
~/.platformio/.cache
~/.buildcache
build_output
key: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }}
restore-keys: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Build firmware
run: pio run -e ${{ matrix.environment }}
- uses: actions/upload-artifact@v4
with:
name: firmware-${{ matrix.environment }}
path: |
build_output/release/*.bin
build_output/release/*_ESP02*.bin.gz
testCdata:
name: Test cdata.js
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
- run: npm ci
- run: npm test

28
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: WLED Release CI
on:
push:
tags:
- '*'
jobs:
wled_build:
uses: ./.github/workflows/build.yml
release:
name: Create Release
runs-on: ubuntu-latest
needs: wled_build
steps:
- uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Create draft release
uses: softprops/action-gh-release@v1
with:
draft: True
files: |
*.bin
*.bin.gz

View File

@@ -1,94 +1,11 @@
name: WLED CI
on: [push, pull_request]
on:
push:
branches:
- '*'
pull_request:
jobs:
get_default_envs:
name: Gather Environments
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Get default environments
id: envs
run: |
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
outputs:
environments: ${{ steps.envs.outputs.environments }}
build:
name: Build Enviornments
runs-on: ubuntu-latest
needs: get_default_envs
strategy:
fail-fast: false
matrix:
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
cache: 'npm'
- run: npm ci
- name: Cache PlatformIO
uses: actions/cache@v4
with:
path: |
~/.platformio/.cache
~/.buildcache
build_output
key: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }}
restore-keys: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Build firmware
run: pio run -e ${{ matrix.environment }}
- uses: actions/upload-artifact@v4
with:
name: firmware-${{ matrix.environment }}
path: |
build_output/release/*.bin
build_output/release/*_ESP02*.bin.gz
release:
name: Create Release
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Create draft release
uses: softprops/action-gh-release@v1
with:
draft: True
files: |
*.bin
*.bin.gz
testCdata:
name: Test cdata.js
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
- run: npm ci
- run: npm test
wled_build:
uses: ./.github/workflows/build.yml

View File

@@ -1,5 +1,23 @@
## WLED changelog
#### Build 2412100
- WLED 0.15.0 release
- Usermod BME280: Fix "Unit of Measurement" for temperature
- WiFi reconnect bugfix (@blazoncek)
#### Build 2411250
- WLED 0.15.0-rc1 release
- Add support for esp32S3_wroom2 (#4243 by @softhack007)
- Fix mixed LED SK6812 and ws2812b booloop (#4301 by @willmmiles)
- Improved FPS calculation (by DedeHai)
- Fix crashes when using HTTP API within MQTT (#4269 by @willmmiles)
- Fix array overflow in exploding_fireworks (#4120 by @willmmiles)
- Fix MQTT topic buffer length (#4293 by @WouterGritter)
- Fix SparkFunDMX fix for possible array bounds violation in DMX.write (by @softhack007)
- Allow TV Simulator on single LED segments (by @softhack007)
- Fix WLED_RELEASE_NAME (by @netmindz)
#### Build 2410270
- WLED 0.15.0-b7 release
- Re-license the WLED project from MIT to EUPL (#4194 by @Aircoookie)

9
package-lock.json generated
View File

@@ -1,18 +1,21 @@
{
"name": "wled",
"version": "0.15.0-b7",
"version": "0.15.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wled",
"version": "0.15.0-b7",
"version": "0.15.0",
"license": "ISC",
"dependencies": {
"clean-css": "^5.3.3",
"html-minifier-terser": "^7.2.0",
"inliner": "^1.13.1",
"nodemon": "^3.0.2"
"nodemon": "^3.1.7"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@jridgewell/gen-mapping": {

View File

@@ -1,6 +1,6 @@
{
"name": "wled",
"version": "0.15.0-b7",
"version": "0.15.0",
"description": "Tools for WLED project",
"main": "tools/cdata.js",
"directories": {
@@ -27,5 +27,8 @@
"html-minifier-terser": "^7.2.0",
"inliner": "^1.13.1",
"nodemon": "^3.1.7"
},
"engines": {
"node": ">=20.0.0"
}
}

View File

@@ -19,8 +19,9 @@ def _create_dirs(dirs=["map", "release", "firmware"]):
os.makedirs(os.path.join(OUTPUT_DIR, d), exist_ok=True)
def create_release(source):
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
if release_name:
release_name_def = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
if release_name_def:
release_name = release_name_def.replace("\\\"", "")
version = _get_cpp_define_value(env, "WLED_VERSION")
release_file = os.path.join(OUTPUT_DIR, "release", f"WLED_{version}_{release_name}.bin")
release_gz_file = release_file + ".gz"

View File

@@ -345,7 +345,7 @@ platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP8266 #-DWLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266\" #-DWLED_DISABLE_2D
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
@@ -354,13 +354,13 @@ extends = env:nodemcuv2
;; using platform version and build options from WLED 0.14.0
platform = ${esp8266.platform_compat}
platform_packages = ${esp8266.platform_packages_compat}
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP8266_compat #-DWLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP8266_compat\" #-DWLED_DISABLE_2D
;; lib_deps = ${esp8266.lib_deps_compat} ;; experimental - use older NeoPixelBus 2.7.9
[env:nodemcuv2_160]
extends = env:nodemcuv2
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP8266_160 #-DWLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP8266_160\" #-DWLED_DISABLE_2D
-D USERMOD_AUDIOREACTIVE
[env:esp8266_2m]
@@ -369,7 +369,7 @@ platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02\"
lib_deps = ${esp8266.lib_deps}
[env:esp8266_2m_compat]
@@ -377,12 +377,12 @@ extends = env:esp8266_2m
;; using platform version and build options from WLED 0.14.0
platform = ${esp8266.platform_compat}
platform_packages = ${esp8266.platform_packages_compat}
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP02_compat #-DWLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP02_compat\" #-DWLED_DISABLE_2D
[env:esp8266_2m_160]
extends = env:esp8266_2m
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02_160
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP02_160\"
-D USERMOD_AUDIOREACTIVE
[env:esp01_1m_full]
@@ -391,7 +391,7 @@ platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP01\" -D WLED_DISABLE_OTA
; -D WLED_USE_REAL_MATH ;; may fix wrong sunset/sunrise times, at the cost of 7064 bytes FLASH and 975 bytes RAM
lib_deps = ${esp8266.lib_deps}
@@ -400,12 +400,12 @@ extends = env:esp01_1m_full
;; using platform version and build options from WLED 0.14.0
platform = ${esp8266.platform_compat}
platform_packages = ${esp8266.platform_packages_compat}
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=ESP01_compat -D WLED_DISABLE_OTA #-DWLED_DISABLE_2D
build_flags = ${common.build_flags} ${esp8266.build_flags_compat} -D WLED_RELEASE_NAME=\"ESP01_compat\" -D WLED_DISABLE_OTA #-DWLED_DISABLE_2D
[env:esp01_1m_full_160]
extends = env:esp01_1m_full
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_DISABLE_OTA
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=\"ESP01_160\" -D WLED_DISABLE_OTA
-D USERMOD_AUDIOREACTIVE
; -D WLED_USE_REAL_MATH ;; may fix wrong sunset/sunrise times, at the cost of 7064 bytes FLASH and 975 bytes RAM
@@ -414,7 +414,7 @@ board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32.lib_deps}
${esp32.AR_lib_deps}
@@ -426,7 +426,7 @@ board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_8M #-D WLED_DISABLE_BROWNOUT_DET
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_8M\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
@@ -442,7 +442,7 @@ board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_16M #-D WLED_DISABLE_BROWNOUT_DET
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_16M\" #-D WLED_DISABLE_BROWNOUT_DET
${esp32.AR_build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
@@ -458,7 +458,7 @@ board_build.flash_mode = dio
;platform = ${esp32.platform}
;platform_packages = ${esp32.platform_packages}
;build_unflags = ${common.build_unflags}
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32_audioreactive #-D WLED_DISABLE_BROWNOUT_DET
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_audioreactive\" #-D WLED_DISABLE_BROWNOUT_DET
; ${esp32.AR_build_flags}
;lib_deps = ${esp32.lib_deps}
; ${esp32.AR_lib_deps}
@@ -473,7 +473,7 @@ platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
${esp32.AR_build_flags}
lib_deps = ${esp32.lib_deps}
@@ -489,7 +489,7 @@ board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = ${esp32.extended_partitions}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_WROVER
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_WROVER\"
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; Older ESP32 (rev.<3) need a PSRAM fix (increases static RAM used) https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html
-D DATA_PINS=25
${esp32.AR_build_flags}
@@ -503,7 +503,7 @@ platform_packages = ${esp32c3.platform_packages}
framework = arduino
board = esp32-c3-devkitm-1
board_build.partitions = ${esp32.default_partitions}
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=ESP32-C3
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-C3\"
-D WLED_WATCHDOG_TIMEOUT=0
-DLOLIN_WIFI_FIX ; seems to work much better with this
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
@@ -520,7 +520,7 @@ platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_16MB_opi
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_16MB_opi\"
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
@@ -543,7 +543,7 @@ platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB_opi
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_8MB_opi\"
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
@@ -565,7 +565,7 @@ 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
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")
@@ -590,7 +590,7 @@ platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_4M_qspi
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S3_4M_qspi\"
-DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
-DLOLIN_WIFI_FIX ; seems to work much better with this
@@ -611,7 +611,7 @@ board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = qio
board_build.f_flash = 80000000L
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=\"ESP32-S2\"
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MSC_ON_BOOT=0
-DARDUINO_USB_DFU_ON_BOOT=0

View File

@@ -37,7 +37,7 @@ build_flags = ${common.build_flags} ${esp8266.build_flags}
; *** To use the below defines/overrides, copy and paste each onto it's own line just below build_flags in the section above.
;
; Set a release name that may be used to distinguish required binary for flashing
; -D WLED_RELEASE_NAME=ESP32_MULTI_USREMODS
; -D WLED_RELEASE_NAME=\"ESP32_MULTI_USREMODS\"
;
; disable specific features
; -D WLED_DISABLE_OTA
@@ -111,7 +111,6 @@ build_flags = ${common.build_flags} ${esp8266.build_flags}
;
; Use 4 Line Display usermod with SPI display
; -D USERMOD_FOUR_LINE_DISPLAY
; -D USE_ALT_DISPlAY # mandatory
; -DFLD_SPI_DEFAULT
; -D FLD_TYPE=SSD1306_SPI64
; -D FLD_PIN_CLOCKSPI=14
@@ -377,7 +376,6 @@ build_flags = ${common.build_flags} ${esp32.build_flags}
-D USERMOD_DALLASTEMPERATURE
-D USERMOD_FOUR_LINE_DISPLAY
-D TEMPERATURE_PIN=23
-D USE_ALT_DISPlAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI
-D USERMOD_AUDIOREACTIVE
lib_deps = ${esp32.lib_deps}
OneWire@~2.3.5

View File

@@ -101,6 +101,7 @@ function adoptVersionAndRepo(html) {
async function minify(str, type = "plain") {
const options = {
collapseWhitespace: true,
conservativeCollapse: true, // preserve spaces in text
collapseBooleanAttributes: true,
collapseInlineTagWhitespace: true,
minifyCSS: true,

View File

@@ -102,9 +102,9 @@ private:
void secondsEffectSineFade(int16_t secondLed, Toki::Time const& time) {
uint32_t ms = time.ms % 1000;
uint8_t b0 = (cos8(ms * 64 / 1000) - 128) * 2;
uint8_t b0 = (cos8_t(ms * 64 / 1000) - 128) * 2;
setPixelColor(secondLed, gamma32(scale32(secondColor, b0)));
uint8_t b1 = (sin8(ms * 64 / 1000) - 128) * 2;
uint8_t b1 = (sin8_t(ms * 64 / 1000) - 128) * 2;
setPixelColor(inc(secondLed, 1, secondsSegment), gamma32(scale32(secondColor, b1)));
}

View File

@@ -444,6 +444,7 @@ public:
configComplete &= getJsonValue(top[F("PublishAlways")], PublishAlways, false);
configComplete &= getJsonValue(top[F("UseCelsius")], UseCelsius, true);
configComplete &= getJsonValue(top[F("HomeAssistantDiscovery")], HomeAssistantDiscovery, false);
tempScale = UseCelsius ? "°C" : "°F";
DEBUG_PRINT(FPSTR(_name));
if (!initDone) {

View File

@@ -7,11 +7,12 @@ platform = ${esp32.platform}
build_unflags = ${common.build_unflags}
build_flags =
${common.build_flags_esp32}
-D USERMOD_FOUR_LINE_DISPLAY -D USE_ALT_DISPlAY
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
upload_speed = 460800
-D USERMOD_FOUR_LINE_DISPLAY
-D FLD_TYPE=SH1106
-D I2CSCLPIN=27
-D I2CSDAPIN=26
lib_deps =
${esp32.lib_deps}
U8g2@~2.34.4
Wire

View File

@@ -1,16 +1,8 @@
# I2C/SPI 4 Line Display Usermod ALT
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
"usermod_v2_four_line_display"
"usermod_v2_rotary_encoder_ui"
This usermod could be used in compination with `usermod_v2_rotary_encoder_ui_ALT`.
The core of these usermods are a copy of the originals. The main changes are to the FourLineDisplay usermod.
The display usermod UI has been completely changed.
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
Without the display, it functions identical to the original.
The original "usermod_v2_auto_save" will not work with the display just yet.
## Functionalities
Press the encoder to cycle through the options:
* Brightness
@@ -18,26 +10,18 @@ Press the encoder to cycle through the options:
* Intensity
* Palette
* Effect
* Main Color (only if display is used)
* Saturation (only if display is used)
* Main Color
* Saturation
Press and hold the encoder to display Network Info. If AP is active, it will display AP, SSID and password
Press and hold the encoder to display Network Info. If AP is active, it will display the AP, SSID and Password
Also shows if the timer is enabled
Also shows if the timer is enabled.
[See the pair of usermods in action](https://www.youtube.com/watch?v=ulZnBt9z3TI)
## Installation
Please refer to the original `usermod_v2_rotary_encoder_ui` readme for the main instructions.
Copy the example `platformio_override.sample.ini` from the usermod_v2_rotary_encoder_ui_ALT folder to the root directory of your particular build and rename it to `platformio_override.ini`.
This file should be placed in the same directory as `platformio.ini`.
Then, to activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file,
or add `-D USE_ALT_DISPlAY` to the original `platformio_override.ini.sample` file
Copy the example `platformio_override.sample.ini` to the root directory of your particular build.
## Configuration

View File

@@ -0,0 +1,14 @@
[platformio]
default_envs = esp32dev
[env:esp32dev]
board = esp32dev
platform = ${esp32.platform}
build_unflags = ${common.build_unflags}
build_flags =
${common.build_flags_esp32}
-D USERMOD_ROTARY_ENCODER_UI
-D USERMOD_ROTARY_ENCODER_GPIO=INPUT
-D ENCODER_DT_PIN=21
-D ENCODER_CLK_PIN=23
-D ENCODER_SW_PIN=0

View File

@@ -1,16 +1,8 @@
# Rotary Encoder UI Usermod ALT
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
"usermod_v2_four_line_display"
"usermod_v2_rotary_encoder_ui"
This usermod supports the UI of the `usermod_v2_rotary_encoder_ui_ALT`.
The core of these usermods are a copy of the originals. The main changes are to the FourLineDisplay usermod.
The display usermod UI has been completely changed.
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
Without the display, it functions identical to the original.
The original "usermod_v2_auto_save" will not work with the display just yet.
## Functionalities
Press the encoder to cycle through the options:
* Brightness
@@ -21,8 +13,7 @@ Press the encoder to cycle through the options:
* Main Color (only if display is used)
* Saturation (only if display is used)
Press and hold the encoder to display Network Info
if AP is active, it will display the AP, SSID and Password
Press and hold the encoder to display Network Info. If AP is active, it will display the AP, SSID and Password
Also shows if the timer is enabled.
@@ -30,9 +21,7 @@ Also shows if the timer is enabled.
## Installation
Copy the example `platformio_override.sample.ini` to the root directory of your particular build and rename it to `platformio_override.ini`.
To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file, or add `-D USE_ALT_DISPlAY` to your `platformio_override.ini` file
Copy the example `platformio_override.sample.ini` to the root directory of your particular build.
### Define Your Options
@@ -40,7 +29,6 @@ To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp
also tells this usermod that the display is available
(see the Four Line Display usermod `readme.md` for more details)
* `USE_ALT_DISPlAY` - Mandatory to use Four Line Display
* `ENCODER_DT_PIN` - defaults to 18
* `ENCODER_CLK_PIN` - defaults to 5
* `ENCODER_SW_PIN` - defaults to 19
@@ -50,7 +38,7 @@ To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE
### PlatformIO requirements
Note: the Four Line Display usermod requires the libraries `U8g2` and `Wire`.
No special requirements.
## Change Log

View File

@@ -25,7 +25,7 @@
// effect utility functions
uint8_t sin_gap(uint16_t in) {
if (in & 0x100) return 0;
return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0
return sin8_t(in + 192); // correct phase shift of sine so that it starts and stops at 0
}
uint16_t triwave16(uint16_t in) {
@@ -335,7 +335,7 @@ uint16_t mode_breath(void) {
counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048
if (counter < 16384) {
if (counter > 8192) counter = 8192 - (counter - 8192);
var = sin16(counter) / 103; //close to parabolic in range 0-8192, max val. 23170
var = sin16_t(counter) / 103; //close to parabolic in range 0-8192, max val. 23170
}
unsigned lum = 30 + var;
@@ -517,7 +517,7 @@ static uint16_t running_base(bool saw, bool dual=false) {
}
a = 255 - a;
}
uint8_t s = dual ? sin_gap(a) : sin8(a);
uint8_t s = dual ? sin_gap(a) : sin8_t(a);
uint32_t ca = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s);
if (dual) {
unsigned b = (SEGLEN-1-i)*x_scale - counter;
@@ -1879,16 +1879,16 @@ uint16_t mode_pride_2015(void) {
unsigned sPseudotime = SEGENV.step;
unsigned sHue16 = SEGENV.aux0;
uint8_t sat8 = beatsin88( 87, 220, 250);
uint8_t brightdepth = beatsin88( 341, 96, 224);
unsigned brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
unsigned msmultiplier = beatsin88(147, 23, 60);
uint8_t sat8 = beatsin88_t( 87, 220, 250);
uint8_t brightdepth = beatsin88_t( 341, 96, 224);
unsigned brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256));
unsigned msmultiplier = beatsin88_t(147, 23, 60);
unsigned hue16 = sHue16;//gHue * 256;
unsigned hueinc16 = beatsin88(113, 1, 3000);
unsigned hueinc16 = beatsin88_t(113, 1, 3000);
sPseudotime += duration * msmultiplier;
sHue16 += duration * beatsin88( 400, 5,9);
sHue16 += duration * beatsin88_t( 400, 5,9);
unsigned brightnesstheta16 = sPseudotime;
for (unsigned i = 0 ; i < SEGLEN; i++) {
@@ -1896,7 +1896,7 @@ uint16_t mode_pride_2015(void) {
uint8_t hue8 = hue16 >> 8;
brightnesstheta16 += brightnessthetainc16;
unsigned b16 = sin16( brightnesstheta16 ) + 32768;
unsigned b16 = sin16_t( brightnesstheta16 ) + 32768;
unsigned bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
@@ -1921,7 +1921,7 @@ uint16_t mode_juggle(void) {
CRGB fastled_col;
byte dothue = 0;
for (int i = 0; i < 8; i++) {
int index = 0 + beatsin88((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
int index = 0 + beatsin88_t((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
fastled_col = CRGB(SEGMENT.getPixelColor(index));
fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255);
SEGMENT.setPixelColor(index, fastled_col);
@@ -1942,8 +1942,8 @@ uint16_t mode_palette() {
constexpr mathType maxAngle = 0x8000;
constexpr mathType staticRotationScale = 256;
constexpr mathType animatedRotationScale = 1;
constexpr int16_t (*sinFunction)(uint16_t) = &sin16;
constexpr int16_t (*cosFunction)(uint16_t) = &cos16;
constexpr int16_t (*sinFunction)(uint16_t) = &sin16_t;
constexpr int16_t (*cosFunction)(uint16_t) = &cos16_t;
#else
using mathType = float;
using wideMathType = float;
@@ -1966,7 +1966,7 @@ uint16_t mode_palette() {
const bool inputAnimateRotation = SEGMENT.check2;
const bool inputAssumeSquare = SEGMENT.check3;
const angleType theta = (!inputAnimateRotation) ? (inputRotation * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
const angleType theta = (!inputAnimateRotation) ? ((inputRotation + 128) * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
const mathType sinTheta = sinFunction(theta);
const mathType cosTheta = cosFunction(theta);
@@ -1985,7 +1985,7 @@ uint16_t mode_palette() {
// So the rectangle needs to have exactly the right size. That size depends on the rotation.
// This scale computation here only considers one dimension. You can think of it like the rectangle is always scaled so that
// the left and right most points always match the left and right side of the display.
const mathType scale = std::abs(sinTheta) + (std::abs(cosTheta) * maxYOut / maxXOut);
const mathType scale = std::abs(sinTheta) + (std::abs(cosTheta) * maxYOut / maxXOut);
// 2D simulation:
// If we are dealing with a 1D setup, we assume that each segment represents one line on a 2-dimensional display.
// The function is called once per segments, so we need to handle one line at a time.
@@ -2016,8 +2016,8 @@ uint16_t mode_palette() {
colorIndex = ((inputSize - 112) * colorIndex) / 16;
}
// Finally, shift the palette a bit.
const int paletteOffset = (!inputAnimateShift) ? (inputShift-128) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
colorIndex += paletteOffset;
const int paletteOffset = (!inputAnimateShift) ? (inputShift) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
colorIndex -= paletteOffset;
const uint32_t color = SEGMENT.color_wheel((uint8_t)colorIndex);
if (isMatrix) {
SEGMENT.setPixelColorXY(x, y, color);
@@ -2028,7 +2028,7 @@ uint16_t mode_palette() {
}
return FRAMETIME;
}
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Anamorphic;;!;12;c1=128,c2=128,c3=128,o1=1,o2=1,o3=0";
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Anamorphic;;!;12;ix=112,c1=0,o1=1,o2=0,o3=1";
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active
@@ -2127,15 +2127,15 @@ uint16_t mode_colorwaves() {
unsigned sPseudotime = SEGENV.step;
unsigned sHue16 = SEGENV.aux0;
unsigned brightdepth = beatsin88(341, 96, 224);
unsigned brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
unsigned msmultiplier = beatsin88(147, 23, 60);
unsigned brightdepth = beatsin88_t(341, 96, 224);
unsigned brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256));
unsigned msmultiplier = beatsin88_t(147, 23, 60);
unsigned hue16 = sHue16;//gHue * 256;
unsigned hueinc16 = beatsin88(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues
unsigned hueinc16 = beatsin88_t(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues
sPseudotime += duration * msmultiplier;
sHue16 += duration * beatsin88(400, 5, 9);
sHue16 += duration * beatsin88_t(400, 5, 9);
unsigned brightnesstheta16 = sPseudotime;
for (int i = 0 ; i < SEGLEN; i++) {
@@ -2149,7 +2149,7 @@ uint16_t mode_colorwaves() {
}
brightnesstheta16 += brightnessthetainc16;
unsigned b16 = sin16(brightnesstheta16) + 32768;
unsigned b16 = sin16_t(brightnesstheta16) + 32768;
unsigned bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
@@ -2168,7 +2168,7 @@ static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!";
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint16_t mode_bpm() {
uint32_t stp = (strip.now / 20) & 0xFF;
uint8_t beat = beatsin8(SEGMENT.speed, 64, 255);
uint8_t beat = beatsin8_t(SEGMENT.speed, 64, 255);
for (int i = 0; i < SEGLEN; i++) {
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10)));
}
@@ -2184,7 +2184,7 @@ uint16_t mode_fillnoise8() {
unsigned index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4
SEGENV.step += beatsin8_t(SEGMENT.speed, 1, 6); //10,1,4
return FRAMETIME;
}
@@ -2196,13 +2196,13 @@ uint16_t mode_noise16_1() {
SEGENV.step += (1 + SEGMENT.speed/16);
for (int i = 0; i < SEGLEN; i++) {
unsigned shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm
unsigned shift_x = beatsin8_t(11); // the x position of the noise field swings @ 17 bpm
unsigned shift_y = SEGENV.step/42; // the y position becomes slowly incremented
unsigned real_x = (i + shift_x) * scale; // the x position of the noise field swings @ 17 bpm
unsigned real_y = (i + shift_y) * scale; // the y position becomes slowly incremented
uint32_t real_z = SEGENV.step; // the z position becomes quickly incremented
unsigned noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down
unsigned index = sin8(noise * 3); // map LED color based on noise data
unsigned index = sin8_t(noise * 3); // map LED color based on noise data
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
@@ -2220,7 +2220,7 @@ uint16_t mode_noise16_2() {
unsigned shift_x = SEGENV.step >> 6; // x as a function of time
uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field
unsigned noise = inoise16(real_x, 0, 4223) >> 8; // get the noise data and scale it down
unsigned index = sin8(noise * 3); // map led color based on noise data
unsigned index = sin8_t(noise * 3); // map led color based on noise data
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise));
}
@@ -2241,7 +2241,7 @@ uint16_t mode_noise16_3() {
uint32_t real_y = (i + shift_y) * scale; // based on the precalculated positions
uint32_t real_z = SEGENV.step*8;
unsigned noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down
unsigned index = sin8(noise * 3); // map led color based on noise data
unsigned index = sin8_t(noise * 3); // map led color based on noise data
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise));
}
@@ -2321,13 +2321,13 @@ static const char _data_FX_MODE_COLORTWINKLE[] PROGMEM = "Colortwinkles@Fade spe
//Calm effect, like a lake at night
uint16_t mode_lake() {
unsigned sp = SEGMENT.speed/10;
int wave1 = beatsin8(sp +2, -64,64);
int wave2 = beatsin8(sp +1, -64,64);
int wave3 = beatsin8(sp +2, 0,80);
int wave1 = beatsin8_t(sp +2, -64,64);
int wave2 = beatsin8_t(sp +1, -64,64);
int wave3 = beatsin8_t(sp +2, 0,80);
for (int i = 0; i < SEGLEN; i++)
{
int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
int index = cos8_t((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
uint8_t lum = (index > wave3) ? index - wave3 : 0;
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum));
}
@@ -2500,7 +2500,7 @@ static uint16_t ripple_base() {
propI /= 2;
unsigned cx = rippleorigin >> 8;
unsigned cy = rippleorigin & 0xFF;
unsigned mag = scale8(sin8((propF>>2)), amp);
unsigned mag = scale8(sin8_t((propF>>2)), amp);
if (propI > 0) SEGMENT.drawCircle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag), true);
} else
#endif
@@ -2565,11 +2565,11 @@ static CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
{
// Overall twinkle speed (changed)
unsigned ticks = ms / SEGENV.aux0;
unsigned fastcycle8 = ticks;
unsigned slowcycle16 = (ticks >> 8) + salt;
slowcycle16 += sin8(slowcycle16);
unsigned fastcycle8 = uint8_t(ticks);
uint16_t slowcycle16 = (ticks >> 8) + salt;
slowcycle16 += sin8_t(slowcycle16);
slowcycle16 = (slowcycle16 * 2053) + 1384;
unsigned slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8);
// Overall twinkle density.
// 0 (NONE lit) to 8 (ALL lit at once).
@@ -3138,7 +3138,7 @@ static const char _data_FX_MODE_ROLLINGBALLS[] PROGMEM = "Rolling Balls@!,# of b
static uint16_t sinelon_base(bool dual, bool rainbow=false) {
if (SEGLEN == 1) return mode_static();
SEGMENT.fade_out(SEGMENT.intensity);
unsigned pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1);
unsigned pos = beatsin16_t(SEGMENT.speed/10,0,SEGLEN-1);
if (SEGENV.call == 0) SEGENV.aux0 = pos;
uint32_t color1 = SEGMENT.color_from_palette(pos, true, false, 0);
uint32_t color2 = SEGCOLOR(2);
@@ -3547,7 +3547,7 @@ uint16_t mode_exploding_fireworks(void)
if (segs <= (strip.getMaxSegments() /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs
int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg
unsigned numSparks = min(2 + ((rows*cols) >> 1), maxSparks);
unsigned numSparks = min(5 + ((rows*cols) >> 1), maxSparks);
unsigned dataSize = sizeof(spark) * numSparks;
if (!SEGENV.allocateData(dataSize + sizeof(float))) return mode_static(); //allocation failed
float *dying_gravity = reinterpret_cast<float*>(SEGENV.data + dataSize);
@@ -3602,7 +3602,8 @@ uint16_t mode_exploding_fireworks(void)
* Size is proportional to the height.
*/
unsigned nSparks = flare->pos + random8(4);
nSparks = constrain(nSparks, 4, numSparks);
nSparks = std::max(nSparks, 4U); // This is not a standard constrain; numSparks is not guaranteed to be at least 4
nSparks = std::min(nSparks, numSparks);
// initialize sparks
if (SEGENV.aux0 == 2) {
@@ -3854,13 +3855,13 @@ uint16_t mode_plasma(void) {
if (SEGENV.call == 0) {
SEGENV.aux0 = random8(0,2); // add a bit of randomness
}
unsigned thisPhase = beatsin8(6+SEGENV.aux0,-64,64);
unsigned thatPhase = beatsin8(7+SEGENV.aux0,-64,64);
unsigned thisPhase = beatsin8_t(6+SEGENV.aux0,-64,64);
unsigned thatPhase = beatsin8_t(7+SEGENV.aux0,-64,64);
for (unsigned i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows:
unsigned colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change.
+ cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
unsigned thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1))));
+ cos8_t((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish.
unsigned thisBright = qsub8(colorIndex, beatsin8_t(7,0, (128 - (SEGMENT.intensity>>1))));
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0, thisBright));
}
@@ -3987,10 +3988,10 @@ static CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, u
unsigned wavescale_half = (wavescale >> 1) + 20;
waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i
unsigned s16 = sin16(waveangle) + 32768;
unsigned s16 = sin16_t(waveangle) + 32768;
unsigned cs = scale16(s16, wavescale_half) + wavescale_half;
ci += (cs * i);
unsigned sindex16 = sin16(ci) + 32768;
unsigned sindex16 = sin16_t(ci) + 32768;
unsigned sindex8 = scale16(sindex16, 240);
return ColorFromPalette(p, sindex8, bri, LINEARBLEND);
}
@@ -4022,34 +4023,34 @@ uint16_t mode_pacifica()
uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7);
strip.now = deltat;
unsigned speedfactor1 = beatsin16(3, 179, 269);
unsigned speedfactor2 = beatsin16(4, 179, 269);
unsigned speedfactor1 = beatsin16_t(3, 179, 269);
unsigned speedfactor2 = beatsin16_t(4, 179, 269);
uint32_t deltams1 = (deltams * speedfactor1) / 256;
uint32_t deltams2 = (deltams * speedfactor2) / 256;
uint32_t deltams21 = (deltams1 + deltams2) / 2;
sCIStart1 += (deltams1 * beatsin88(1011,10,13));
sCIStart2 -= (deltams21 * beatsin88(777,8,11));
sCIStart3 -= (deltams1 * beatsin88(501,5,7));
sCIStart4 -= (deltams2 * beatsin88(257,4,6));
sCIStart1 += (deltams1 * beatsin88_t(1011,10,13));
sCIStart2 -= (deltams21 * beatsin88_t(777,8,11));
sCIStart3 -= (deltams1 * beatsin88_t(501,5,7));
sCIStart4 -= (deltams2 * beatsin88_t(257,4,6));
SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2;
SEGENV.step = (sCIStart4 << 16) | (sCIStart3 & 0xFFFF);
// Clear out the LED array to a dim background blue-green
//SEGMENT.fill(132618);
unsigned basethreshold = beatsin8( 9, 55, 65);
unsigned basethreshold = beatsin8_t( 9, 55, 65);
unsigned wave = beat8( 7 );
for (int i = 0; i < SEGLEN; i++) {
CRGB c = CRGB(2, 6, 10);
// Render each of four layers, with different scales and speeds, that vary over time
c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0-beat16(301));
c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8(9, 10,38) , 0-beat16(503));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8(8, 10,28) , beat16(601));
c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16_t(3, 11 * 256, 14 * 256), beatsin8_t(10, 70, 130), 0-beat16(301));
c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16_t(4, 6 * 256, 9 * 256), beatsin8_t(17, 40, 80), beat16(401));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8_t(9, 10,38) , 0-beat16(503));
c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8_t(8, 10,28) , beat16(601));
// Add extra 'white' to areas where the four layers of light have lined up brightly
unsigned threshold = scale8( sin8( wave), 20) + basethreshold;
unsigned threshold = scale8( sin8_t( wave), 20) + basethreshold;
wave += 7;
unsigned l = c.getAverageLight();
if (l > threshold) {
@@ -4173,7 +4174,7 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine
for (int i = 0; i < SEGLEN; i++) {
unsigned ranstart = random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work.
unsigned pixBri = sin8(ranstart + 16 * strip.now/(256-SEGMENT.speed));
unsigned pixBri = sin8_t(ranstart + 16 * strip.now/(256-SEGMENT.speed));
if (random8() > SEGMENT.intensity) pixBri = 0;
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri));
}
@@ -4216,7 +4217,7 @@ uint16_t mode_noisepal(void) { // Slow noise
SEGMENT.setPixelColor(i, color.red, color.green, color.blue);
}
SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave.
SEGENV.aux0 += beatsin8_t(10,1,4); // Moving along the distance. Vary it a bit with a sine wave.
return FRAMETIME;
}
@@ -4298,7 +4299,7 @@ uint16_t mode_chunchun(void)
for (unsigned i = 0; i < numBirds; i++)
{
counter -= span;
unsigned megumin = sin16(counter) + 0x8000;
unsigned megumin = sin16_t(counter) + 0x8000;
unsigned bird = uint32_t(megumin * SEGLEN) >> 16;
uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping
bird = constrain(bird, 0U, SEGLEN-1U);
@@ -4467,7 +4468,7 @@ uint16_t mode_washing_machine(void) {
SEGENV.step += (speed * 2048) / (512 - SEGMENT.speed);
for (int i = 0; i < SEGLEN; i++) {
uint8_t col = sin8(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7));
uint8_t col = sin8_t(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7));
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3));
}
@@ -4630,7 +4631,7 @@ uint16_t mode_tv_simulator(void) {
return FRAMETIME;
}
static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;";
static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;!;01";
/*
@@ -4823,8 +4824,8 @@ static const char _data_FX_MODE_PERLINMOVE[] PROGMEM = "Perlin Move@!,# of pixel
uint16_t mode_wavesins(void) {
for (int i = 0; i < SEGLEN; i++) {
uint8_t bri = sin8(strip.now/4 + i * SEGMENT.intensity);
uint8_t index = beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3)); // custom3 is reduced resolution slider
uint8_t bri = sin8_t(strip.now/4 + i * SEGMENT.intensity);
uint8_t index = beatsin8_t(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3)); // custom3 is reduced resolution slider
//SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, index, bri, LINEARBLEND));
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, bri));
}
@@ -4846,9 +4847,9 @@ uint16_t mode_FlowStripe(void) {
for (int i = 0; i < SEGLEN; i++) {
int c = (abs(i - hl) / hl) * 127;
c = sin8(c);
c = sin8(c / 2 + t);
byte b = sin8(c + t/8);
c = sin8_t(c);
c = sin8_t(c / 2 + t);
byte b = sin8_t(c + t/8);
SEGMENT.setPixelColor(i, CHSV(b + hue, 255, 255));
}
@@ -4875,14 +4876,14 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
unsigned long t = strip.now/128; // timebase
// outer stars
for (size_t i = 0; i < 8; i++) {
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i);
x = beatsin8_t(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8_t(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i);
SEGMENT.addPixelColorXY(x, y, SEGMENT.color_from_palette(i*32, false, PALETTE_SOLID_WRAP, SEGMENT.check1?0:255));
}
// inner stars
for (size_t i = 0; i < 4; i++) {
x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i);
x = beatsin8_t(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8_t(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i);
SEGMENT.addPixelColorXY(x, y, SEGMENT.color_from_palette(255-i*64, false, PALETTE_SOLID_WRAP, SEGMENT.check1?0:255));
}
// central white dot
@@ -4916,10 +4917,10 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
SEGENV.aux0++; // hue
SEGMENT.fadeToBlackBy(40);
for (size_t i = 0; i < numLines; i++) {
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (rows - 1));
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24);
byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
byte x1 = beatsin8_t(2 + SEGMENT.speed/16, 0, (cols - 1));
byte x2 = beatsin8_t(1 + SEGMENT.speed/16, 0, (rows - 1));
byte y1 = beatsin8_t(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24);
byte y2 = beatsin8_t(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
CRGB color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
byte xsteps = abs8(x1 - y1) + 1;
@@ -4958,8 +4959,8 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa
SEGMENT.fadeToBlackBy(64);
for (int i = 0; i < cols; i++) {
SEGMENT.setPixelColorXY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4 ), ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.setPixelColorXY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128), ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND));
SEGMENT.setPixelColorXY(i, beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 ), ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND));
SEGMENT.setPixelColorXY(i, beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128), ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND));
}
SEGMENT.blur(SEGMENT.intensity>>3);
@@ -4988,8 +4989,8 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
SEGMENT.fadeToBlackBy(135);
for (int i = 0; i < rows; i++) {
int x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128);
int x1 = beatsin8(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
int x = beatsin8_t(speeds, 0, cols - 1, 0, i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, i * freq + 128);
int x1 = beatsin8_t(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq);
unsigned hue = (i * 128 / rows) + ms;
// skip every 4th row every now and then (fade it more)
if ((i + ms / 8) & 3) {
@@ -5090,9 +5091,9 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so
SEGMENT.fadeToBlackBy(16);
for (size_t i = 8; i > 0; i--) {
SEGMENT.addPixelColorXY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1),
beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1),
ColorFromPalette(SEGPALETTE, beatsin8(12, 0, 255), 255, LINEARBLEND));
SEGMENT.addPixelColorXY(beatsin8_t(SEGMENT.speed/8 + i, 0, cols - 1),
beatsin8_t(SEGMENT.intensity/8 - i, 0, rows - 1),
ColorFromPalette(SEGPALETTE, beatsin8_t(12, 0, 255), 255, LINEARBLEND));
}
SEGMENT.blur(SEGMENT.custom1>>3);
@@ -5224,7 +5225,7 @@ uint16_t mode_2DHiphotic() { // By: ldirko https://edit
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0));
SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8_t(cos8_t(x * SEGMENT.speed/16 + a / 3) + sin8_t(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0));
}
}
@@ -5300,8 +5301,8 @@ uint16_t mode_2DJulia(void) { // An animated Julia set
reAl = -0.94299f; // PixelBlaze example
imAg = 0.3162f;
reAl += sin_t((float)strip.now/305.f)/20.f;
imAg += sin_t((float)strip.now/405.f)/20.f;
reAl += (float)sin16_t(strip.now * 34) / 655340.f;
imAg += (float)sin16_t(strip.now * 26) / 655340.f;
dx = (xmax - xmin) / (cols); // Scale the delta x and y values to our matrix size.
dy = (ymax - ymin) / (rows);
@@ -5364,10 +5365,10 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline
//for (int i=0; i < 4*(cols+rows); i ++) {
for (int i=0; i < 256; i ++) {
//float xlocn = float(sin8(now/4+i*(SEGMENT.speed>>5))) / 255.0f;
//float ylocn = float(cos8(now/4+i*2)) / 255.0f;
uint_fast8_t xlocn = sin8(phase/2 + (i*SEGMENT.speed)/32);
uint_fast8_t ylocn = cos8(phase/2 + i*2);
//float xlocn = float(sin8_t(now/4+i*(SEGMENT.speed>>5))) / 255.0f;
//float ylocn = float(cos8_t(now/4+i*2)) / 255.0f;
uint_fast8_t xlocn = sin8_t(phase/2 + (i*SEGMENT.speed)/32);
uint_fast8_t ylocn = cos8_t(phase/2 + i*2);
xlocn = (cols < 2) ? 1 : (map(2*xlocn, 0,511, 0,2*(cols-1)) +1) /2; // softhack007: "(2* ..... +1) /2" for proper rounding
ylocn = (rows < 2) ? 1 : (map(2*ylocn, 0,511, 0,2*(rows-1)) +1) /2; // "rows > 1" is needed to avoid div/0 in map()
SEGMENT.setPixelColorXY((uint8_t)xlocn, (uint8_t)ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0));
@@ -5467,8 +5468,8 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have
int y3 = map(inoise8(strip.now * speed, 25355, 22685), 0, 255, 0, rows-1);
// and one Lissajou function
int x1 = beatsin8(23 * speed, 0, cols-1);
int y1 = beatsin8(28 * speed, 0, rows-1);
int x1 = beatsin8_t(23 * speed, 0, cols-1);
int y1 = beatsin8_t(28 * speed, 0, rows-1);
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
@@ -5633,7 +5634,7 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi
SEGMENT.fadeToBlackBy(8 - (SEGMENT.intensity>>5));
uint32_t a = strip.now / (18 - SEGMENT.speed / 16);
int x = (a / 14) % cols;
int y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0);
int y = map((sin8_t(a * 5) + sin8_t(a * 4) + sin8_t(a * 2)), 0, 765, rows-1, 0);
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND));
SEGMENT.blur(SEGMENT.intensity>>4);
@@ -5659,10 +5660,10 @@ uint16_t mode_2DSindots(void) { // By: ldirko http
SEGMENT.fadeToBlackBy(SEGMENT.custom1>>3);
byte t1 = strip.now / (257 - SEGMENT.speed); // 20;
byte t2 = sin8(t1) / 4 * 2;
byte t2 = sin8_t(t1) / 4 * 2;
for (int i = 0; i < 13; i++) {
int x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15!
int y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15!
int x = sin8_t(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15!
int y = sin8_t(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15!
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND));
}
SEGMENT.blur(SEGMENT.custom2>>3);
@@ -5689,12 +5690,12 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
SEGMENT.blur(SEGMENT.custom3>>1);
// Use two out-of-sync sine waves
int i = beatsin8(19, kBorderWidth, cols-kBorderWidth);
int j = beatsin8(22, kBorderWidth, cols-kBorderWidth);
int k = beatsin8(17, kBorderWidth, cols-kBorderWidth);
int m = beatsin8(18, kBorderWidth, rows-kBorderWidth);
int n = beatsin8(15, kBorderWidth, rows-kBorderWidth);
int p = beatsin8(20, kBorderWidth, rows-kBorderWidth);
int i = beatsin8_t(19, kBorderWidth, cols-kBorderWidth);
int j = beatsin8_t(22, kBorderWidth, cols-kBorderWidth);
int k = beatsin8_t(17, kBorderWidth, cols-kBorderWidth);
int m = beatsin8_t(18, kBorderWidth, rows-kBorderWidth);
int n = beatsin8_t(15, kBorderWidth, rows-kBorderWidth);
int p = beatsin8_t(20, kBorderWidth, rows-kBorderWidth);
SEGMENT.addPixelColorXY(i, m, ColorFromPalette(SEGPALETTE, strip.now/29, 255, LINEARBLEND));
SEGMENT.addPixelColorXY(j, n, ColorFromPalette(SEGPALETTE, strip.now/41, 255, LINEARBLEND));
@@ -5770,19 +5771,19 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
uint8_t hue, bri;
size_t intensity;
int offsetX = beatsin16(3, -360, 360);
int offsetY = beatsin16(2, -360, 360);
int offsetX = beatsin16_t(3, -360, 360);
int offsetY = beatsin16_t(2, -360, 360);
int sharpness = SEGMENT.custom3 / 8; // 0-3
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
hue = x * beatsin16(10, 1, 10) + offsetY;
intensity = bri = sin8(x * SEGMENT.speed/2 + offsetX);
hue = x * beatsin16_t(10, 1, 10) + offsetY;
intensity = bri = sin8_t(x * SEGMENT.speed/2 + offsetX);
for (int i=0; i<sharpness; i++) intensity *= bri;
intensity >>= 8*sharpness;
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND));
hue = y * 3 + offsetX;
intensity = bri = sin8(y * SEGMENT.intensity/2 + offsetY);
intensity = bri = sin8_t(y * SEGMENT.intensity/2 + offsetY);
for (int i=0; i<sharpness; i++) intensity *= bri;
intensity >>= 8*sharpness;
SEGMENT.addPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND));
@@ -5817,9 +5818,9 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
SEGMENT.move(SEGENV.aux0, 1);
for (size_t i = 0; i < 8; i++) {
int x = beatsin8(12 + i, 2, cols - 3);
int y = beatsin8(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
int x = beatsin8_t(12 + i, 2, cols - 3);
int y = beatsin8_t(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(SEGPALETTE, beatsin8_t(12 + i, 0, 255), 255);
SEGMENT.addPixelColorXY(x, y, color);
if (cols > 24 || rows > 24) {
SEGMENT.addPixelColorXY(x+1, y, color);
@@ -6215,8 +6216,8 @@ uint16_t mode_2Ddriftrose(void) {
SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3));
for (size_t i = 1; i < 37; i++) {
float angle = radians(i * 10);
uint32_t x = (CX + (sin_t(angle) * (beatsin8(i, 0, L*2)-L))) * 255.f;
uint32_t y = (CY + (cos_t(angle) * (beatsin8(i, 0, L*2)-L))) * 255.f;
uint32_t x = (CX + (sin_t(angle) * (beatsin8_t(i, 0, L*2)-L))) * 255.f;
uint32_t y = (CY + (cos_t(angle) * (beatsin8_t(i, 0, L*2)-L))) * 255.f;
SEGMENT.wu_pixel(x, y, CHSV(i * 10, 255, 255));
}
SEGMENT.blur(SEGMENT.intensity>>4);
@@ -6265,6 +6266,7 @@ uint16_t mode_2Dplasmarotozoom() {
}
}
*a -= 0.03f + float(SEGENV.speed-128)*0.0002f; // rotation speed
if(*a < -6283.18530718f) *a += 6283.18530718f; // 1000*2*PI, protect sin/cos from very large input float values (will give wrong results)
return FRAMETIME;
}
@@ -6412,8 +6414,8 @@ uint16_t mode_2DSwirl(void) {
SEGMENT.blur(SEGMENT.custom1);
int i = beatsin8( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth);
int j = beatsin8( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth);
int i = beatsin8_t( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth);
int j = beatsin8_t( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth);
int ni = (cols - 1) - i;
int nj = (cols - 1) - j;
@@ -6625,7 +6627,7 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline.
for (size_t i=0; i<SEGMENT.intensity/32+1U; i++) {
// if SEGLEN equals 1, we will always set color to the first and only pixel, but the effect is still good looking
SEGMENT.setPixelColor(beatsin16(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc));
SEGMENT.setPixelColor(beatsin16_t(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc));
}
return FRAMETIME;
@@ -6685,8 +6687,8 @@ uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline.
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.aux0=SEGENV.aux0+beatsin8(5,0,10);
SEGENV.aux1=SEGENV.aux1+beatsin8(4,0,10);
SEGENV.aux0=SEGENV.aux0+beatsin8_t(5,0,10);
SEGENV.aux1=SEGENV.aux1+beatsin8_t(4,0,10);
return FRAMETIME;
} // mode_midnoise()
@@ -6745,8 +6747,8 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline.
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0));
}
SEGENV.aux0+=beatsin8(5,0,10);
SEGENV.aux1+=beatsin8(4,0,10);
SEGENV.aux0+=beatsin8_t(5,0,10);
SEGENV.aux1+=beatsin8_t(4,0,10);
return FRAMETIME;
} // mode_noisemeter()
@@ -6801,13 +6803,13 @@ uint16_t mode_plasmoid(void) { // Plasmoid. By Andrew Tuline.
SEGMENT.fadeToBlackBy(32);
plasmoip->thisphase += beatsin8(6,-4,4); // You can change direction and speed individually.
plasmoip->thatphase += beatsin8(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline.
plasmoip->thisphase += beatsin8_t(6,-4,4); // You can change direction and speed individually.
plasmoip->thatphase += beatsin8_t(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline.
for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set a brightness based on a wave as follows.
// updated, similar to "plasma" effect - softhack007
uint8_t thisbright = cubicwave8(((i*(1 + (3*SEGMENT.speed/32)))+plasmoip->thisphase) & 0xFF)/2;
thisbright += cos8(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases.
thisbright += cos8_t(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases.
uint8_t colorIndex=thisbright;
if (volumeSmth * SEGMENT.intensity / 64 < thisbright) {thisbright = 0;}
@@ -7266,7 +7268,7 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac
frTemp -= 132.0f; // This should give us a base musical note of C3
frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255;
unsigned i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1);
unsigned i = map(beatsin8_t(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1);
i = constrain(i, 0U, SEGLEN-1U);
SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint8_t)frTemp, false, PALETTE_SOLID_WRAP, 0), volTemp));
@@ -7553,12 +7555,12 @@ uint16_t mode_2Ddistortionwaves() {
unsigned a2 = a/2;
unsigned a3 = a/3;
unsigned cx = beatsin8(10-speed,0,cols-1)*scale;
unsigned cy = beatsin8(12-speed,0,rows-1)*scale;
unsigned cx1 = beatsin8(13-speed,0,cols-1)*scale;
unsigned cy1 = beatsin8(15-speed,0,rows-1)*scale;
unsigned cx2 = beatsin8(17-speed,0,cols-1)*scale;
unsigned cy2 = beatsin8(14-speed,0,rows-1)*scale;
unsigned cx = beatsin8_t(10-speed,0,cols-1)*scale;
unsigned cy = beatsin8_t(12-speed,0,rows-1)*scale;
unsigned cx1 = beatsin8_t(13-speed,0,cols-1)*scale;
unsigned cy1 = beatsin8_t(15-speed,0,rows-1)*scale;
unsigned cx2 = beatsin8_t(17-speed,0,cols-1)*scale;
unsigned cy2 = beatsin8_t(14-speed,0,rows-1)*scale;
unsigned xoffs = 0;
for (int x = 0; x < cols; x++) {
@@ -7568,17 +7570,17 @@ uint16_t mode_2Ddistortionwaves() {
for (int y = 0; y < rows; y++) {
yoffs += scale;
byte rdistort = cos8((cos8(((x<<3)+a )&255)+cos8(((y<<3)-a2)&255)+a3 )&255)>>1;
byte gdistort = cos8((cos8(((x<<3)-a2)&255)+cos8(((y<<3)+a3)&255)+a+32 )&255)>>1;
byte bdistort = cos8((cos8(((x<<3)+a3)&255)+cos8(((y<<3)-a) &255)+a2+64)&255)>>1;
byte rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1;
byte gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1;
byte bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1;
byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 ));
byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ));
byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ));
valueR = gamma8(cos8(valueR));
valueG = gamma8(cos8(valueG));
valueB = gamma8(cos8(valueB));
valueR = gamma8(cos8_t(valueR));
valueG = gamma8(cos8_t(valueG));
valueB = gamma8(cos8_t(valueB));
SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0));
}
@@ -7735,8 +7737,10 @@ uint16_t mode_2Doctopus() {
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
rMap[XY(x, y)].angle = 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
int dx = (x - C_X);
int dy = (y - C_Y);
rMap[XY(x, y)].angle = int(40.7436f * atan2_t(dy, dx)); // avoid 128*atan2()/PI
rMap[XY(x, y)].radius = sqrtf(dx * dx + dy * dy) * mapp; //thanks Sutaburosu
}
}
}
@@ -7746,8 +7750,8 @@ uint16_t mode_2Doctopus() {
for (int y = 0; y < rows; y++) {
byte angle = rMap[XY(x,y)].angle;
byte radius = rMap[XY(x,y)].radius;
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
unsigned intensity = sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1));
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
unsigned intensity = sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1));
intensity = map((intensity*intensity) & 0xFFFF, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display
CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity);
SEGMENT.setPixelColorXY(x, y, c);
@@ -7755,7 +7759,7 @@ uint16_t mode_2Doctopus() {
}
return FRAMETIME;
}
static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs;;!;2;";
static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs,fasttan;;!;2;";
//Waving Cell
@@ -7772,7 +7776,7 @@ uint16_t mode_2Dwavingcell() {
uint8_t aY = SEGMENT.custom2/16 + 1;
uint8_t aZ = SEGMENT.custom3 + 1;
for (int x = 0; x < cols; x++) for (int y = 0; y <rows; y++)
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, ((sin8((x*aX)+sin8((y+t)*aY))+cos8(y*aZ))+1)+t));
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, ((sin8_t((x*aX)+sin8_t((y+t)*aY))+cos8_t(y*aZ))+1)+t));
return FRAMETIME;
}

View File

@@ -47,6 +47,15 @@
#define FRAMETIME_FIXED (1000/WLED_FPS)
#define FRAMETIME strip.getFrameTime()
// FPS calculation (can be defined as compile flag for debugging)
#ifndef FPS_CALC_AVG
#define FPS_CALC_AVG 7 // average FPS calculation over this many frames (moving average)
#endif
#ifndef FPS_MULTIPLIER
#define FPS_MULTIPLIER 1 // dev option: multiplier to get sub-frame FPS without floats
#endif
#define FPS_CALC_SHIFT 7 // bit shift for fixed point math
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#ifdef ESP8266
@@ -729,7 +738,7 @@ class WS2812FX { // 96 bytes
_transitionDur(750),
_targetFps(WLED_FPS),
_frametime(FRAMETIME_FIXED),
_cumulativeFps(2),
_cumulativeFps(50 << FPS_CALC_SHIFT),
_isServicing(false),
_isOffRefreshRequired(false),
_hasWhiteChannel(false),

View File

@@ -1286,14 +1286,9 @@ void WS2812FX::finalizeInit() {
_isOffRefreshRequired |= bus->isOffRefreshRequired() && !bus->isPWM(); // use refresh bit for phase shift with analog
unsigned busEnd = bus->getStart() + bus->getLength();
if (busEnd > _length) _length = busEnd;
#ifdef ESP8266
// why do we need to reinitialise GPIO3???
//if (!bus->isDigital() || bus->is2Pin()) continue;
//uint8_t pins[5];
//if (!bus->getPins(pins)) continue;
//BusDigital* bd = static_cast<BusDigital*>(bus);
//if (pins[0] == 3) bd->reinit();
#endif
// This must be done after all buses have been created, as some kinds (parallel I2S) interact
bus->begin();
}
Segment::maxWidth = _length;
@@ -1412,10 +1407,12 @@ void WS2812FX::show() {
unsigned long showNow = millis();
size_t diff = showNow - _lastShow;
size_t fpsCurr = 200;
if (diff > 0) fpsCurr = 1000 / diff;
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
_lastShow = showNow;
if (diff > 0) { // skip calculation if no time has passed
size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math
_cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding
_lastShow = showNow;
}
}
/**
@@ -1432,7 +1429,7 @@ bool WS2812FX::isUpdating() const {
*/
uint16_t WS2812FX::getFps() const {
if (millis() - _lastShow > 2000) return 0;
return _cumulativeFps +1;
return (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; // _cumulativeFps is stored in fixed point
}
void WS2812FX::setTargetFps(uint8_t fps) {

View File

@@ -150,7 +150,7 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
//_buffering = bc.doubleBuffer;
uint16_t lenToCreate = bc.count;
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz);
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr);
_valid = (_busPtr != nullptr);
DEBUG_PRINTF_P(PSTR("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n"), _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], is2Pin(bc.type)?_pins[1]:255, _iType, _milliAmpsPerLed, _milliAmpsMax);
}
@@ -410,9 +410,9 @@ std::vector<LEDType> BusDigital::getLEDTypes() {
};
}
void BusDigital::reinit() {
void BusDigital::begin() {
if (!_valid) return;
PolyBus::begin(_busPtr, _iType, _pins);
PolyBus::begin(_busPtr, _iType, _pins, _frequencykHz);
}
void BusDigital::cleanup() {
@@ -910,7 +910,7 @@ void BusManager::on() {
if (busses[i]->isDigital() && busses[i]->getPins(pins)) {
if (pins[0] == LED_BUILTIN || pins[1] == LED_BUILTIN) {
BusDigital *bus = static_cast<BusDigital*>(busses[i]);
bus->reinit();
bus->begin();
break;
}
}

View File

@@ -79,6 +79,7 @@ class Bus {
virtual ~Bus() {} //throw the bus under the bus
virtual void begin() {};
virtual void show() = 0;
virtual bool canShow() const { return true; }
virtual void setStatusPixel(uint32_t c) {}
@@ -213,7 +214,7 @@ class BusDigital : public Bus {
uint16_t getLEDCurrent() const override { return _milliAmpsPerLed; }
uint16_t getUsedCurrent() const override { return _milliAmpsTotal; }
uint16_t getMaxCurrent() const override { return _milliAmpsMax; }
void reinit();
void begin() override;
void cleanup();
static std::vector<LEDType> getLEDTypes();

View File

@@ -336,7 +336,7 @@ class PolyBus {
// initialize SPI bus speed for DotStar methods
template <class T>
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz = 0U) {
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz /* 0 == use default */) {
T dotStar_strip = static_cast<T>(busPtr);
#ifdef ESP8266
dotStar_strip->Begin();
@@ -363,7 +363,7 @@ class PolyBus {
tm1914_strip->SetPixelSettings(NeoTm1914Settings()); //NeoTm1914_Mode_DinFdinAutoSwitch, NeoTm1914_Mode_DinOnly, NeoTm1914_Mode_FdinOnly
}
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz = 0U) {
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz /* only used by DotStar */) {
switch (busType) {
case I_NONE: break;
#ifdef ESP8266
@@ -480,7 +480,7 @@ class PolyBus {
}
}
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) {
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel) {
#if defined(ARDUINO_ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
// NOTE: "channel" is only used on ESP32 (and its variants) for RMT channel allocation
// since 0.15.0-b3 I2S1 is favoured for classic ESP32 and moved to position 0 (channel 0) so we need to subtract 1 for correct RMT allocation
@@ -597,7 +597,7 @@ class PolyBus {
case I_HS_P98_3: busPtr = new B_HS_P98_3(len, pins[1], pins[0]); break;
case I_SS_P98_3: busPtr = new B_SS_P98_3(len, pins[1], pins[0]); break;
}
begin(busPtr, busType, pins, clock_kHz);
return busPtr;
}

View File

@@ -2827,7 +2827,7 @@ function search(field, listId = null) {
// restore default preset sorting if no search term is entered
if (!search) {
if (listId === 'pcont') { populatePresets(); return; }
if (listId === 'pcont') { populatePresets(); return; }
if (listId === 'pallist') {
let id = parseInt(d.querySelector('#pallist input[name="palette"]:checked').value); // preserve selected palette
populatePalettes();
@@ -2846,12 +2846,16 @@ function search(field, listId = null) {
// filter list items but leave (Default & Solid) always visible
const listItems = gId(listId).querySelectorAll('.lstI');
listItems.forEach((listItem,i)=>{
if (listId!=='pcont' && i===0) return;
listItems.forEach((listItem, i) => {
if (listId !== 'pcont' && i === 0) return;
const listItemName = listItem.querySelector('.lstIname').innerText.toUpperCase();
const searchIndex = listItemName.indexOf(field.value.toUpperCase());
listItem.style.display = (searchIndex < 0) ? 'none' : '';
listItem.dataset.searchIndex = searchIndex;
if (searchIndex < 0) {
listItem.dataset.searchIndex = Number.MAX_SAFE_INTEGER;
} else {
listItem.dataset.searchIndex = searchIndex;
}
listItem.style.display = (searchIndex < 0) && !listItem.classList.contains("selected") ? 'none' : '';
});
// sort list items by search index and name
@@ -2920,11 +2924,11 @@ function filterFx() {
inputField.value = '';
inputField.focus();
clean(inputField.nextElementSibling);
gId("fxlist").querySelectorAll('.lstI').forEach((listItem,i) => {
gId("fxlist").querySelectorAll('.lstI').forEach((listItem, i) => {
const listItemName = listItem.querySelector('.lstIname').innerText;
let hide = false;
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { if (e.checked && !listItemName.includes(e.dataset.flt)) hide = i>0 /*true*/; });
listItem.style.display = hide ? 'none' : '';
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { if (e.checked && !listItemName.includes(e.dataset.flt)) hide = i > 0 /*true*/; });
listItem.style.display = hide && !listItem.classList.contains("selected") ? 'none' : '';
});
}

View File

@@ -42,15 +42,14 @@
if (loc) d.Sf.action = getURL('/settings/leds');
}
function bLimits(b,v,p,m,l,o=5,d=2,a=6) {
// maxB - max buses (can be changed if using ESP32 parallel I2S)
// maxD - max digital channels (can be changed if using ESP32 parallel I2S)
// maxA - max analog channels
// maxV - min virtual buses
// maxPB - max LEDs per bus
// maxM - max LED memory
// maxL - max LEDs (will serve to determine ESP >1664 == ESP32)
// maxCO - max Color Order mappings
oMaxB = maxB = b; maxD = d, maxA = a, maxV = v; maxM = m; maxPB = p; maxL = l; maxCO = o;
oMaxB = maxB = b; // maxB - max buses (can be changed if using ESP32 parallel I2S)
maxD = d; // maxD - max digital channels (can be changed if using ESP32 parallel I2S)
maxA = a; // maxA - max analog channels
maxV = v; // maxV - min virtual buses
maxPB = p; // maxPB - max LEDs per bus
maxM = m; // maxM - max LED memory
maxL = l; // maxL - max LEDs (will serve to determine ESP >1664 == ESP32)
maxCO = o; // maxCO - max Color Order mappings
}
function pinsOK() {
var ok = true;

View File

@@ -60,8 +60,8 @@
<hr>
<h3>Backup & Restore</h3>
<div class="warn">&#9888; Restoring presets/configuration will OVERWRITE your current presets/configuration.<br>
Incorrect upload or configuration may require a factory reset or re-flashing of your ESP.</div>
For security reasons, passwords are not backed up.
Incorrect upload or configuration may require a factory reset or re-flashing of your ESP.<br>
For security reasons, passwords are not backed up.</div>
<a class="btn lnk" id="bckcfg" href="/presets.json" download="presets">Backup presets</a><br>
<div>Restore presets<br><input type="file" name="data" accept=".json"> <button type="button" onclick="uploadFile(d.Sf.data,'/presets.json');">Upload</button><br></div><br>
<a class="btn lnk" id="bckpresets" href="/cfg.json" download="cfg">Backup configuration</a><br>
@@ -78,4 +78,4 @@
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>
</html>

View File

@@ -389,6 +389,9 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL
int16_t extractModeDefaults(uint8_t mode, const char *segVar);
void checkSettingsPIN(const char *pin);
uint16_t crc16(const unsigned char* data_p, size_t length);
uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0);
uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0);
uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0);
um_data_t* simulateSound(uint8_t simulationId);
void enumerateLedmaps();
uint8_t get_random_wheel_index(uint8_t pos);
@@ -419,27 +422,37 @@ void clearEEPROM();
#endif
//wled_math.cpp
#if defined(ESP8266) && !defined(WLED_USE_REAL_MATH)
template <typename T> T atan_t(T x);
float cos_t(float phi);
float sin_t(float x);
float tan_t(float x);
float acos_t(float x);
float asin_t(float x);
float floor_t(float x);
float fmod_t(float num, float denom);
#else
#include <math.h>
#define sin_t sinf
#define cos_t cosf
#define tan_t tanf
#define asin_t asinf
#define acos_t acosf
#define atan_t atanf
#define fmod_t fmodf
#define floor_t floorf
#endif
//float cos_t(float phi); // use float math
//float sin_t(float phi);
//float tan_t(float x);
int16_t sin16_t(uint16_t theta);
int16_t cos16_t(uint16_t theta);
uint8_t sin8_t(uint8_t theta);
uint8_t cos8_t(uint8_t theta);
float sin_approx(float theta); // uses integer math (converted to float), accuracy +/-0.0015 (compared to sinf())
float cos_approx(float theta);
float tan_approx(float x);
float atan2_t(float y, float x);
float acos_t(float x);
float asin_t(float x);
template <typename T> T atan_t(T x);
float floor_t(float x);
float fmod_t(float num, float denom);
#define sin_t sin_approx
#define cos_t cos_approx
#define tan_t tan_approx
/*
#include <math.h> // standard math functions. use a lot of flash
#define sin_t sinf
#define cos_t cosf
#define tan_t tanf
#define asin_t asinf
#define acos_t acosf
#define atan_t atanf
#define fmod_t fmodf
#define floor_t floorf
*/
//wled_serial.cpp
void handleSerial();
void updateBaudRate(uint32_t rate);

View File

@@ -207,6 +207,7 @@ void WiFiEvent(WiFiEvent_t event)
break;
#endif
default:
DEBUG_PRINTF_P(PSTR("Network event: %d\n"), (int)event);
break;
}
}

View File

@@ -215,6 +215,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
// we will not bother with pre-allocating ColorOrderMappings vector
BusManager::getColorOrderMap().reset();
for (int s = 0; s < WLED_MAX_COLOR_ORDER_MAPPINGS; s++) {
int offset = s < 10 ? 48 : 55;
char xs[4] = "XS"; xs[2] = offset+s; xs[3] = 0; //start LED

View File

@@ -34,8 +34,8 @@ static const int enablePin = -1; // disable the enable pin because it is not ne
static const int rxPin = -1; // disable the receiving pin because it is not needed - softhack007: Pin=-1 means "use default" not "disable"
static const int txPin = 2; // transmit DMX data over this pin (default is pin 2)
//DMX value array and size. Entry 0 will hold startbyte
static uint8_t dmxData[dmxMaxChannel] = { 0 };
//DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
static uint8_t dmxData[dmxMaxChannel+1] = { 0 };
static int chanSize = 0;
#if !defined(DMX_SEND_ONLY)
static int currentChannel = 0;

View File

@@ -372,6 +372,39 @@ uint16_t crc16(const unsigned char* data_p, size_t length) {
return crc;
}
// fastled beatsin: 1:1 replacements to remove the use of fastled sin16()
// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
{
uint16_t beat = beat88( beats_per_minute_88, timebase);
uint16_t beatsin (sin16_t( beat + phase_offset) + 32768);
uint16_t rangewidth = highest - lowest;
uint16_t scaledbeat = scale16( beatsin, rangewidth);
uint16_t result = lowest + scaledbeat;
return result;
}
// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
{
uint16_t beat = beat16( beats_per_minute, timebase);
uint16_t beatsin = (sin16_t( beat + phase_offset) + 32768);
uint16_t rangewidth = highest - lowest;
uint16_t scaledbeat = scale16( beatsin, rangewidth);
uint16_t result = lowest + scaledbeat;
return result;
}
// Generates an 8-bit sine wave at a given BPM that oscillates within a given range. see fastled for details.
uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest, uint8_t highest, uint32_t timebase, uint8_t phase_offset)
{
uint8_t beat = beat8( beats_per_minute, timebase);
uint8_t beatsin = sin8_t( beat + phase_offset);
uint8_t rangewidth = highest - lowest;
uint8_t scaledbeat = scale8( beatsin, rangewidth);
uint8_t result = lowest + scaledbeat;
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Begin simulateSound (to enable audio enhanced effects to display something)
@@ -431,8 +464,8 @@ um_data_t* simulateSound(uint8_t simulationId)
default:
case UMS_BeatSin:
for (int i = 0; i<16; i++)
fftResult[i] = beatsin8(120 / (i+1), 0, 255);
// fftResult[i] = (beatsin8(120, 0, 255) + (256/16 * i)) % 256;
fftResult[i] = beatsin8_t(120 / (i+1), 0, 255);
// fftResult[i] = (beatsin8_t(120, 0, 255) + (256/16 * i)) % 256;
volumeSmth = fftResult[8];
break;
case UMS_WeWillRockYou:
@@ -469,12 +502,12 @@ um_data_t* simulateSound(uint8_t simulationId)
break;
case UMS_10_13:
for (int i = 0; i<16; i++)
fftResult[i] = inoise8(beatsin8(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3);
fftResult[i] = inoise8(beatsin8_t(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3);
volumeSmth = fftResult[8];
break;
case UMS_14_3:
for (int i = 0; i<16; i++)
fftResult[i] = inoise8(beatsin8(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3);
fftResult[i] = inoise8(beatsin8_t(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3);
volumeSmth = fftResult[8];
break;
}

View File

@@ -478,10 +478,7 @@ void WLED::setup()
if (strcmp(multiWiFi[0].clientSSID, DEFAULT_CLIENT_SSID) == 0)
showWelcomePage = true;
WiFi.persistent(false);
#ifdef WLED_USE_ETHERNET
WiFi.onEvent(WiFiEvent);
#endif
WiFi.mode(WIFI_STA); // enable scanning
findWiFi(true); // start scanning for available WiFi-s
@@ -781,7 +778,7 @@ int8_t WLED::findWiFi(bool doScan) {
void WLED::initConnection()
{
DEBUG_PRINTLN(F("initConnection() called."));
DEBUG_PRINTF_P(PSTR("initConnection() called @ %lus.\n"), millis()/1000);
#ifdef WLED_ENABLE_WEBSOCKETS
ws.onEvent(wsEvent);
@@ -825,9 +822,7 @@ void WLED::initConnection()
if (WLED_WIFI_CONFIGURED) {
showWelcomePage = false;
DEBUG_PRINT(F("Connecting to "));
DEBUG_PRINT(multiWiFi[selectedWiFi].clientSSID);
DEBUG_PRINTLN(F("..."));
DEBUG_PRINTF_P(PSTR("Connecting to %s...\n"), multiWiFi[selectedWiFi].clientSSID);
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[25];
@@ -926,7 +921,8 @@ void WLED::handleConnection()
{
static bool scanDone = true;
static byte stacO = 0;
unsigned long now = millis();
const unsigned long now = millis();
const unsigned long nowS = now/1000;
const bool wifiConfigured = WLED_WIFI_CONFIGURED;
// ignore connection handling if WiFi is configured and scan still running
@@ -935,7 +931,7 @@ void WLED::handleConnection()
return;
if (lastReconnectAttempt == 0 || forceReconnect) {
DEBUG_PRINTLN(F("Initial connect or forced reconnect."));
DEBUG_PRINTF_P(PSTR("Initial connect or forced reconnect (@ %lus).\n"), nowS);
selectedWiFi = findWiFi(); // find strongest WiFi
initConnection();
interfacesInited = false;
@@ -955,8 +951,7 @@ void WLED::handleConnection()
#endif
if (stac != stacO) {
stacO = stac;
DEBUG_PRINT(F("Connected AP clients: "));
DEBUG_PRINTLN(stac);
DEBUG_PRINTF_P(PSTR("Connected AP clients: %d\n"), (int)stac);
if (!WLED_CONNECTED && wifiConfigured) { // trying to connect, but not connected
if (stac)
WiFi.disconnect(); // disable search so that AP can work
@@ -979,6 +974,7 @@ void WLED::handleConnection()
initConnection();
interfacesInited = false;
scanDone = true;
return;
}
//send improv failed 6 seconds after second init attempt (24 sec. after provisioning)
if (improvActive > 2 && now - lastReconnectAttempt > 6000) {
@@ -987,13 +983,13 @@ void WLED::handleConnection()
}
if (now - lastReconnectAttempt > ((stac) ? 300000 : 18000) && wifiConfigured) {
if (improvActive == 2) improvActive = 3;
DEBUG_PRINTLN(F("Last reconnect too old."));
DEBUG_PRINTF_P(PSTR("Last reconnect (%lus) too old (@ %lus).\n"), lastReconnectAttempt/1000, nowS);
if (++selectedWiFi >= multiWiFi.size()) selectedWiFi = 0; // we couldn't connect, try with another network from the list
initConnection();
}
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) {
if (!(apBehavior == AP_BEHAVIOR_TEMPORARY && now > WLED_AP_TIMEOUT)) {
DEBUG_PRINTLN(F("Not connected AP."));
DEBUG_PRINTF_P(PSTR("Not connected AP (@ %lus).\n"), nowS);
initAP(); // start AP only within first 5min
}
}
@@ -1003,7 +999,7 @@ void WLED::handleConnection()
dnsServer.stop();
WiFi.softAPdisconnect(true);
apActive = false;
DEBUG_PRINTLN(F("Temporary AP disabled."));
DEBUG_PRINTF_P(PSTR("Temporary AP disabled (@ %lus).\n"), nowS);
}
}
} else if (!interfacesInited) { //newly connected

View File

@@ -3,12 +3,12 @@
/*
Main sketch, global variable declarations
@title WLED project sketch
@version 0.15.0-b7
@version 0.15.0
@author Christian Schwinne
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2410270
#define VERSION 2412100
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
@@ -264,12 +264,12 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument<PSRAM_Allocator>;
#define WLED_VERSION dev
#endif
#ifndef WLED_RELEASE_NAME
#define WLED_RELEASE_NAME dev_release
#define WLED_RELEASE_NAME "Custom"
#endif
// Global Variable definitions
WLED_GLOBAL char versionString[] _INIT(TOSTRING(WLED_VERSION));
WLED_GLOBAL char releaseString[] _INIT(TOSTRING(WLED_RELEASE_NAME)); // somehow this will not work if using "const char releaseString[]
WLED_GLOBAL char releaseString[] _INIT(WLED_RELEASE_NAME); // must include the quotes when defining, e.g -D WLED_RELEASE_NAME=\"ESP32_MULTI_USREMODS\"
#define WLED_CODENAME "Kōsen"
// AP and OTA default passwords (for maximum security change them!)

View File

@@ -10,16 +10,25 @@
//#define WLED_DEBUG_MATH
// Note: cos_t, sin_t and tan_t are very accurate but slow
// the math.h functions use several kB of flash and are to be avoided if possible
// sin16_t / cos16_t are faster and much more accurate than the fastled variants
// sin_approx and cos_approx are float wrappers for sin16_t/cos16_t and have an accuracy better than +/-0.0015 compared to sinf()
// sin8_t / cos8_t are fastled replacements and use sin16_t / cos16_t. Slightly slower than fastled version but very accurate
// Taylor series approximations, replaced with Bhaskara I's approximation
/*
#define modd(x, y) ((x) - (int)((x) / (y)) * (y))
float cos_t(float phi)
{
float x = modd(phi, TWO_PI);
float x = modd(phi, M_TWOPI);
if (x < 0) x = -1 * x;
int8_t sign = 1;
if (x > PI)
if (x > M_PI)
{
x -= PI;
x -= M_PI;
sign = -1;
}
float xx = x * x;
@@ -31,8 +40,8 @@ float cos_t(float phi)
return res;
}
float sin_t(float x) {
float res = cos_t(HALF_PI - x);
float sin_t(float phi) {
float res = cos_t(M_PI_2 - phi);
#ifdef WLED_DEBUG_MATH
Serial.printf("sin: %f,%f,%f,(%f)\n",x,res,sin(x),res-sin(x));
#endif
@@ -48,6 +57,80 @@ float tan_t(float x) {
#endif
return res;
}
*/
// 16-bit, integer based Bhaskara I's sine approximation: 16*x*(pi - x) / (5*pi^2 - 4*x*(pi - x))
// input is 16bit unsigned (0-65535), output is 16bit signed (-32767 to +32767)
// optimized integer implementation by @dedehai
int16_t sin16_t(uint16_t theta) {
int scale = 1;
if (theta > 0x7FFF) {
theta = 0xFFFF - theta;
scale = -1; // second half of the sine function is negative (pi - 2*pi)
}
uint32_t precal = theta * (0x7FFF - theta);
uint64_t numerator = (uint64_t)precal * (4 * 0x7FFF); // 64bit required
int32_t denominator = 1342095361 - precal; // 1342095361 is 5 * 0x7FFF^2 / 4
int16_t result = numerator / denominator;
return result * scale;
}
int16_t cos16_t(uint16_t theta) {
return sin16_t(theta + 0x4000); //cos(x) = sin(x+pi/2)
}
uint8_t sin8_t(uint8_t theta) {
int32_t sin16 = sin16_t((uint16_t)theta * 257); // 255 * 257 = 0xFFFF
sin16 += 0x7FFF + 128; //shift result to range 0-0xFFFF, +128 for rounding
return min(sin16, int32_t(0xFFFF)) >> 8; // min performs saturation, and prevents overflow
}
uint8_t cos8_t(uint8_t theta) {
return sin8_t(theta + 64); //cos(x) = sin(x+pi/2)
}
float sin_approx(float theta) {
uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3)
int32_t result = sin16_t(scaled_theta);
float sin = float(result) / 0x7FFF;
return sin;
}
float cos_approx(float theta) {
uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3)
int32_t result = sin16_t(scaled_theta + 0x4000);
float cos = float(result) / 0x7FFF;
return cos;
}
float tan_approx(float x) {
float c = cos_approx(x);
if (c==0.0f) return 0;
float res = sin_approx(x) / c;
return res;
}
#define ATAN2_CONST_A 0.1963f
#define ATAN2_CONST_B 0.9817f
// atan2_t approximation, with the idea from https://gist.github.com/volkansalma/2972237?permalink_comment_id=3872525#gistcomment-3872525
float atan2_t(float y, float x) {
float abs_y = fabs(y);
float abs_x = fabs(x);
float r = (abs_x - abs_y) / (abs_y + abs_x + 1e-10f); // avoid division by zero by adding a small nubmer
float angle;
if(x < 0) {
r = -r;
angle = M_PI_2 + M_PI_4;
}
else
angle = M_PI_2 - M_PI_4;
float add = (ATAN2_CONST_A * (r * r) - ATAN2_CONST_B) * r;
angle += add;
angle = y < 0 ? -angle : angle;
return angle;
}
//https://stackoverflow.com/questions/3380628
// Absolute error <= 6.7e-5
@@ -60,10 +143,10 @@ float acos_t(float x) {
ret = ret * xabs;
ret = ret - 0.2121144f;
ret = ret * xabs;
ret = ret + HALF_PI;
ret = ret + M_PI_2;
ret = ret * sqrt(1.0f-xabs);
ret = ret - 2 * negate * ret;
float res = negate * PI + ret;
float res = negate * M_PI + ret;
#ifdef WLED_DEBUG_MATH
Serial.printf("acos: %f,%f,%f,(%f)\n",x,res,acos(x),res-acos(x));
#endif
@@ -71,7 +154,7 @@ float acos_t(float x) {
}
float asin_t(float x) {
float res = HALF_PI - acos_t(x);
float res = M_PI_2 - acos_t(x);
#ifdef WLED_DEBUG_MATH
Serial.printf("asin: %f,%f,%f,(%f)\n",x,res,asin(x),res-asin(x));
#endif
@@ -87,7 +170,7 @@ float atan_t(float x) {
//For A/B/C, see https://stackoverflow.com/a/42542593
static const double A { 0.0776509570923569 };
static const double B { -0.287434475393028 };
static const double C { ((HALF_PI/2) - A - B) };
static const double C { ((M_PI_4) - A - B) };
// polynominal factors for approximation between 1 and 5
static const float C0 { 0.089494f };
static const float C1 { 0.974207f };
@@ -102,7 +185,7 @@ float atan_t(float x) {
x = std::abs(x);
float res;
if (x > 5.0f) { // atan(x) converges to pi/2 - (1/x) for large values
res = HALF_PI - (1.0f/x);
res = M_PI_2 - (1.0f/x);
} else if (x > 1.0f) { //1 < x < 5
float xx = x * x;
res = (C4*xx*xx)+(C3*xx*x)+(C2*xx)+(C1*x)+C0;

View File

@@ -83,7 +83,7 @@ void appendGPIOinfo(Print& settingsScript) {
// usermod pin reservations will become unnecessary when settings pages will read cfg.json directly
if (requestJSONBufferLock(6)) {
// if we can't allocate JSON buffer ignore usermod pins
JsonObject mods = pDoc->createNestedObject(F("um"));
JsonObject mods = pDoc->createNestedObject("um");
UsermodManager::addToConfig(mods);
if (!mods.isNull()) fillUMPins(settingsScript, mods);
releaseJSONBufferLock();
@@ -91,35 +91,42 @@ void appendGPIOinfo(Print& settingsScript) {
settingsScript.print(F("];"));
// add reserved (unusable) pins
bool firstPin = true;
settingsScript.print(F("d.rsvd=["));
for (unsigned i = 0; i < WLED_NUM_PINS; i++) {
if (!PinManager::isPinOk(i, false)) { // include readonly pins
settingsScript.print(i); settingsScript.print(",");
if (!firstPin) settingsScript.print(',');
settingsScript.print(i);
firstPin = false;
}
}
#ifdef WLED_ENABLE_DMX
settingsScript.print(F("2,")); // DMX hardcoded pin
if (!firstPin) settingsScript.print(',');
settingsScript.print(2); // DMX hardcoded pin
firstPin = false;
#endif
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
settingsScript.printf_P(PSTR(",%d"),hardwareTX); // debug output (TX) pin
if (!firstPin) settingsScript.print(',');
settingsScript.print(hardwareTX); // debug output (TX) pin
firstPin = false;
#endif
//Note: Using pin 3 (RX) disables Adalight / Serial JSON
#ifdef WLED_USE_ETHERNET
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
for (unsigned p=0; p<WLED_ETH_RSVD_PINS_COUNT; p++) { settingsScript.printf(",%d", esp32_nonconfigurable_ethernet_pins[p].pin); }
if (ethernetBoards[ethernetType].eth_power>=0) { settingsScript.printf(",%d", ethernetBoards[ethernetType].eth_power); }
if (ethernetBoards[ethernetType].eth_mdc>=0) { settingsScript.printf(",%d", ethernetBoards[ethernetType].eth_mdc); }
if (ethernetBoards[ethernetType].eth_mdio>=0) { settingsScript.printf(",%d", ethernetBoards[ethernetType].eth_mdio); }
switch (ethernetBoards[ethernetType].eth_clk_mode) {
if (!firstPin) settingsScript.print(',');
for (unsigned p=0; p<WLED_ETH_RSVD_PINS_COUNT; p++) { settingsScript.printf("%d,",esp32_nonconfigurable_ethernet_pins[p].pin); }
if (ethernetBoards[ethernetType].eth_power >= 0) { settingsScript.printf("%d,",ethernetBoards[ethernetType].eth_power); }
if (ethernetBoards[ethernetType].eth_mdc >= 0) { settingsScript.printf("%d,",ethernetBoards[ethernetType].eth_mdc); }
if (ethernetBoards[ethernetType].eth_mdio >= 0) { settingsScript.printf("%d,",ethernetBoards[ethernetType].eth_mdio); }
switch (ethernetBoards[ethernetType].eth_clk_mode) {
case ETH_CLOCK_GPIO0_IN:
case ETH_CLOCK_GPIO0_OUT:
settingsScript.print(F("0"));
settingsScript.print(0);
break;
case ETH_CLOCK_GPIO16_OUT:
settingsScript.print(F("16"));
settingsScript.print(16);
break;
case ETH_CLOCK_GPIO17_OUT:
settingsScript.print(F("17"));
settingsScript.print(17);
break;
}
}
@@ -128,11 +135,11 @@ void appendGPIOinfo(Print& settingsScript) {
// add info for read-only GPIO
settingsScript.print(F("d.ro_gpio=["));
bool firstPin = true;
firstPin = true;
for (unsigned i = 0; i < WLED_NUM_PINS; i++) {
if (PinManager::isReadOnlyPin(i)) {
// No comma before the first pin
if (!firstPin) settingsScript.print(F(","));
if (!firstPin) settingsScript.print(',');
settingsScript.print(i);
firstPin = false;
}
@@ -140,9 +147,7 @@ void appendGPIOinfo(Print& settingsScript) {
settingsScript.print(F("];"));
// add info about max. # of pins
settingsScript.print(F("d.max_gpio="));
settingsScript.print(WLED_NUM_PINS);
settingsScript.print(F(";"));
settingsScript.printf_P(PSTR("d.max_gpio=%d;"),WLED_NUM_PINS);
}
//get values for settings form in javascript
@@ -152,6 +157,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
DEBUG_PRINTF_P(PSTR("settings resp %u\n"), (unsigned)subPage);
if (subPage <0 || subPage >10) return;
char nS[32];
if (subPage == SUBPAGE_MENU)
{
@@ -259,11 +265,9 @@ void getSettingsJS(byte subPage, Print& settingsScript)
if (subPage == SUBPAGE_LEDS)
{
char nS[32];
appendGPIOinfo(settingsScript);
settingsScript.print(F("d.ledTypes=")); settingsScript.print(BusManager::getLEDTypesJSONString().c_str()); settingsScript.print(";");
settingsScript.printf_P(PSTR("d.ledTypes=%s;"), BusManager::getLEDTypesJSONString().c_str());
// set limits
settingsScript.printf_P(PSTR("bLimits(%d,%d,%d,%d,%d,%d,%d,%d);"),
@@ -399,7 +403,6 @@ void getSettingsJS(byte subPage, Print& settingsScript)
if (subPage == SUBPAGE_SYNC)
{
[[maybe_unused]] char nS[32];
printSetFormValue(settingsScript,PSTR("UP"),udpPort);
printSetFormValue(settingsScript,PSTR("U2"),udpPort2);
#ifndef WLED_DISABLE_ESPNOW
@@ -465,7 +468,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("MG"),mqttGroupTopic);
printSetFormCheckbox(settingsScript,PSTR("BM"),buttonPublishMqtt);
printSetFormCheckbox(settingsScript,PSTR("RT"),retainMqttMsg);
settingsScript.printf_P(PSTR("d.Sf.MD.maxlength=%d;d.Sf.MG.maxlength=%d;d.Sf.MS.maxlength=%d;"),
settingsScript.printf_P(PSTR("d.Sf.MD.maxLength=%d;d.Sf.MG.maxLength=%d;d.Sf.MS.maxLength=%d;"),
MQTT_MAX_TOPIC_LEN, MQTT_MAX_TOPIC_LEN, MQTT_MAX_SERVER_LEN);
#else
settingsScript.print(F("toggle('MQTT');")); // hide MQTT settings
@@ -637,7 +640,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
#if defined(ARDUINO_ARCH_ESP32)
ESP.getChipModel(),
#else
F("esp8266"),
"esp8266",
#endif
VERSION);
@@ -648,8 +651,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
{
printSetFormValue(settingsScript,PSTR("SOMP"),strip.isMatrix);
#ifndef WLED_DISABLE_2D
settingsScript.printf_P(PSTR("maxPanels=%d;"),WLED_MAX_PANELS);
settingsScript.print(F("resetPanels();"));
settingsScript.printf_P(PSTR("maxPanels=%d;resetPanels();"),WLED_MAX_PANELS);
if (strip.isMatrix) {
if(strip.panels>0){
printSetFormValue(settingsScript,PSTR("PW"),strip.panel[0].width); //Set generator Width and Height to first panel size for convenience
@@ -658,12 +660,9 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("MPC"),strip.panels);
// panels
for (unsigned i=0; i<strip.panels; i++) {
char n[5];
settingsScript.print(F("addPanel("));
settingsScript.print(itoa(i,n,10));
settingsScript.print(F(");"));
settingsScript.printf_P(PSTR("addPanel(%d);"), i);
char pO[8] = { '\0' };
snprintf_P(pO, 7, PSTR("P%d"), i); // MAX_PANELS is 64 so pO will always only be 4 characters or less
snprintf_P(pO, 7, PSTR("P%d"), i); // WLED_MAX_PANELS is 18 so pO will always only be 4 characters or less
pO[7] = '\0';
unsigned l = strlen(pO);
// create P0B, P1B, ..., P63B, etc for other PxxX