Compare commits

...

1735 Commits

Author SHA1 Message Date
Blaz Kristan
e48a1ec814 Some optimisations and fixes 2024-09-24 21:36:22 +02:00
Blaz Kristan
abb08e2aaf Merge branch '0_15' into debug-refactor 2024-09-23 19:43:09 +02:00
Blaz Kristan
bd7cd32f91 Add mandatory refresh capability to remove type dependency. 2024-09-22 13:56:14 +02:00
Blaz Kristan
9cb3531e2d Remove erroneous file
Fix constant dependancy
2024-09-21 22:24:36 +02:00
Blaz Kristan
b50e6e0d90 Static PinManager & UsermodManager
- saves a few bytes of flash
2024-09-19 21:44:11 +02:00
Blaz Kristan
72455ccde1 Missing "not" 2024-09-17 19:47:24 +02:00
Blaz Kristan
88fb860568 SAVE_RAM bugfix introduced by #4137 2024-09-17 16:34:38 +02:00
Blaz Kristan
ceed494cf7 Introduce common.js in settings pages 2024-09-17 16:26:11 +02:00
Blaz Kristan
ac8f919304 Serial improvements (can RX, canTX)
PinManager bugfix for unsigned long long
2024-09-17 16:21:52 +02:00
Blaž Kristan
7f1ec4802d Merge pull request #4137 from felddy/feature/toggle_pallet_sync
Add the ability to toggle the reception of palette synchronizations
2024-09-16 16:19:19 +02:00
Blaz Kristan
d5777b7bce Fix for missing WLED_NUM_PINS check 2024-09-15 20:34:05 +02:00
PaoloTK
e34f179a82 fix pin conflict check logic 2024-09-15 20:27:44 +02:00
Blaz Kristan
6a90b9a512 FX Temperature better ranges 2024-09-15 19:31:14 +02:00
Blaz Kristan
65a8dbfe41 FX: Usermod Temperature effect 2024-09-15 11:04:02 +02:00
Blaž Kristan
0806c7fbdb Merge pull request #4142 from willmmiles/fix-webserver-pin
Fix AsyncWebServer version pin
2024-09-14 22:51:19 +02:00
Blaz Kristan
5708d7a6b8 Build bump, changelog update 2024-09-14 22:30:56 +02:00
Will Miles
2264cc5d10 Use tag to pin AsyncWebServer version 2024-09-14 16:11:46 -04:00
Blaž Kristan
28cb3f9d0c Merge pull request #4107 from PaoloTK/compile_different_busses
Configure different kinds of busses at compile
2024-09-14 22:02:56 +02:00
PaoloTK
f16ed4697f fix isReadOnlyPin() logic 2024-09-14 18:58:53 +02:00
Blaz Kristan
81e412fe5b Use refernece to avoid ctor/dtor
Use PinManager to determine reserved pins
2024-09-14 14:54:42 +02:00
Blaz Kristan
e3d9417b84 Minor fixes
- rely on HAL for RO pins and max pins
- remove isPinDefined() and do clash check inline
- JS fix to use HAL max pins
2024-09-14 11:39:56 +02:00
Blaz Kristan
6a188033c6 Merge branch '0_15' into compile_different_busses 2024-09-14 09:27:37 +02:00
Blaž Kristan
df24fd7bf2 Merge pull request #4129 from Aircoookie/bus-config
Fetch LED types from Bus classes (dynamic UI)
2024-09-13 23:23:08 +02:00
PaoloTK
fa82e759bd bug fix 2024-09-12 18:27:51 +02:00
PaoloTK
daf0bcfac3 bug fix on pin already defined check 2024-09-12 18:12:38 +02:00
Blaz Kristan
49d51c5af8 Hot 2024-09-12 15:26:26 +02:00
Blaz Kristan
ec7f69d559 Merge branch '0_15' into bus-config 2024-09-12 15:22:56 +02:00
Blaz Kristan
a8c5bf2573 Ease IRAM 2024-09-12 15:22:37 +02:00
Blaz Kristan
f12de61d7f Merge branch '0_15' into bus-config 2024-09-12 15:08:10 +02:00
Blaz Kristan
71fcd6482d Fix CRLF in boblight 2024-09-12 15:07:49 +02:00
Blaz Kristan
e59b38a5d2 Fix unsigned long in debug printf 2024-09-12 15:04:10 +02:00
Blaž Kristan
5b8d9d1510 Merge branch '0_15' into bus-config 2024-09-12 08:49:04 +02:00
Blaž Kristan
6169c458bf Remove void 2024-09-12 08:48:31 +02:00
Blaž Kristan
23400d0449 Conditional IRAM for gamma 2024-09-12 08:30:46 +02:00
PaoloTK
c5435ec1fa Merge remote-tracking branch 'AC/bus-config' into compile_different_busses 2024-09-11 23:04:37 +02:00
Blaz Kristan
eae5a74a11 color_fade bugfix
impure void remove
optimisations: hot
2024-09-11 17:14:59 +02:00
Blaz Kristan
5df1a223c2 Pre-allocate COM vector 2024-09-11 16:45:39 +02:00
Blaž Kristan
81382a4bc0 Merge pull request #4131 from iammattcoleman/update-temperature-dependency
Temperature usermod: update OneWire to 2.3.8
2024-09-11 16:24:25 +02:00
Matt Coleman
750a429bd4 Temperature usermod: update OneWire to 2.3.8
OneWire 2.3.8 includes stickbreaker's and garyd9's ESP32 fixes:
blazoncek's fork is no longer needed
2024-09-11 06:35:09 -04:00
Matt Coleman
dbe78dff93 Temperature usermod: fix changelog formatting
This change ensures that the dates are displayed on their own lines.
Without the blank lines, many Markdown renderers will append the dates
to the previous bullet point.
2024-09-11 06:35:09 -04:00
PaoloTK
5869627b32 - More optimization on bus configuration logic.
- Renamed LEDPIN to DEFAULT_LED_PIN.
- Removed ability to override DEFAULT_LED_PIN, DEFAULT_LED_TYPE and DEFAULT_LED_COUNT. Use DATA_PINS, LED_TYPES and PIXEL_COUNTS instead.
2024-09-11 01:27:19 +02:00
Frank
5bc5ef0ae8 Update CONTRIBUTING.md - typo 2024-09-10 20:36:48 +02:00
Frank
cce5e8f811 Update CONTRIBUTING.md - adding a hint to avoid force-pushing 2024-09-10 20:34:43 +02:00
Felddy
8ae09c3d02 Fix comment alignment 2024-09-10 18:16:00 +00:00
Felddy
83699bc5c3 Add support for toggle of palette sync 2024-09-10 18:02:29 +00:00
Blaz Kristan
3a5eb8c5d2 WLED 0.15.0-b5 release
- Audioreactive usermod always included
2024-09-10 16:07:37 +02:00
Blaz Kristan
fd00e5eaae LED settings text update 2024-09-10 15:23:27 +02:00
Blaz Kristan
20444ee7d5 Debug optimisations 2024-09-10 15:20:34 +02:00
PaoloTK
eb06e575c2 add check for pin reassigned conflict with pin defined for current bus 2024-09-10 01:03:19 +02:00
Blaz Kristan
b4315152e2 Add numPins() 2024-09-08 11:07:53 +02:00
Frank
340a9f8b76 better bugfix for seven-seg-reloaded
* only reject invalid ranges when array access will be actually performed
* fixed another stupid pointer arithmetic error

Hint: I AM NOT THE MAINTAINER of this usermod. I'm just fixing an obvious coding error without knowing what the usermod really does.
2024-09-06 20:09:25 +02:00
Frank
81cec6a25a Update usermod_seven_segment_reloaded.h - prevent array bounds violation (solves #4121)
I'm not the maintainer of this usermod, but its obvious that the code might overrun array bounds, so fixing this.
2024-09-06 19:36:24 +02:00
Blaz Kristan
c5b31e2f63 Bugfix 2024-09-06 17:56:36 +02:00
Blaz Kristan
0642b17ab0 Bugfix 2024-09-06 17:54:36 +02:00
Blaz Kristan
ac689a9a2e Remove array, un-inline calculateCCT 2024-09-06 12:19:04 +02:00
Blaz Kristan
43cc4ec009 Increase oappend buffer on ESP8266 2024-09-05 22:18:50 +02:00
Blaz Kristan
9cc333b2bd Move LED types to individual bus type
- (credit @netmindz & @willmmiles)
Tuning.
2024-09-05 21:49:27 +02:00
Blaž Kristan
55d98ff935 Merge pull request #4126 from DedeHai/PWM-fixes
fixed offsets and inverted signal plus dead time
2024-09-05 17:26:28 +02:00
Blaz Kristan
b9080f9479 Mirroring bugfix. 2024-09-04 21:17:21 +02:00
Blaz Kristan
092a5a1ca3 Unsigned fix 2024-09-04 20:54:44 +02:00
Damian Schneider
d3c31c52a2 found a better way of deadTime subtraction, fixed inverted signals 2024-09-04 18:03:52 +02:00
PaoloTK
329173e145 added complete validation logic for pins and types 2024-09-04 13:28:43 +02:00
PaoloTK
8e4f8fcbc8 fix bug in reassignment logic 2024-09-04 13:27:04 +02:00
Frank
c1c707c77a 8266 compatibility builds for older chips (another attempt t o solve #3690 and #3685)
some users have reported that releases after 0.14.0 are not working reliably. So we add a few "compat" for 8266 that try to reproduce the buildenv of 0.14.0 as much as possible.

* platform and platform_packages from 0.14.0
* not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
* due to smaller IRAM, we had to move some functions back from IRAM to normal flash (may cause slowdown)
2024-09-04 11:38:03 +02:00
Blaz Kristan
b1e58dd10d Optimisations
- renamed variables
- some tuning
2024-09-03 22:28:21 +02:00
Damian Schneider
2cc0aceac7 Bugfixes
- fixed maxBri value
- fixed overflow in dead time subtraction
- deadtime and offset now also work if signals are inverted (_reversed)
2024-09-03 19:14:50 +02:00
PaoloTK
d79d5dbadd remove getReadOnlyPins() function 2024-09-03 17:29:38 +02:00
Damian Schneider
be7475fe66 bugfixes, removed debug printout 2024-09-02 22:06:46 +02:00
Damian Schneider
85e2f7eb34 fixed offsets and inverted signal plus dead time 2024-09-02 17:53:15 +02:00
PaoloTK
9bb979f2e8 bug fix 2024-09-01 21:46:30 +02:00
PaoloTK
c942345453 bug fix 2024-09-01 21:35:09 +02:00
PaoloTK
fcc344ba99 add read/only pin logic and check 2024-09-01 21:31:19 +02:00
Blaz Kristan
a3b28871c6 Dirty fix for newer framework 2024-09-01 12:27:41 +02:00
Blaz Kristan
2ca034bfa8 Remove ledc_set_duty_and_update
Add semaphoring
Determine CCT overlap
2024-09-01 11:43:22 +02:00
Blaz Kristan
0d035a08d6 Dithering support & bugfix in UI
Thanks to @dedehai & @zalatnaicsongor
2024-08-30 15:21:16 +02:00
PaoloTK
6655e2664e rebase to bus-config 2024-08-29 13:18:48 +02:00
Blaz Kristan
c51ce2eec7 Fix C/P error
Clarifications
2024-08-27 21:57:00 +02:00
Blaz Kristan
b2e00eb868 Introduce network type (previous virtual)
- phase shifting correction (limit to PWM CCT)
2024-08-27 14:11:56 +02:00
Blaz Kristan
820df0c596 PinManager update
- LEDC: allocate same timer for CCT PWM
- use SOC constants
BusManager update
- use allocateMultiplePins for BusPwm
2024-08-27 00:21:24 +02:00
Blaz Kristan
865e3dcd0c getNumberOfPins 2024-08-25 12:53:23 +02:00
Blaz Kristan
f55e2fc7b8 Merge branch '0_15' into bus-config 2024-08-25 12:41:16 +02:00
Blaž Kristan
cb22e1933e Merge pull request #4111 from DedeHai/0_15_PWM_CIEbrightnesscalc
replaced PWM LUT with calculation
2024-08-25 12:36:23 +02:00
Blaz Kristan
8818a9e82a Remove erroneous debug 2024-08-24 11:41:23 +02:00
Blaz Kristan
dbb47d506c Bus manager rework
- move macros to constexpr methods
- introduce type capabilities for UI
- add phase shifting (POC) to PWM
- replace PWM CIE LUT with calculated curve
CIE & phase shifting credit @dedehai
2024-08-24 11:35:32 +02:00
Blaž Kristan
e4d5d77347 Merge pull request #4114 from ChuckMash/struct-def
Demystified some byte definitions of WiZmote ESP-NOW message
2024-08-23 07:13:48 +02:00
ChuckMash
dd52124765 Added some byte definitions to WiZmote ESP-NOW message 2024-08-22 20:24:03 -07:00
Blaz Kristan
6f3267aee9 Dynamic bus config
- provide LED types from BusManager for settings
Credit: @netmindz for the idea.
2024-08-22 17:15:12 +02:00
Blaz Kristan
0bbd6b7c4b Minor optimisation
- disable JSON live
- WS error string
- button irelevant check
2024-08-22 17:08:51 +02:00
Damian Schneider
1cc47b02cf use CIE brightness also for ESP8266 2024-08-21 08:06:32 +02:00
Damian Schneider
e7babc071d replaced PWM LUT with calculation 2024-08-20 20:15:17 +02:00
Blaž Kristan
d11ca2e159 Merge pull request #4110 from itCarl/usermod_battery_mqtt_update
Update usermod "Battery" improved MQTT support
2024-08-20 12:51:02 +02:00
Maximilian Mewes
2d6365dc6a Add HA-discovery as config option 2024-08-20 12:37:01 +02:00
Maximilian Mewes
cc24119a59 remove unnecessary comments 2024-08-19 22:22:46 +02:00
Maximilian Mewes
b8f15333d8 update readme.md 2024-08-19 22:12:21 +02:00
Maximilian Mewes
e5a426419c Improve mqtt support, add battery percentage and voltage 2024-08-19 22:07:08 +02:00
Blaž Kristan
8a1df1e700 Merge pull request #4093 from axlan/pixel-dice-usermod
Added a usermod for interacting with BLE Pixels Dice.
2024-08-19 05:39:35 +02:00
Blaž Kristan
cc298f56e2 Merge pull request #4081 from RobinMeis/0_15
Allow lower values for touch threshold
2024-08-18 13:49:03 +02:00
Robin Meis
665693a513 Remove minimum threshold according to https://github.com/Aircoookie/WLED/pull/4081#issuecomment-2295198219 2024-08-18 13:31:14 +02:00
Blaž Kristan
c35e82e59f Merge branch '0_15' into pixel-dice-usermod 2024-08-18 13:20:45 +02:00
Blaž Kristan
72d38f4cff Merge pull request #3539 from Liliputech/pov_display
Added POV image effect
2024-08-18 13:15:34 +02:00
Blaz Kristan
f6c47ac19c Fix some compiler warnings 2024-08-18 10:45:16 +02:00
Blaž Kristan
27bec89386 Merge pull request #4106 from srg74/patch-1
correct spelling error xml.cpp
2024-08-17 20:54:58 +02:00
srg74
79b3ce141c correct spelling error xml.cpp 2024-08-17 14:42:44 -04:00
Blaz Kristan
8d00e4d31d Save some tiny amounts of RAM
- use `-D WLED_SAVE_RAM`
2024-08-17 15:09:41 +02:00
Blaž Kristan
8688777ae1 Merge pull request #4103 from netmindz/FX-cleanup
Remove repeating code to fetch audio data
2024-08-16 17:39:49 +02:00
Frank
198aceee07 Merge pull request #4104 from FreakyJ/Fix-Bug-#3809
Fixes #3809 Loxone JSON parser doesn't handle lx=0 correctly
2024-08-16 02:04:00 +02:00
FreakyJ
ee1bf1c221 #3809 Loxone JSON parser doesn't handle lx=0 correctly 2024-08-15 20:18:06 +02:00
Will Tatam
24ecf1a166 Move getAudioData to static 2024-08-15 17:58:19 +01:00
Frank
5cb49c86a0 Merge pull request #4090 from willmmiles/ino-to-cpp
Rename wled00.ino to wled_main.cpp
2024-08-15 18:23:53 +02:00
Blaz Kristan
9940d2590b Arc expansion getPixelColor fix. 2024-08-15 17:22:59 +02:00
Blaz Kristan
577fce69e2 MQTT unification and cleanup 2024-08-15 16:18:34 +02:00
Will Tatam
e68375a71e Remove repeating code to fetch audio data 2024-08-15 09:08:57 +01:00
Blaž Kristan
fe7fb6c7a9 Merge pull request #4092 from Aircoookie/sm16825
SM16825 support
2024-08-14 22:21:01 +02:00
Blaz Kristan
cec67d8eff Const and 2D box blur
- added 2D blur
2024-08-14 22:15:48 +02:00
Frank
2443e2ec7c wled00 -> wled_main 2024-08-14 11:16:46 +02:00
Frank
bcf862044a Update wled00.cpp
* added #include <Arduino.h> - this is basically what the preprocessing tool (wled.ino -> wled00.ino.cpp) does
* added a comment that Arduino IDE is not supported, use platformIO.
2024-08-13 22:21:21 +02:00
jdiamond
b73f049484 Clean up addEffect() changes. 2024-08-13 04:40:59 +00:00
jdiamond
cde5314d41 Add "dice" to environment names, and add more information about fitting in a 4MB partition. 2024-08-11 01:23:41 +00:00
Arthur Suzuki
ed5eb28228 Added POV image effect
Setup is really easy, after first boot and WiFi/LEDs setup:
go to wled.local/edit and upload a couple image to WLed's filesystem.
Only PNG is supported right now, further support for GIF is planned.
The image should be as wide as the 1D segment you want to apply to.

When done, go to the Effect page on the UI, select "POV Image" effect.

You could also update the image with a post to the JSON-API like this:
curl -X POST http://[wled]/json/state -d '{"seg":{"id":0,"fx":114,"f":"/axel.png"}}'

The segment should move at around 120RPM (that's 2revolutions per seconds) for an image to showup.
More informations and pictures here : https://lumina.toys
2024-08-10 00:03:55 +02:00
Frank
db5e66a9b0 playing with Fire2012
* speedup: add functions to only blur rows or columns (50% faster)

* fire2012: tinkering with bur options. Vertical blur only when slider < 64 (faster); extra blur for  slider values >192 (bush burn)
2024-08-09 12:53:41 +02:00
jdiamond
96c7716d3e Added a usermod for interacting with BLE Pixels Dice. 2024-08-08 03:13:33 +00:00
Blaz Kristan
ea80c1ed83 Swap WW & CW 2024-08-07 22:39:31 +02:00
Blaž Kristan
7d7b7c1e25 Merge pull request #4088 from willmmiles/stress-testing-scripts
Add stress testing scripts
2024-08-05 21:05:42 +02:00
Blaž Kristan
9d860c265c Merge pull request #4089 from willmmiles/improved-locking
Improve jsonBufferLock management
2024-08-05 21:04:24 +02:00
Blaz Kristan
d234b4b0f1 SM16825 support
- add WW & CW swapping
2024-08-05 20:56:12 +02:00
Blaz Kristan
e82f38e277 Tuning 2024-08-05 16:42:21 +02:00
Will Miles
1d27aa2f18 Move .ino to .cpp
This fixes platformio continually recompiling this file.
2024-08-04 15:47:02 -04:00
Will Miles
113dbbdf94 Use DEBUG_PRINTF_P for jsonBufferLock
Tiny code space usage reduction.
2024-08-04 15:27:23 -04:00
Will Miles
e701b5b5eb util: Print locking module when JSON lock fails
For debugging, also log who was trying to lock when it was contended.
2024-08-04 15:27:23 -04:00
Will Miles
6f01896d04 requestJSONBufferLock: Fix locking implementation
On ESP8266, it isn't permissible to call delay() in system context;
ensure this is legal before waiting.

On ESP32, use an operating system mutex to ensure consistent variable
state in a multicore environment, and manage the wait without needing
to loop.
2024-08-04 15:27:18 -04:00
Will Miles
5582bbac60 stress_test: Add code for logging responses 2024-08-04 13:47:37 -04:00
Blaz Kristan
690811bbbd Merge branch '0_15' into debug-refactor 2024-08-04 17:13:00 +02:00
Blaž Kristan
d2401a212a Merge pull request #4082 from PaoloTK/fix_esp32c3_pwm_bit_depth
Fix incorrect PWM bit depth on Esp32 with XTAL clock
2024-08-04 17:10:21 +02:00
Blaz Kristan
52548542d2 Remove clock/max bit overrides
Move contants into bus manager
2024-08-04 17:05:47 +02:00
Will Miles
509cbdf476 Add UDP test code
Courtesy of @_tvk_ on Discord
2024-08-04 09:57:01 -04:00
Will Miles
5a6ebd6657 stress_test: Allow replication argument 2024-08-04 09:57:01 -04:00
Will Miles
541d3f286a stress_test: Make it worse
Read 40 copies!
2024-08-04 09:57:01 -04:00
Will Miles
0191af412b stress_test: Add small JSON target
Good for measuring quick response performance
2024-08-04 09:57:01 -04:00
Will Miles
abcd2a2d01 tools/stress_test: Allow command line target spec 2024-08-04 09:57:01 -04:00
Will Miles
91efcb910b stress_test: Add a larger JSON target 2024-08-04 09:57:01 -04:00
Will Miles
e9b7320d1c Add preliminary web stress test script 2024-08-04 09:57:01 -04:00
PaoloTK
779744bd8e typo in comment 2024-08-03 15:56:29 +02:00
PaoloTK
1123d85fd2 removed float math and log(), added max bit width 2024-08-03 15:54:39 +02:00
PaoloTK
5c247d2833 first implementation 2024-08-01 20:25:18 +02:00
Robin Meis
17fdb4f5c9 Allow lower values for touch threshold 2024-08-01 19:49:47 +02:00
Frank
ef8f23ce90 Merge pull request #4073 from axlan/devcountainer-runargs
Add example runArgs to devcountainer to access serial port (for firmware upload) directly from the devcontainer.
2024-07-30 12:45:16 +02:00
jdiamond
050f7ebddf Add note for Windows. 2024-07-29 18:00:46 +00:00
jdiamond
10fdf46410 Clarify security implicatations. 2024-07-29 17:34:10 +00:00
Blaž Kristan
49976ae35a Merge pull request #4078 from apanteleev/fire-blur-control
Add a parameter for blur amount in the Fire 2012 effect
2024-07-29 07:31:33 +02:00
Frank
21afb05409 Merge pull request #4077 from adrianschroeter/0_15
2DGEQ: Getting same sized bar width on 32x32 display, and better distribution of bar width in general.
2024-07-28 17:35:08 +02:00
Alexey Panteleev
0af1ec3bde Added a parameter for blur amount in the Fire 2012 effect. 2024-07-27 12:33:59 -07:00
Adrian Schröter
343d766ddd 2DGEQ: Getting same sized bar width on 32x32 display
before a x=32 (n times of 16) had not equal sized bars, but first was
a single pixel and later a bar had 3 pixel width. This solves it to
have always 2 pixel sized bars.

I have to admit that I did not test with other pixel dimensions.
2024-07-27 12:44:16 +02:00
jdiamond
02cae2e61e Add example runArgs to devcountainer to access serial port. 2024-07-25 04:47:44 +00:00
Blaz Kristan
876202c7cc Merge branch '0_15' into debug-refactor 2024-07-24 14:17:46 +02:00
Frank
42decbddd9 Merge pull request #4060 from DedeHai/0_15_bootdelay
boot-up delay to fix wifi not starting in some setups

use
`-D WLED_BOOTUPDELAY=500` (or some other delay you want, in milliseconds)
in platformio env definition to add 500ms of delay before hardware init.
2024-07-22 11:25:00 +02:00
Blaz Kristan
b6cf58f15d Merge branch '0_15' into debug-refactor 2024-07-18 20:25:43 +02:00
Blaz Kristan
b71467b9be LED settings remove output bugfix 2024-07-17 22:24:08 +02:00
Damian Schneider
ac503ef72e adding boot-up delay define
use
-D WLED_BOOTUPDELAY=500
in platformio env definition to add 500ms of delay before hardware init.
2024-07-17 18:54:33 +02:00
Frank
ea608cecb0 Merge pull request #3962 from gaaat98/esp8266-audioreactive-sync
ESP8266 audioreactive UDP sound sync ported from MoonModules/WLED - receive only
2024-07-13 10:16:07 +02:00
Frank
2e266ec945 use fixes-size stack buffer
... protected against array overflow due to previous "if (packetSize <= UDPSOUND_MAX_PACKET)"
2024-07-13 09:55:59 +02:00
Blaž Kristan
bec1adf7ad Merge pull request #4035 from willmmiles/esp8266_pwm_fix 2024-07-13 07:13:09 +02:00
Will Miles
2fc2f47d06 ESP8266PWM: Annotate sources
Add additional clarification as to the original source URL and the
specific local patches.
2024-07-12 19:16:31 -04:00
Frank
3a8e19d1b4 audiosync receive improvements (maintainer edit)
* fixed a few typo's in comments
* fixed 8266 specific warning about 'comparison of integer expressions of different signedness'

based on recommendations made by @willmmiles:
* make sure that audioSyncPacket is the same size  (44bytes) on all platforms
* use static buffer for receiving (avoids heap fragmentation)
* copy receive buffer to local audioSyncPacket struct - avoids alignment problems
* esp32 only: to stay in sync with UDP, Udp.flush() is needed when Udp.parsePacket() is _not_ followed by Udp.read()
2024-07-12 22:09:52 +02:00
gaaat98
cc9db0220c removed audioreactive usermod build flag 2024-07-12 16:59:08 +02:00
Blaz Kristan
d04a164db5 Merge branch '0_15' into debug-refactor 2024-07-11 21:29:30 +02:00
Blaz Kristan
cd1ede38a7 Size & speed optimisations 2024-07-11 21:22:58 +02:00
Blaž Kristan
1ec68c428a Merge pull request #4051 from Nickbert7/patch-1
Fix typo in "Battery" usermod (Build Failed)
2024-07-11 18:52:30 +02:00
Niklas Fäth
f6ed3bc9db Fix typo in "Battery" usermod (Build Failed) 2024-07-11 13:56:33 +02:00
Blaz Kristan
34cdda2e28 Merge branch '0_15' of https://github.com/aircoookie/WLED into 0_15 2024-07-10 15:08:34 +02:00
Blaž Kristan
6417193986 Merge branch '0_15' into debug-refactor 2024-07-10 14:27:51 +02:00
Blaž Kristan
2ccc897532 Separate different debug components
- generic (WLED_DEBUG)
- FX (WLED_DEBUG_FX)
- bus manager (WLED_DEBUG_BUS)
- pin manager (WLED_DEBUG_PINMANAGER)
- usermods (WLED_DEBUG_USERMODS)
- math (WLED_DEBUG_MATH)
- all (WLED_DEBUG_ALL)

In an attempt to reduce flash usage while still getting a few debug messages.
2024-07-10 14:21:44 +02:00
Blaž Kristan
4ab2c907f5 Merge pull request #4048 from willmmiles/mpu6050-crash-fix
Mpu6050 usermod crash fix
2024-07-10 06:31:41 +02:00
Will Miles
8632d99341 MPU6050: Fix crash when enabling
Avoid reconfiguring the device during web server context, which can
trigger a yield().  Instead defer the device initialization to loop().
2024-07-09 18:49:53 -04:00
Blaz Kristan
efa32ed4f6 Size optimisations 2024-07-09 21:50:27 +02:00
Blaz Kristan
551b8af76d Hide 2D effects on 1D segments 2024-07-09 19:00:32 +02:00
Blaz Kristan
887254f5da Bugfixes
- LED memory calculation (not UI)
- potential fix for #4040
- compiler warning in FX
2024-07-07 14:18:51 +02:00
Blaz Kristan
5874b78349 Bugfixes
- FX: Breathe, Meteor
- IR: use Segment
- UI: palette search, LED settings
2024-07-05 21:22:05 +02:00
Blaž Kristan
a812fc07f2 Merge pull request #4033 from adamsthws/0_15_internal_temp_usermod_improvement_new
Usermod Updated: Internal Temperature V2
2024-07-03 07:12:52 +02:00
Adam Matthews
78e7312adf Update usermod internal temperature
Enabled the storing the currently active preset or playlist for it to be restored later
2024-07-01 00:26:03 +01:00
Blaz Kristan
693bf4816b Minor tweaks. 2024-06-30 10:44:25 +02:00
Blaz Kristan
b8b11880b0 Merge branch 'main' into 0_15 2024-06-29 20:27:37 +02:00
Blaz Kristan
0ff4016250 WLED 0.15.0-b4 release
- LED settings update (limit to available outputs)
- minor fixes
2024-06-29 20:22:47 +02:00
Blaz Kristan
e753f3849e Revert "WLED 0.15.0-b4 release"
Messed FX_fcn.cpp CRLF conversion
2024-06-29 20:18:30 +02:00
Blaz Kristan
7b248c8fb2 WLED 0.15.0-b4 release
- LED settings update (limit to available outputs)
- minor fixes
2024-06-29 16:36:27 +02:00
Blaž Kristan
f0e4dd90ee Merge pull request #4013 from wesleygas/0_15
Add LD2410 sensor usermod
2024-06-29 16:21:21 +02:00
Blaž Kristan
c540ec5417 Update readme.md 2024-06-29 16:17:46 +02:00
Blaž Kristan
3615ab535b Merge pull request #4028 from Aircoookie/dependabot/pip/urllib3-1.26.19
Bump urllib3 from 1.26.18 to 1.26.19
2024-06-29 16:11:39 +02:00
Blaž Kristan
b8d6ebe882 Merge pull request #4023 from Aircoookie/dependabot/npm_and_yarn/braces-3.0.3
Bump braces from 3.0.2 to 3.0.3
2024-06-29 16:11:26 +02:00
Blaž Kristan
1f27872294 Merge pull request #3995 from Aircoookie/dependabot/pip/requests-2.32.0
Bump requests from 2.31.0 to 2.32.0
2024-06-29 16:10:58 +02:00
Adam Matthews
3815516022 Fixes to feature update for Internal Temperature usermod
Simplified the code by removing an unnecessary function definition and instead using direct assignment in the place where the function was previously called.
2024-06-28 16:12:56 +01:00
Adam Matthews
a1dfdced31 Fixes to feature update for Internal Temperature usermod
- Updated all doubles to floating-point literals by adding explicit `f` suffix

- Removed all remaining html from readme markdown documentation.
2024-06-28 15:47:54 +01:00
Will Miles
ff39a8db3f Fix PWM crashes on ESP8266
Vendor in the ESP8266 Arduino core PWM library, with a fix for a nasty
NMI crash bug.  Sometimes the NMI return instruction seems to fail,
resulting in an infinite loop as the PC gets stuck.  Work around this
by backing up and restoring the PC if needed.
2024-06-27 21:30:05 -04:00
Adam Matthews
9877e899e0 Fixed images in readme
Github flavoured markdown didn't work as expected.
2024-06-27 17:52:41 +01:00
Adam Matthews
bc4a6138b1 Fixes to feature update for Internal Temperature usermod
Applied various fixes as advised by @blazoncek

Thankyou for the advice!

- Updated float: 95.0 > 95.0f

- Updated type: const > constexpr

- Comments clarified

- Preset setting: `-1` > `0`
2024-06-27 17:33:37 +01:00
Adam Matthews
f825cab54a Usermod Updated: Internal Temperature V2
# Added high temperature indicator/action...

- A configurable preset is activated when the internal temperature raises above a configurable threshold temperature.

- When the internal temperature falls back below the threshold, the previously active preset is re-activated.

- To prevent frequent toggling between states when the temperature is close to the threshold, the reset threshold is slightly lower than the activation threshold to provide a small buffer.

- Reset threshold is automatically calculated to be two degrees lower than whatever the activation threshold is set to.

- To prevent the user setting the loop interval too low, a minimum allowable interval has been added.
2024-06-26 20:27:53 +01:00
Blaž Kristan
57b01c2711 Merge pull request #4030 from rorosaurus/0_15
add ETH support for LILYGO-POE-Pro
2024-06-26 12:01:36 +02:00
Blaž Kristan
5f3e3d7796 Merge pull request #4017 from xkvmoto/patch-2
Update usermod_sn_photoresistor.h
2024-06-26 11:56:15 +02:00
Blaz Kristan
d13b8c8421 Move LED_BUILTIN handling to BusManager class
- reduce max panels
2024-06-23 14:09:18 +02:00
Blaz Kristan
0af3063127 Enhancements
- edit WiFi TX power (ESP32)
- keep current ledmap ID in UI
- limit outputs in UI based on length
- wifi.ap addition to JSON Info
- relay pin init bugfix
- file editor button in UI
2024-06-23 14:08:18 +02:00
Rory Hayes
17e1975dd8 add ETH support for LILYGO-POE-Pro
Also includes minor spelling corrections for CONTRIBUTING.md
2024-06-18 16:07:46 -07:00
dependabot[bot]
166eeacab9 Bump urllib3 from 1.26.18 to 1.26.19
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.18 to 1.26.19.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.19/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.18...1.26.19)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-18 01:26:00 +00:00
dependabot[bot]
017169f1a1 Bump braces from 3.0.2 to 3.0.3
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-16 12:12:05 +00:00
Blaz Kristan
ed0e73803f Minor tweaks for ESP8266
- update was restarting device on some occasions
- a bit of throttling in UI
2024-06-14 22:12:09 +02:00
Blaz Kristan
f4475b9d2a Dynamic parallel I2S output
- update NeoPixelBus to v2.8.0
- use single/mono I2S + 4x RMT for 5 outputs or less
- use parallel x8 I2S + 8x RMT for >5 outputs (limit of 300 LEDs per output)
2024-06-12 18:00:00 +02:00
xkvmoto
8a1df9afee Update usermod_sn_photoresistor.h
Allow to configure the analog input pin for the Photoresistor.
2024-06-07 19:50:45 +02:00
wesleygas
9cfb56d9c6 Add LD2410 sensor usermod 2024-06-04 21:39:31 -03:00
Blaz Kristan
25ade86994 Filter/sort bugfix 2024-06-04 17:05:11 +02:00
Blaz Kristan
c10ec2962b Fix custom palette reorder on search 2024-06-02 21:25:05 +02:00
Blaž Kristan
1bb06106fd Merge pull request #4001 from DevilPro1/smartnest
Fixed code of Smartnest and updated documentation
2024-06-01 17:52:55 +02:00
Blaž Kristan
bc18cdbeea Merge pull request #4010 from cstruck/fix_esp32_s3_zero_wifi_not_working
fix: esp32 s3 zero rev v0.2 wifi not working
2024-06-01 14:43:33 +02:00
Christian Struck
67df5d6dcc fix: ESP32-S3 rev v0.2 seems to need the wifi fix 2024-06-01 09:09:01 +02:00
Blaz Kristan
68a7282b27 Speed and size optimisations in FX.cpp
- replace uint8_t and uint16_t with unsigned
- replace in8_t and int16_t with int
- reduces code by 1kB
- WARNING may break effects that rely on overflow/narrow width (most fixed)
2024-05-31 15:58:18 +02:00
Blaz Kristan
5732b66c5a Add UI error description. 2024-05-31 15:50:10 +02:00
devilpro1
f1cce8ef46 Update readme.md 2024-05-29 20:14:12 +02:00
devilpro1
e47932c9aa Update usermod_smartnest.h 2024-05-29 20:13:37 +02:00
Blaž Kristan
3a70fb0e15 Merge pull request #3897 from muebau/fix_usermod_tetisai
reset usermod TetrisAI back to initial version
2024-05-27 20:22:26 +02:00
muebau
d5da84dcb2 add more information of the partition table to readme 2024-05-27 18:36:48 +02:00
muebau
1bd051d703 fixed link to partition table 2024-05-27 18:15:39 +02:00
muebau
abb55f8e4b center the canvas if the segment exceeds the maximum width or height 2024-05-27 13:29:03 +02:00
muebau
46f6a257d0 fixed another throw statement 2024-05-26 22:08:01 +02:00
muebau
97e4eec5be avoid exceptions to stay compatible with ESP8266
add limitaion information to readme
2024-05-26 21:00:13 +02:00
muebau
69b99abb7d improved readme 2024-05-26 15:46:23 +02:00
devilpro1
08f6d5a683 Add files via upload 2024-05-26 12:46:45 +02:00
devilpro1
627bea30ed Delete usermods/smartnest directory 2024-05-26 12:46:34 +02:00
muebau
caf0a5bbe8 changed the last double variables and values to float and add more hints to readme 2024-05-26 11:01:57 +02:00
Blaz Kristan
501f988b0f ESP-NOW usermod hook 2024-05-25 20:01:38 +02:00
muebau
5f0c6fce74 fixed static or global variables
use of strip.now instead of millis()
use float instead of double
respond to changes in segment size
make effect usable with multible segments
2024-05-23 18:51:55 +02:00
muebau
78089107b7 Merge remote-tracking branch 'upstream/0_15' into fix_usermod_tetisai 2024-05-23 16:15:35 +02:00
Blaž Kristan
f3b0906cea Merge pull request #3993 from gsieben/0_15
Update wled.h regarding OTA Password
2024-05-21 21:22:35 +02:00
Blaž Kristan
9f581c6181 Merge pull request #3994 from gsieben/0_15-Usermod-BME68X-Pull-Request
Usermod BME68X Sensor Implementation rebased for WLED 0.15
2024-05-21 21:20:47 +02:00
Blaž Kristan
31b232d3f3 Merge pull request #3977 from LordMike/feature/aht10_usermod
Add a usermod for AHT10, AHT15 and AHT20 temperature/humidity sensors
2024-05-21 21:20:03 +02:00
Blaž Kristan
77e6a6de61 Revert .gitignore 2024-05-21 18:23:25 +02:00
Blaž Kristan
85702a8142 Merge branch '0_15' into feature/aht10_usermod 2024-05-21 18:21:16 +02:00
Blaž Kristan
0bcdc9641d Merge pull request #3968 from adamsthws/0_15_battery_usermod_readme
Update Battery usermod documentation
2024-05-21 18:17:08 +02:00
Blaž Kristan
bfd1bdfc64 Merge branch '0_15' into 0_15-Usermod-BME68X-Pull-Request 2024-05-21 18:14:23 +02:00
Blaž Kristan
c1fed6d469 Merge pull request #3986 from LordMike/feature/ina226_usermod
Add INA226 usermod for reading current and power over i2c
2024-05-21 18:12:03 +02:00
Gabriel Sieben
79ffe021e4 Update usermod_bme68x.h
One error message was in German
2024-05-21 11:41:57 +02:00
dependabot[bot]
a1c348b365 ---
updated-dependencies:
- dependency-name: requests
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-21 05:40:22 +00:00
Gabriel Sieben
904b1f114b Merge branch 'Aircoookie:0_15' into 0_15 2024-05-20 22:30:28 +02:00
Gabriel Sieben
63f481d498 Update wled.h
Accidentally included changes removed.
2024-05-20 22:09:20 +02:00
Gabriel Sieben
fc5c19788e Update usermod_bme68x.h 2024-05-20 14:49:05 +02:00
Gabriel Sieben
56e0bde8ab Rebase of the user mode BME68X sensor in WLED 0.15 2024-05-20 14:45:01 +02:00
Gabriel Sieben
db2cdca71b Revert "First implementation of the user mods for the BME68X sensor in WLED 0.15"
This reverts commit faa2fba6b9.
2024-05-20 14:25:08 +02:00
Gabriel Sieben
faa2fba6b9 First implementation of the user mods for the BME68X sensor in WLED 0.15 2024-05-20 14:10:25 +02:00
Gabriel Sieben
f727ea2874 Update wled.h
OTA_PASS
2024-05-20 13:13:40 +02:00
Blaž Kristan
4a7ef07089 Fix for #3991 2024-05-20 12:24:26 +02:00
Michael Bisbjerg
0df726cdab Add note to platformio override sample 2024-05-18 15:52:01 +02:00
Blaz Kristan
2f6f0d2f3e WLED 0.14.4 2024-05-18 15:17:08 +02:00
Blaz Kristan
fae5938b0a Build bump, changelog update 2024-05-18 13:01:28 +02:00
Blaz Kristan
2ec3639900 Merge branch 'main' into 0_15 2024-05-18 11:24:18 +02:00
Blaz Kristan
4513404629 Fix for #3987 2024-05-18 11:15:16 +02:00
Blaz Kristan
13bfda56ef Auto segment creation bugfix
- additional debug
- minor optimisation
2024-05-18 11:11:40 +02:00
Michael Bisbjerg
075c164407 Fix bug in triggered measurements 2024-05-17 15:03:56 +02:00
Michael Bisbjerg
dcb5049f97 Move to individual settings for samples and conversion time 2024-05-17 14:36:27 +02:00
Michael Bisbjerg
d24cf14009 Triggered & continuous modes 2024-05-17 14:36:27 +02:00
Michael Bisbjerg
3d34802ab2 Initial ina226 2024-05-17 14:36:27 +02:00
Blaz Kristan
2aec21a6d0 Palette loading optimisation
- fixes #3978
- FX: Firenoise can use selected palette
2024-05-16 06:23:15 +02:00
Adam Matthews
19ccff9ff1 Merge branch '0_15' into 0_15_battery_usermod_readme 2024-05-15 22:15:18 +01:00
Michael Bisbjerg
1dd9c6754c Cleanup unecessary struct 2024-05-15 21:32:08 +02:00
Michael Bisbjerg
f9467ceaf1 Fix state issue on change reporting, add override sample ini 2024-05-15 21:26:30 +02:00
Michael Bisbjerg
f51da4f0c4 Change reporting to be on significant changes 2024-05-15 18:56:45 +02:00
Michael Bisbjerg
2eff389fff Handle feedback
- Reduce some strings
- Use an unnamed struct to pack the bitfield instead
2024-05-15 18:44:36 +02:00
Blaz Kristan
77ca2ec0e9 Compiler warning fix 2024-05-15 15:35:14 +02:00
Blaz Kristan
77e6ea8a6f Palette loading optimisation
- fixes #3978
- FX: Firenoise can use selected palette
2024-05-15 15:34:53 +02:00
Frank
e33299bbd7 Merge pull request #3961 from Brandon502/0_15
Added Pinwheel Expand 1D ->2D effect mapping mode
2024-05-15 14:22:10 +02:00
Michael Bisbjerg
74e273274c Replace 5 booleans with 1 byte flags field 2024-05-14 23:15:59 +02:00
Michael Bisbjerg
02bf5902f0 Add MQTT and HASS support for AHT10 2024-05-14 22:57:19 +02:00
Blaž Kristan
5f41de8938 Merge pull request #3966 from LordMike/feature/bme280_changeable_i2c
Add changeable i2c address to BME280 usermod
2024-05-14 19:39:42 +02:00
Michael Bisbjerg
f71d839009 Address comments 2024-05-14 18:02:39 +02:00
Brandon502
3cb6b17316 Pinwheel fix 2024-05-14 11:46:52 -04:00
Brandon502
c0cb677a4c Pinwheel cleanup 2024-05-14 11:30:33 -04:00
Frank
a5a6a8eaee pinwheel : fix holes on large matrix, minor code cleanup
there were still two holes in my 52x52 setup --> added "XL" size for bigger than 50x50 - achieves 18fps on 52x52
2024-05-14 11:30:25 +02:00
Frank
ecb861de56 pinwheel code cleanup
reducing code duplication between sPC and gPC
2024-05-14 10:36:50 +02:00
Brandon502
1d20f18d3f Pinwheel bugfix
Fixed getPixelColor.
2024-05-13 17:43:31 -04:00
Michael Bisbjerg
68f6b3452e Initial implementation of the AHT10/AHT15/AHT20 sensors 2024-05-13 23:12:57 +02:00
Michael Bisbjerg
60075f6e8c Avoid storing the settings of bme280 globally 2024-05-13 20:22:31 +02:00
Frank
1d7789f544 pinwheel bugfixing
* setPixelColor: ensure that 0/0 is used
* getPixelColor: accuracy improvements

unfortunately, "scrolling" audioreactive effects are still not working properly - they end after 1/4 of the circle. Could be due to limited resolution of getPixelColor.
2024-05-13 19:27:41 +02:00
Michael Bisbjerg
bd10a9aa26 Change BME280I2C to be reused between configs 2024-05-13 18:35:13 +02:00
Blaz Kristan
1ceeed38bc Another fix for fix :rolleyes: 2024-05-13 14:30:30 +02:00
Brandon502
2e1e917952 Merge branch '0_15' of https://github.com/Brandon502/WLED into 0_15 2024-05-12 17:46:52 -04:00
Brandon502
9e0b91ac17 Pinwheel changes.
Jump distance for odd rays fixed. Removed holes on rectangular matrices.
2024-05-12 17:46:42 -04:00
Frank
ea83ec496b pinwheel - parameter tuning to fix some holes
fixing holes that appeared during testing
* at 52x52 (big 296 -> 304)
* at 24x32 (medium 192 -> 208)
* at 12x16 (small 72 -> 82)

... there is still one hole at 14x16 ... well wtf
2024-05-12 23:05:58 +02:00
Frank
f26bb26ffa Update FX_fcn.cpp
* minor cleanup, moved prevRay into setPixelColor
* removed experimental code (too slow)
* comments cleanup
2024-05-12 22:35:33 +02:00
Frank
28348f919b Merge branch '0_15' into pr/3961 2024-05-12 21:30:59 +02:00
Brandon502
c84d4c637d Pinwheel Expand 1D Optimization
Changed method for drawing odd numbered rays.
2024-05-12 11:52:31 -04:00
Blaz Kristan
04706cfa9c JS fix & warning 2024-05-12 16:34:07 +02:00
Frank
3078bea7cc Pinwheel optimization: do nor repaint "same" pixels in a line
avoids back to back duplicates within the same line
2024-05-12 13:29:04 +02:00
Frank
c91e0fc988 Merge branch '0_15' into pr/3961 2024-05-12 13:25:46 +02:00
Blaž Kristan
5183af4e8a Typo. 2024-05-12 11:30:57 +02:00
Blaž Kristan
1ff5cb0596 Experimental parallel I2S support for ESP32
- increased outputs to 17
- increased max possible color order overrides
- use WLED_USE_PARALLEL_I2S during compile

WARNING: Do not set up more than 256 LEDs per output when using parallel I2S with NeoPixelBus less than 2.9.0
2024-05-12 11:12:13 +02:00
Blaž Kristan
522e5e7957 Merge pull request #3964 from adamsthws/0_15_battery_usermod_init_improvement
Update Usermod: Battery
2024-05-11 21:11:26 +02:00
Brandon502
9e468bd059 Pinwheel Expand 1D Optimizations
Added small pinwheel size. Adjusts medium and large values.
2024-05-11 13:57:21 -04:00
Frank
ecc9443677 (0_14 branch only) adding compatibility for building with upstream arduinoFFT 2.xx
support compilation with new arduinoFFT versions 2.x
2024-05-11 14:45:42 +02:00
Adam Matthews
6b8d8bf735 Update Battery usermod documentation
Improved wiring, installation and calibration instructions.

Example screenshots added.

Minor grammar improvements.

Heading visual consistency improved.

Improved vertical separation between sections
(separator lines added).

Thankyou!
2024-05-11 13:34:35 +01:00
Michael Bisbjerg
43d024fe42 Make BME280 usermod i2c address changeable 2024-05-11 12:23:53 +02:00
Blaž Kristan
c016dedea4 Merge pull request #3965 from LordMike/bugfix/usermod_bme280 2024-05-11 07:42:09 +02:00
Michael Bisbjerg
b9ca2cfe90 Fix missing conversions of bme280 values
The BME280 usermod uses a multiply-round-divide approach to cap the temperature/humidity/pressure values to some number of decimals. But the divide-part was missing in a few instances.
2024-05-10 22:44:46 +02:00
Brandon502
d3492b5b6c Pinwheel Expand 1D Bug Fix
Removed holes on 31x31 and 32x32 grids.
2024-05-10 16:06:37 -04:00
Blaž Kristan
3682cd6a5e Merge pull request #3913 from Aircoookie/tm1914
Tm1914 chip support
2024-05-10 21:44:40 +02:00
Blaz Kristan
b209b1e481 Peek on/off fix 2024-05-10 16:01:47 +02:00
Blaz Kristan
4afed48f58 Use libc trigonometric functions on ESP32 by default
- use custom (space saving) functions on ESP8266
2024-05-10 15:59:11 +02:00
Brandon502
6a18ce078e Pinwheel Expand1D changes
cosf/sinf changed to cos_t/sin_t. int_fast32_t and int_fast_16_t changed to int.
2024-05-09 20:38:41 -04:00
Adam Matthews
bc5aadff7d Update Usermod: Battery
Issue:
When taking the initial voltage reading after first powering on, voltage hasn't had chance to stabilize so the reading can be inaccurate, which in turn may incorrectly trigger the low-power preset. (Manifests when the user has selected a low read interval and/or is using a capacitor).

Resolution:
A non-blocking, fixed 10 second delay has been added to the initial voltage reading to give the voltage time to stabilize.

This is a reworked version of the (now closed) PR here:
https://github.com/Aircoookie/WLED/pull/3959

- Rebased the update for 0_15.

- Added a constant so the delay can be modified via my_config.h.

- Small adjustments to make the PR compatible again after the recent restructuring in this PR: (https://github.com/Aircoookie/WLED/pull/3003).

Thankyou!
2024-05-09 23:09:45 +01:00
Blaz Kristan
de89b516dc Merge branch '0_15' of https://github.com/aircoookie/WLED into 0_15 2024-05-10 00:04:43 +02:00
Blaz Kristan
4dbe9a7015 Antialiased line & circle 2024-05-10 00:02:28 +02:00
Blaz Kristan
a320f16404 Real math fix 2024-05-09 23:58:58 +02:00
gaaat
cec7241986 removed commented variables 2024-05-08 15:42:41 +02:00
gaaat
6de77293ad Merge branch '0_15' of https://github.com/Aircoookie/WLED into esp8266-audioreactive-sync 2024-05-08 15:36:10 +02:00
gaaat
0ac53d8353 initial port of MoonModules/WLED/pull/60 and related commit 2024-05-08 15:33:51 +02:00
Brandon502
da79b93387 Added Pinwheel Expand 1D Effect 2024-05-07 18:04:29 -04:00
Frank
b88c300d04 audioreactive: workaround for ArduinoFFT bug 93
This fix works around a problem that was solved in upstream ArduinoFFT 2.0.2
2024-05-07 23:38:19 +02:00
Blaz Kristan
88372cd516 Brighter peek (ignore strip brightness) 2024-05-07 16:34:15 +02:00
Blaž Kristan
b3206121cc Merge pull request #3942 from gaaat98/audioreactive-analog
Enabled some audioreactive effects for single pixel strips/segments
2024-05-07 07:35:46 +02:00
gaaat98
5bccb5fc42 removed commented checks 2024-05-07 00:31:37 +02:00
Blaž Kristan
47e1cbdaff Merge pull request #3003 from itCarl/usermod-battery-update2023
Usermod Battery 🔋 Added Support for different battery types, Optimized file structure
2024-05-06 20:41:00 +02:00
Maximilian Mewes
52020cbe26 CP fix 2024-05-06 17:46:26 +02:00
Maximilian Mewes
d33651c25b Update setup method 2024-05-06 17:45:02 +02:00
Maximilian Mewes
18e9f9c304 Rename Battery classes 2024-05-06 17:39:40 +02:00
Frank
2607c44fbb make objdump work
Script update based on latest version from Tasmota
* add support for all esp32 variants
* add "-C" : Decode (demangle) low-level symbol names into user-level C++ names.
2024-05-06 11:00:41 +02:00
gaaat
c8a7d44f55 Merge branch '0_15' of https://github.com/Aircoookie/WLED into audioreactive-analog 2024-05-06 00:09:43 +02:00
Frank
a6e536189c output_bin.py : fix for mapfile copy
The build script was not looking into the right place, so there was never a .map file dropped into build_output/map/

Builds with the newer arduino-esp32 v2.0.x framework actually generate a .map file that is placed directly next to firmware.bin
2024-05-05 21:56:01 +02:00
Frank
3f9a6cae53 AR: fix for arduinoFFT 2.x API
in contrast to previous 'dev' versions, the storage for windowWeighingFactors is now managed internally by the arduinoFFT object.
2024-05-04 14:34:23 +02:00
Frank
cd5494fdd2 AR pin config: SCK == 1 --> PDM microphone 2024-05-04 14:12:44 +02:00
Blaž Kristan
5ab1b14d6b Merge pull request #3946 from freakintoddles2/0_15
Adds an API parameter to allow the user to skip to the next preset in a playlist at any time
2024-05-03 23:25:36 +02:00
Todd Meyer
379f181362 Further simplification 2024-05-03 11:51:47 -07:00
Todd Meyer
dd19aa63d0 Forgot F[], added it 2024-05-03 08:47:14 -07:00
Todd Meyer
6df3b417a9 Updated based on more feedback 2024-05-03 08:30:37 -07:00
Blaz Kristan
fa76431dd6 Changelog update 2024-05-03 16:08:20 +02:00
Blaz Kristan
6504fb68b6 Minor MQTT optimisation. 2024-05-03 15:46:16 +02:00
Blaz Kristan
2ff49cf657 Fix for #3952
- included IR optimisations & code rearrangement
2024-05-03 15:45:15 +02:00
Blaž Kristan
fa1aa1fe80 Merge pull request #3944 from paspiz85/pas4
Using brightness in analog clock overlay
2024-05-03 09:56:14 +02:00
Blaž Kristan
85b95a2940 Merge pull request #3945 from w00000dy/Webpage-shortcuts
Add Webpage shortcuts and Fix resizing bug
2024-05-03 09:53:00 +02:00
Todd Meyer
5e38039c4d Updated based on more feedback 2024-05-02 14:36:18 -07:00
Blaz Kristan
4df936a437 Fix for unfortunate prior CRLF coversion. 2024-05-02 10:33:10 +02:00
Blaz Kristan
736a8b1b80 Fix for rotating tablet into PC mode. 2024-05-02 10:31:50 +02:00
Pasquale Pizzuti
22f6128bc4 using global brightness 2024-05-02 09:05:37 +02:00
freakintoddles2
db475b6998 Update playlist.cpp 2024-05-01 10:09:17 -07:00
freakintoddles2
6daf7f6322 Update wled.cpp
reworked based on PR feedback
2024-05-01 10:07:52 -07:00
freakintoddles2
16086c0961 Update wled.h
reworked based on feedback from original PR
2024-05-01 10:05:26 -07:00
freakintoddles2
e88c81ad0d Update set.cpp
reworked based on feedback
2024-05-01 10:04:02 -07:00
freakintoddles2
a2b9aed40d Update playlist.cpp
reworked approach based on feedback
2024-05-01 10:03:16 -07:00
freakintoddles2
caa4fe1ec4 Update json.cpp
reworked approach based on feedback
2024-05-01 10:02:27 -07:00
freakintoddles2
25fb878e54 Update fcn_declare.h
reworked approach based on feedback
2024-05-01 10:01:30 -07:00
freakintoddles2
a1d6ffadad Update json.cpp
adds support for np boolean parameter to skip to next preset
2024-04-30 16:49:52 -07:00
freakintoddles2
3b89814b69 Update set.cpp
added new NP command to API to allow user to skip to next preset in a playlist. Example use is win&NP in a preset.
2024-04-30 16:33:30 -07:00
freakintoddles2
071e0be445 Update fcn_declare.h
Updated to add the optional skipNext bool to handlePlaylist() which allows people to skip to the next preset when desired
2024-04-30 16:23:43 -07:00
freakintoddles2
bed364d75e Update playlist.cpp
Updated to allow a user to optionally skip to the next preset in the playlist anytime they desire.
2024-04-30 16:21:40 -07:00
Woody
d2984e9e16 add Webpage shortcuts, resolves #2362 2024-04-30 18:57:53 +02:00
Maximilian Mewes
05a8c692f2 read initial voltage correctly 2024-04-30 18:11:18 +02:00
Pasquale Pizzuti
fd9570e782 using color_fade 2024-04-30 17:52:35 +02:00
Maximilian Mewes
35d26afcb4 Merge remote-tracking branch 'upstream/0_15' into usermod-battery-update2023 2024-04-30 17:12:08 +02:00
Maximilian Mewes
2245ee6fce bugfixes 2024-04-30 17:02:57 +02:00
Woody
ff10130176 Fix resizing bug
The bug was that when resizing the window, it always jumped to the Colors tab instead of staying on the currently selected tab.
2024-04-30 16:53:47 +02:00
Maximilian Mewes
a13f1a9bee bug fixes 2024-04-30 15:24:02 +02:00
Maximilian Mewes
3cc60fa4d4 Merge branch 'main' into usermod-battery-update2023 2024-04-30 15:01:23 +02:00
Maximilian Mewes
bd69c24231 intermediate update 2024-04-30 14:54:53 +02:00
Pasquale Pizzuti
c7d292a716 using brightness in analog clock overlay 2024-04-30 14:09:12 +02:00
gaaat
74bc159a52 enabled some audioreactive effects for single pixel strips/segments 2024-04-29 20:19:10 +02:00
Frank
9f99a1896d presets.json PSRAM caching: consider cacheInvalidate
* trying to make the caching mechanism bulletproof.
`cacheInvalidate` is changed when
- autosave usermod updates presets
- a file was upload
* (coding style) fixed some unitialized variables
2024-04-29 16:51:27 +02:00
Blaž Kristan
8110259d1c Merge pull request #3892 from askask/pollreply 2024-04-28 09:32:04 +02:00
Frank
1048bf993a use lolin_s3_mini for esp32-S3 4MB buildenv 2024-04-27 23:34:35 +02:00
Blaž Kristan
3eba0f4e0d Merge pull request #3933 from gaaat98/0_15
Improved brightness change via long button presses
2024-04-27 12:53:56 +02:00
gaaat98
d7e0b364d1 fixed wrong comment 2024-04-27 12:25:34 +02:00
Blaz Kristan
25dd43b949 Bugfix for bugfix
- thanks @softhack007
2024-04-26 23:49:34 +02:00
Blaz Kristan
69da2f4b23 Merge branch '0_15' into tm1914 2024-04-26 20:41:56 +02:00
Blaz Kristan
d48bab02a1 Speed & size optimisations using native sized variables 2024-04-26 20:11:46 +02:00
Blaz Kristan
886120fe9f Bugfix
- getPixelColor() for analog
- RMT channel (#3922)
2024-04-26 20:07:27 +02:00
gaaat98
bdd4d9f3ff set buttonBriDirection as local static 2024-04-26 18:23:34 +02:00
gaaat
6276c2f1f5 improved brightness change via long button presses 2024-04-26 16:39:32 +02:00
Blaž Kristan
b3acc97d03 Merge pull request #3920 from Suxsem/relay-3-states
Relay open drain output (allow esp32 to drive 5v relay modules)
2024-04-26 07:06:03 +02:00
Suxsem
24bd1db4fc "X" span near to the number input field 2024-04-26 00:29:48 +02:00
Blaz Kristan
e83d3cb4a3 Fix for #3878 2024-04-24 16:04:54 +02:00
Blaz Kristan
674481f0d1 Multiple fixes
- several compile warning fixes
- multipin LED compile config
- release info (update page, JSON "info")
- WiFi scan fix if no networks found
- UI glitch when no presets are found fix

With multipin LED config it is now possible to assign GPIO to PWM RGB outputs.
Achieved by having length of DATA_PINS be divisble by lengt of PIXEL_COUNTS.
2024-04-23 19:05:49 +02:00
Blaz Kristan
5d271d21bc INI cleanup
added 8M ESP32 and 16M ESP32-S3
2024-04-23 18:55:36 +02:00
Frank
4e4493e627 Merge pull request #3902 from Aircoookie/arduino_2_0_9
update esp32 platform to arduino-esp32 v2.0.9
2024-04-23 15:56:08 +02:00
Frank
1154905818 upgrading WROVER to use new platform 2024-04-23 15:49:39 +02:00
Frank
0d3ea848c2 "big partition" added - 300KB FS and coredump support(from WLEDMM) 2024-04-23 15:27:44 +02:00
Frank
8ffe1e65fd audioreactive: arduino-esp32 up to 2.0.14 still has the swapped-channel-bug 2024-04-23 15:07:08 +02:00
Blaž Kristan
127ea7e351 Fix for #3926 2024-04-23 13:04:17 +02:00
Suxsem
34b16f1919 optimizations 2024-04-21 20:02:00 +02:00
Suxsem
fa32faf759 feat(new): relay open drain output 2024-04-21 13:37:07 +02:00
Blaz Kristan
6f3d7e76c9 Fix for #3919 2024-04-19 22:54:25 +02:00
Frank
57665e8964 audioreactive readme - removed UM_AUDIOREACTIVE_USE_NEW_FFT
The customized library is not needed / supported any more in 0_15.
2024-04-18 12:16:04 +02:00
Blaz Kristan
5c502b1fe4 Bump arduinoFFT, organise partitions 2024-04-17 22:49:33 +02:00
Blaz Kristan
6d1410741d Fix 8266 compile 2024-04-17 19:00:16 +02:00
Blaz Kristan
3e20724058 ArduinoFFT update
shadow variables
2024-04-17 18:52:35 +02:00
Blaž Kristan
197f47befe Merge pull request #3905 from w00000dy/main
Set stale lable to 'stale' and increase operations-per-run in stale.yml
2024-04-16 20:31:16 +02:00
Blaž Kristan
d126611e87 Merge pull request #3904 from DedeHai/FX_fcn_improvements
added improvements to color scaling and blurring
2024-04-16 17:41:20 +02:00
Blaž Kristan
1b75be5710 Update FX_2Dfcn.cpp
Undo indent
2024-04-16 17:37:48 +02:00
Woody
6272969983 Set stale-pr-label & stale-issue-label to 'stale' in stale.yml
Hopefully this fixes the error messages that were thrown the last time the action was executed
2024-04-16 15:07:12 +02:00
Damian Schneider
084fc2fcd1 bugfix & code formatting, removed color_scale
also replaced scale8_video with 32bit calculation in color_fade for consistency and speed.
2024-04-16 10:43:06 +02:00
Woody
b2e68db380 Increase operations-per-run in stale.yml again 2024-04-15 22:56:38 +02:00
Damian Schneider
459156fe57 added improvements to color scaling and blurring
-changes save roughly 600bytes of flash
-made blurring faster by not writing the color and then reading it back but keeping it as a variable: on a C3, FX black hole goes from 55FPS to 71FPS
-added optional parameter to blur (smear) that can be used in combination with SEGMENT.clear(), blurring the frame without dimming the current frame (repeated calls without clearing will result in white). this is useful to blur without 'motion blurring' being added
-scale8 is inlined and repeated calls uses flash, plus it is slower than native 32bit, so I added 'color_scale' function which is native 32bit and scales 32bit colors (RGBW).
2024-04-15 21:20:45 +02:00
Blaz Kristan
7abfe68458 Add support for TM1914 chip 2024-04-15 16:13:13 +02:00
Frank
442d7a7226 arduino-esp32 v2.0.9 2024-04-15 14:08:28 +02:00
Blaž Kristan
80ebcb2c28 Merge pull request #3901 from w00000dy/main
Increase operations-per-run in stale.yml
2024-04-14 15:47:31 +02:00
Woody
cd928bc586 Increase operations-per-run in stale.yml
Because of this we don't need to run this action 3 times a day
2024-04-14 13:14:03 +02:00
dependabot[bot]
d2b4d25317 Bump idna from 3.4 to 3.7 (#3895)
Bumps [idna](https://github.com/kjd/idna) from 3.4 to 3.7.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst)
- [Commits](https://github.com/kjd/idna/compare/v3.4...v3.7)

---
updated-dependencies:
- dependency-name: idna
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-13 19:38:03 +02:00
Woody
a418cd2a2a Activate stale (#3898)
* Update stale.yml

Update pr text
Schedule action 3 times a day

* Delete old .github/stale.yml

* Set exempt-all-milestones to true in stale.yml
2024-04-13 19:37:49 +02:00
Blaz Kristan
94cdd88474 Version bump B3
- fix for #3896
- fix WS2815 current
- conditional AA setPixelColor()
2024-04-13 18:25:25 +02:00
muebau
1bdf3876fc reset usermod TetrisAI back to initial version 2024-04-12 12:00:15 +02:00
Blaz Kristan
30435e6406 2D compile fix 2024-04-11 20:11:29 +02:00
Blaz Kristan
bd1c06a7a7 Changelog update 2024-04-10 20:06:46 +02:00
Blaž Kristan
8358272b9a Merge pull request #3876 from w00000dy/main
Create new stale.yml
2024-04-10 19:42:52 +02:00
Blaž Kristan
ff3cce0ed2 Merge pull request #3763 from Aircoookie/new-KITT
Effect: modified KITT (Scanner)
2024-04-10 19:40:37 +02:00
Andreas Kling
c3787af29d Send ArtnetPollReply for Art-Net proxy universe 2024-04-09 20:00:00 +02:00
Blaz Kristan
38539aac74 Merge branch '0_15' into new-KITT 2024-04-09 16:36:18 +02:00
Blaz Kristan
58e8346209 Fix for #3889 2024-04-09 08:25:07 +02:00
Blaz Kristan
ba9ce4adf2 PIO env. PSRAM fix for S3 & S3 with 4M flash
- audioreactive always included for S3 & S2
2024-04-08 16:32:21 +02:00
Blaž Kristan
bd60fe5a13 Merge pull request #3798 from DedeHai/ESP32_S3_TouchFix
Esp32 s3 touch fix
2024-04-07 22:24:32 +02:00
Blaž Kristan
b72f3baab7 Update set.cpp
Compile fix
2024-04-07 22:21:41 +02:00
Blaž Kristan
d1d54ce9c8 Update cfg.cpp
Indentation fix
2024-04-07 22:15:58 +02:00
Blaž Kristan
954f26308b Update button.cpp
Indentation fix
2024-04-07 22:12:01 +02:00
Blaž Kristan
1cafa0b33f Merge pull request #3880 from DedeHai/harmonic-random-palette-generator
Added fix for #3870
2024-04-07 22:03:59 +02:00
Damian Schneider
18c17168e1 replaced &0xFFFF with explicit casts 2024-04-07 16:07:37 +02:00
Damian Schneider
d3a97f1062 removed detachinterrupt from pin manager, added it to set.cpp instead 2024-04-07 13:49:17 +02:00
Blaž Kristan
d18f078b1e Merge pull request #3887 from gaaat98/0_15
fix for #3884
2024-04-06 16:47:18 +02:00
gaaat98
9ffcde878a fix for #3884 2024-04-06 15:40:32 +02:00
Blaz Kristan
aa970d6ca5 Extend JSON API info object
- add "clock" - CPU clock in MHz
- add "flash" - flash size in MB
Fix for #3879
2024-04-05 19:26:09 +02:00
Damian Schneider
503c68320a Bugfix: millis rollover (fix for #3870)
millis()/1000 rollover after 18h was not handled, truncating to 16bits after division fixes it.
2024-04-05 07:23:28 +02:00
Blaz Kristan
a106342439 PICO & WROVER runtime support
return of GPIO16
2024-04-04 23:09:59 +02:00
Blaz Kristan
00f5471270 Build bump, changelog udate 2024-04-04 21:59:41 +02:00
Blaž Kristan
3b0e6ec65c Merge pull request #3667 from ccruz09/main
usermod support for Adafruit MAX17048 module
2024-04-04 20:25:14 +02:00
Blaž Kristan
8691ddc081 Merge pull request #3875 from w00000dy/cdata
Update cdata.js to rebuild if package.json changes
2024-04-04 20:21:27 +02:00
Blaz Kristan
24c5935661 Fix for missing firmware build
updated changelog (missing credit)
2024-04-03 18:31:17 +02:00
Will Miles
bff6697690 Update to AsyncWebServer v2.2.1 2024-04-03 18:23:50 +02:00
Woody
02405b4856 Create stale.yml 2024-04-03 12:32:18 +02:00
Woody
78b37b592e backup & restore package.json in cdata tests 2024-04-02 20:59:31 +02:00
Woody
4db88cf86b update cdata.js to rebuild if package.json changes 2024-04-02 20:38:56 +02:00
Woody
a7e17eabff add cdata test for package.json & fix a small bug 2024-04-02 20:12:14 +02:00
Blaž Kristan
93d9ce18b2 Merge pull request #3873 from willmmiles/aws-v2.2.1
Update to AsyncWebServer v2.2.1
2024-04-02 07:13:00 +02:00
Will Miles
6f7ac93d84 Update to AsyncWebServer v2.2.1
Fix use-after-free issue and slightly improve code size.  Note that the
version is changed to a hard pin, so future updates can be validated
before getting picked up by new clones, and old version builds
are reproducible.
2024-04-01 11:25:31 -04:00
Carlos Cruz
fa5d60ca26 Merge branch '0_15' into main 2024-04-01 11:02:02 -04:00
Blaz Kristan
20ed81cd86 Prefer I2S1 over RMT on ESP32
- remove Audioreactive limitation
2024-03-30 11:02:28 +01:00
Blaž Kristan
6f38874096 Merge pull request #3862 from willmmiles/fix-esp8266-platform-selection
Fix ESP8266 framework version selection
2024-03-29 21:01:21 +01:00
Blaž Kristan
b7db5be4df Merge pull request #3859 from w00000dy/serg
Only create bin.gz files for esp8266
2024-03-29 21:00:43 +01:00
Blaz Kristan
6d278994ec WLED 0.14.3 release
- Fix for transition 0 (#3854, #3832, #3720)
- copyright year update
- updated AsyncWebServer to v2.2.0
2024-03-29 20:05:56 +01:00
Blaz Kristan
157dbffc59 Changelog update 2024-03-29 18:56:43 +01:00
Blaz Kristan
f21ab3588d Individual color channel control for JSON API
- fixes #3860
- debug verbose
- PSRAM detection
2024-03-29 16:43:37 +01:00
Will Miles
2900bda8f9 Select ESP8266 framework version via platform
By explicitly listing an unversioned framework dependency in
'platform_packages', we were overriding the selection via the 'platform'
specification, allowing PlatformIO to select any random version.
Remove this line to allow 'platform' to add the framework dependency
with the expected version.
2024-03-29 09:33:12 -04:00
Blaz Kristan
5f37c19d42 PSRAM fix & CCT IC
- prevent PSRAM use on ESP32 rev.1 without compile fix
- add runtime selection for CCT IC (Athom 15W bulb)
2024-03-28 16:03:06 +01:00
Woody
6f6356e617 fix print output for bin.gz file 2024-03-27 21:34:51 +01:00
Woody
5d152baac0 Do not create release_gz folder 2024-03-27 21:19:03 +01:00
Woody
d7739f9764 Revert "Change path for ESP02-binary"
This reverts commit e3271b8082.
2024-03-26 17:41:28 +01:00
Woody
d6e73fde50 only create bin.gz files for esp8266 2024-03-26 17:34:01 +01:00
Blaz Kristan
fd149b3f46 fileDoc removal (optimisation) 2024-03-26 17:18:52 +01:00
Blaž Kristan
d1d45e7166 Merge pull request #3850 from w00000dy/GitHub-Actions
Use npm ci instead of npm install & Remove zlib dependency from package.json
2024-03-25 08:46:40 +01:00
Blaz Kristan
4b19759dd6 Rotary encoder palette count bugfix 2024-03-24 20:34:22 +01:00
Blaz Kristan
47f44680a3 Multi-update
- 0.15.0-b2
- WS2805 support (NeoPixelBus 2.7.9)
- generic PSRAM support (ESP32 rev.1 still needs compile fix)
- BREAKING: default LEDPIN 2 (due to PSRAM)
- PinManager optimisations
2024-03-24 17:37:11 +01:00
Woody
0a344ada97 Add bin.gz binaries for 160mhz builds 2024-03-24 15:23:33 +01:00
Woody
3b98d01f71 Merge branch '0_15' into serg 2024-03-24 14:42:06 +01:00
Woody
23d8000239 Remove accidental space in cdata.js 2024-03-24 14:34:17 +01:00
Woody
c32ee40ca0 add node: prefix to Core modules
The node: prefix makes it clear that you’re importing a built-in module, not a user-defined or third-party module. This can help avoid confusion.
2024-03-24 14:19:49 +01:00
Woody
213f45494f Merge branch '0_15' into GitHub-Actions 2024-03-24 13:38:36 +01:00
Frank
85a51e6c42 Update requirements.txt to solve CI build errors
use latest platformIO package, to avoid build errors due to missing 'scons'

> Tool Manager: Installing platformio/tool-scons @ ~4.40400.0 
> Error: Could not find the package with 'platformio/tool-scons @ ~4.40400.0' requirements for your system 'linux_x86_64' 

> Error: Process completed with exit code 1.
2024-03-24 12:27:32 +01:00
Blaz Kristan
ecfdc6f0a8 Bugfixes:
- #3843
- #3844
- network scan on new install
- misc optimization
2024-03-22 20:49:13 +01:00
Woody
1c1c3fd832 Use npm ci instead of npm install 2024-03-21 12:03:35 +01:00
Woody
7bafe995e5 Remove zlib dependency from package.json 2024-03-21 12:00:18 +01:00
Blaž Kristan
3c23672347 Merge pull request #3836 from THATDONFC/0_15
Add SSD1309_64 I2C Support for FLD Usermod
2024-03-21 05:48:42 +01:00
thatdonfc
33fe68d7eb Revert breaking change 2024-03-20 13:48:15 -07:00
Blaz Kristan
b031fa1531 Palette cycling fix.
Updated getPaletteCount() to return count of all available palettes, including custom ones.
2024-03-20 20:12:21 +01:00
Blaž Kristan
dab4dc3f41 Merge pull request #3810 from deece/fw1906_0_15
Fw1906 Support (based on 0-15)
2024-03-20 19:57:10 +01:00
Blaž Kristan
78096803ea Merge branch '0_15' into fw1906_0_15 2024-03-20 19:51:32 +01:00
Blaž Kristan
f1987b9544 Merge pull request #3828 from willmmiles/0_15-asyncwebserver-2.2.0-features
ESPAsyncWebServer 2.2.0 + features
2024-03-20 19:50:06 +01:00
Will Miles
8b6bf08a23 serveLiveLeds: Use variable buffer size
Allocate the serialization buffer size at the required length, rather
than always allocating the maximum size.
2024-03-19 23:50:32 -04:00
Will Miles
2640203c88 wled_server: Remove local content type variables
Use the CONTENT_TYPEs exported by AsyncWebServer directly.
2024-03-19 23:46:55 -04:00
thatdonfc
2dafa9644f Update Readme for Rotary Encoder Usermod
Add example platformio_override.sample.ini
2024-03-19 14:48:51 -07:00
thatdonfc
92ebeddcb0 Update Readme for Four Line Display Usermod 2024-03-19 14:48:04 -07:00
thatdonfc
ecee073e08 Fix palette names when palette ID > 58 and not custom 2024-03-19 14:04:24 -07:00
thatdonfc
6d1b9ffad2 Add SSD1309_64 I2C Support to FDL Usermod 2024-03-19 14:04:09 -07:00
Woody
7ee4b54154 optimize output_bins.py 2024-03-19 20:06:09 +01:00
Woody
e3271b8082 Change path for ESP02-binary 2024-03-19 18:15:18 +01:00
Woody
c6ff45f959 Merge branch '0_15' into serg 2024-03-19 17:49:56 +01:00
Blaz Kristan
5d3f22e06a Changelog update and build bump. 2024-03-19 15:18:17 +01:00
Blaž Kristan
c77f6c5f7b Merge pull request #3711 from muebau/tetris-ai
Tetris AI usermod
2024-03-19 14:44:51 +01:00
Blaž Kristan
6d03c3a54c Merge pull request #3834 from willmmiles/ddp-no-push
Support DDP sources that don't PUSH
2024-03-19 07:30:58 +01:00
Blaž Kristan
92dc63e5c9 Merge pull request #3833 from willmmiles/fix-avgloopmillis
Fix avgLoopMillis
2024-03-19 06:20:29 +01:00
Will Miles
505d319e01 Fix avgLoopMillis 2024-03-18 19:50:54 -04:00
Will Miles
62f845a94e DDP: Support sources that don't push
If the source never sends the push flag, WLED buffers the update but
never publishes it to the LEDs.  This causes the confusing case where
the peek display shows one thing but the LEDs themselves something else.

Add a static flag that tracks if we've seen a push from the source;
until we do, apply every update as soon as it's received, per the DDP
specification.
2024-03-18 19:49:26 -04:00
Blaz Kristan
7a9eff7f35 Fix. 2024-03-18 20:23:30 +01:00
Blaz Kristan
b849ea8eaa Fix for #3827 2024-03-18 20:01:32 +01:00
muebau
f1635fa302 Merge branch '0_15' into tetris-ai 2024-03-18 13:21:35 +01:00
Blaž Kristan
6110b72b87 Merge pull request #3831 from willmmiles/missing-ir-disable
getSettingsJS: Fix missing DISABLE_INFRARED guard
2024-03-18 08:00:44 +01:00
Will Miles
6de617ecd5 getSettingsJS: Fix missing DISABLE_INFRARED guard 2024-03-17 16:28:09 -04:00
Blaz Kristan
7c8df97968 Merge branch 'main' into 0_15 2024-03-17 12:21:35 +01:00
Blaz Kristan
acf6736afd WLED 0.14.2 release 2024-03-17 11:52:09 +01:00
Will Miles
5f2480c3d9 serveLiveLeds: Use dynamic buffer
There were three problems here:
- AsyncWebServer is going to copy to a heap buffer anyways, so we might
   as well just pass it one it can use
- The buffer size estimate was wrong -- we need 9 bytes per pixel
   ("RRGGBB",), so the buffer could overflow, and it was not
   considering the extra 2D requirements
- On ESP8266, the stack allocation was overflowing the stack, causing
  corruption and crashes.
2024-03-16 12:16:36 -04:00
Will Miles
0593a078c6 handleFileRead: Leverage AWS code
No need to filter or look up content type, just pitch it over the wall.
Also fixes .gz'd content processing.
2024-03-16 12:12:48 -04:00
Will Miles
323c70dcdf Update for new AsyncWebSocketBuffer
Eliminate the extra indirection and allocate shared buffers directly.
2024-03-16 12:12:48 -04:00
Will Miles
a1b0f84444 Pass PROGMEM type to server.on()
Rather than relying on the exception handler, indicate the
__FlashStringHelper type so the correct String constructor is
used.
2024-03-16 12:12:48 -04:00
Will Miles
df6c271830 Use web server ContentType symbols
These were mostly PROGMEM already, but every little bit helps.
2024-03-16 12:12:48 -04:00
Will Miles
12bf04826a Update ESPAsyncWebServer to v2.2.0 2024-03-16 12:12:48 -04:00
Blaz Kristan
52a1b0453c MQTT cleanup & reduction 2024-03-16 15:26:52 +01:00
Blaz Kristan
0dcb56eab5 Modify Bus & BusManager to accommodate digital CCT
- additional fix in hasWhite() & setCCT() & hasCCT()
2024-03-16 12:36:05 +01:00
Frank
a42f78b08b Update CONTRIBUTING.md
Trying to explain why any PR should have a`description`
2024-03-14 20:27:03 +01:00
Blaž Kristan
505768db04 Some fixes & implement recommendation from @Aircoookie
https://github.com/Aircoookie/WLED/pull/3298#issuecomment-1651910418
2024-03-13 20:44:34 +11:00
Robert
c74db95c14 Add FW1906 support 2024-03-13 20:44:33 +11:00
Robert
af3f27feae Move CTT calculation from BusPwm to Bus class.
This enable it to other bus types.
2024-03-13 20:26:58 +11:00
Blaz Kristan
7b366d49d2 Effect: 2D Drift gets original twin option 2024-03-12 21:23:09 +01:00
Blaž Kristan
88b30e7e28 Merge pull request #3816 from BaptisteHudyma/3813-fix-the-drift-animation-0_15
fix the 2d drift animation
2024-03-12 20:59:19 +01:00
BaptisteHudyma
05c0febd04 fix the 2d drift animation 2024-03-12 12:01:25 +01:00
Blaz Kristan
9d70ec56f2 Distinguish 160MHz binaries 2024-03-11 23:22:14 +01:00
Blaz Kristan
7f8ec59939 Changelog update 2024-03-11 23:08:50 +01:00
Blaz Kristan
0398ec40b7 Merge branch 'main' into v0142-beta2 2024-03-11 23:00:17 +01:00
Blaz Kristan
f55465f8b8 Fix AsyncWebServer library 2024-03-11 18:02:03 +01:00
Blaz Kristan
a4384bd340 Simpler boot preset save
- fixes #3806
2024-03-11 17:59:13 +01:00
Blaz Kristan
a2368a75f7 Fix AsynWebServer lib
Add 160MHz builds for ESP8266
2024-03-11 17:41:17 +01:00
Christian Schwinne
68e5e74882 Fix expanded preset low width
Fix spaces missing in HTML somehow
Update copyright year
2024-03-10 21:52:54 +01:00
Damian Schneider
0637c1c9d4 bugfixes
-added minimum threshold, had some crashes when setting threshold to zero before
-moved interrupt detach to GPIO deallocation where it belongs
-added check for touchbutton before detaching interrupt
-moved thochThreshold readout up so it gets updated before passing it to the system call
2024-03-10 19:44:27 +01:00
Damian Schneider
0453a5fb3d added interrupt detach to cfg.cpp 2024-03-10 16:54:25 +01:00
Christian Schwinne
6322ab9f07 . 2024-03-09 22:00:18 +01:00
Christian Schwinne
21d0f10dd7 Fix AR compilation 2024-03-09 21:59:45 +01:00
Christian Schwinne
51b9e81c3d Fix missing spaces in info page 2024-03-09 21:48:48 +01:00
Christian Schwinne
7723011594 Update CONTRIBUTING.md 2024-03-09 21:32:10 +01:00
Christian Schwinne
91c11a18e0 Update CONTRIBUTING.md 2024-03-09 21:31:53 +01:00
Christian Schwinne
215ba35fe1 Make ASCII art in build script more like WLED logo 2024-03-09 20:56:14 +01:00
Christian Schwinne
7e17011ebc Revert "Merge branch 'gif' into 0_15"
This reverts commit cb5eb9edc7, reversing
changes made to da5c12f466.
2024-03-09 20:00:41 +01:00
Carlos Cruz
ab13db73e7 Added files to usermod directory and changes to platform.ini to support Adafruit MAX17048 module. (#2)
Co-authored-by: Azots <78281612+Azots@users.noreply.github.com>
2024-03-09 13:06:30 -05:00
Christian Schwinne
cb5eb9edc7 Merge branch 'gif' into 0_15 2024-03-09 18:23:59 +01:00
Damian Schneider
509675fe66 added touch interrupt activation to set.cpp for S2/S3 2024-03-09 16:03:01 +01:00
Blaz Kristan
da5c12f466 Segment UI bugfix. 2024-03-09 12:37:35 +01:00
Blaz Kristan
f2ad10bbce Limit max frequency to 64k 2024-03-08 18:11:40 +01:00
Blaz Kristan
99a7bece2e Build bump & changlog update 2024-03-07 21:43:41 +01:00
Blaz Kristan
b305fd8865 Fix for ArduinoFFT 2024-03-07 20:52:18 +01:00
Blaz Kristan
c0beb621e2 Better low brightness level PWM handling
Additional string optimisation
2024-03-07 20:21:56 +01:00
Blaz Kristan
da6d64e581 Multiple fixes
- compile time button configuration #3792
- remove IR config if not compiled
- additional string optimisations
2024-03-05 16:27:28 +01:00
Blaž Kristan
a6d58ee360 Merge pull request #3790 from WoodyLetsCode/fix-preset-sorting
Fix preset sorting
2024-03-05 11:38:26 +01:00
Woody
2a480ab7db Revert "fix preset sorting reordering bug"
This reverts commit f25fadafd8.
2024-03-05 11:30:11 +01:00
Damian Schneider
5c09ee29db removed notes 2024-03-04 14:42:50 +01:00
Damian Schneider
15526bd6e8 some tuning for touch buttons on S2/S3
now better fits the default threshold value of 32
2024-03-04 14:38:51 +01:00
Damian Schneider
c8f48168b4 fixed touch buttons for ESP32 S2 and S3
touch is implemented differently on S2 and S3, these changes make touch buttons work on S2 and S3
2024-03-04 14:38:37 +01:00
Blaž Kristan
d937d473f9 Merge pull request #3737 from WoodyLetsCode/GitHub-Actions
Update setup-node and cache usermods in wled-ci.yml
2024-03-04 07:00:49 +01:00
Woody
66f14c6343 restore default preset sorting if no search term is entered 2024-03-03 15:58:30 +01:00
Woody
f25fadafd8 fix preset sorting reordering bug 2024-03-03 15:16:10 +01:00
Will Miles
d9b0df94e2 LockedJsonResponse: Release early if possible
Release the json buffer lock as soon as we've finished serializing.
This should slightly reduce the number of lock collisions as the
response class isn't destructed until after the last packet is ack'd.
2024-03-03 10:58:40 +01:00
Woody
200d11ca99 Revert "Fix preset sorting"
This reverts commit 00038453e1.
2024-03-02 21:56:25 +01:00
Blaž Kristan
f8c48ef60a Merge pull request #3760 from willmmiles/json-response-early-unlock
LockedJsonResponse: Release early if possible
2024-03-02 14:29:34 +01:00
Blaz Kristan
1fc0680c71 160MHz clock & alternate AWS 2024-03-02 14:12:57 +01:00
Blaž Kristan
ec4afb2cbc Merge pull request #3616 from demophoon/dmx-segment-options-expanded
Add additional segment options when controlling over e1.31
2024-03-01 16:28:19 +01:00
Blaz Kristan
a2a632c415 Variable PWM duty cycle resolution 2024-03-01 14:36:17 +01:00
Blaz Kristan
962e64106c A few more PROGMEM optimisations 2024-03-01 14:36:07 +01:00
Blaž Kristan
c40b6088ee Merge pull request #3783 from shammy642/virtual-artnet-rgbw
Add virtual Art-Net RGBW option
2024-02-29 14:57:42 +01:00
shammy642
0d1a254ca8 Changed values to 89 2024-02-29 12:47:45 +00:00
shammy642
fdbcb61a12 Rebased to 0.15 2024-02-29 08:27:11 +00:00
Blaz Kristan
6435cb1466 Fix for missing string in OTA 2024-02-28 20:25:59 +01:00
Blaz Kristan
4739cfab9a JS ABL optimisation 2024-02-28 18:14:42 +01:00
Blaz Kristan
00a73e9cc8 ABL display bugfix 2024-02-27 21:21:53 +01:00
Blaz Kristan
0ff5dec004 Reposition upload warning message.
Fixes #3778
2024-02-27 15:59:41 +01:00
Blaz Kristan
41129cf379 Sqeeze every byte 2024-02-25 17:08:01 +01:00
Will Miles
c8c394b4e9 TZ_TABLE: Add missing const 2024-02-20 18:33:18 +01:00
Will Miles
59886a1528 Move timezone table to PROGMEM 2024-02-20 18:33:09 +01:00
Frank
a28d2c869f Merge pull request #3766 from willmmiles/tztable-progmem
Move timezone table to PROGMEM, saving ~200 bytes of RAM on 8266.
2024-02-20 17:09:47 +01:00
Will Miles
6f1fff44fa TZ_TABLE: Add missing const 2024-02-19 09:48:34 -05:00
Will Miles
108978d1a5 Move timezone table to PROGMEM 2024-02-18 21:23:53 -05:00
Blaz Kristan
a4733b4d91 Move strings into flash 2024-02-18 14:25:07 +01:00
Blaz Kristan
66f4671ec0 Move strings into flash 2024-02-18 14:09:38 +01:00
Blaz Kristan
c932621b5d string fix 2024-02-17 15:00:47 +01:00
Frank
21173dc907 Fixing a potential array bounds violation in ESPDMX
DMXESPSerial::write and DMXESPSerial::read could access DMXDataStore[512] -   one more than the allocated number of elements (i.e. 0...511].
2024-02-17 13:05:04 +01:00
Blaz Kristan
f2c30ba3f7 Effect: modified KITT (Scanner)
- add delay
- add dual checkmark
- rename Fade rate to Trail (inverse)
- makes Scanner Dual obsolete
2024-02-17 12:58:04 +01:00
Blaz Kristan
989bdfb0d5 Reduce string RAM usage for ESP8266 debug builds 2024-02-17 11:33:42 +01:00
Blaz Kristan
5761dce957 JSON buffer lock error messages
Reduce wait time for lock to 100ms
2024-02-17 11:30:29 +01:00
Blaz Kristan
95e2e574b8 ESP-NOW packet modification
- include up to 5 segments in 1st packet
- header contains total number of packets (instead of segments)

web server code reorganise
2024-02-15 20:40:55 +01:00
Will Miles
c789d80ce5 LockedJsonResponse: Release early if possible
Release the json buffer lock as soon as we've finished serializing.
This should slightly reduce the number of lock collisions as the
response class isn't destructed until after the last packet is ack'd.
2024-02-14 19:37:34 -05:00
Frank
8422ffcd19 Fixing a potential array bounds violation in ESPDMX
DMXESPSerial::write and DMXESPSerial::read could access DMXDataStore[512] -   one more than the allocated number of elements (i.e. 0...511].
2024-02-15 00:53:00 +01:00
lost-hope
2d30535b69 Fixing stairway usermod and adding buildflags 2024-02-14 09:56:57 +01:00
Blaž Kristan
0a815179a2 Merge pull request #3758 from lost-hope/main
Fixing stairway usermod and adding buildflags
2024-02-14 09:45:52 +01:00
Blaz Kristan
aa24e5d284 Preset caching on chips with PSRAM
- credit @akaricchi
2024-02-13 11:12:04 +01:00
lost-hope
23aad24027 Fixing stairway usermod and adding buildflags
Fixing Stairway:
missing setup function

Adding builflags:
USERMOD_STAIRCASE_WIPE to install the usermod
2024-02-12 22:41:13 +01:00
Blaz Kristan
7ae5459fe7 0.14.2-b1 2024-02-12 13:29:08 +01:00
Blaz Kristan
0a8a88421e Possible fix for #3589 & partial fix for #3605 2024-02-12 13:20:47 +01:00
Blaz Kristan
4f42a176ef Prevent JSON buffer clear after failed lock attempt
(alternative to #3743)
2024-02-11 20:12:54 +01:00
Blaz Kristan
4457067045 Multiple analog button fix for #3549 2024-02-10 11:47:40 +01:00
Blaz Kristan
e7dc2048ad Multiple analog button fix for #3549 2024-02-10 11:45:33 +01:00
Blaz Kristan
af6094bb06 Bump 2024-02-09 22:58:11 +01:00
Blaž Kristan
0ab139cb24 Merge pull request #3560 from roelbroersma/usermod_v2_HttpPullLightControl_0.0.5
Usermod:  httpPullLightControl v0.0.5 (supersede v0.0.4)
2024-02-09 22:42:40 +01:00
Blaz Kristan
500a7301f2 Fix merge error 2024-02-09 22:37:52 +01:00
Blaz Kristan
c92cef1780 Merge branch '0_15' into usermod_v2_HttpPullLightControl_0.0.5 2024-02-09 22:34:38 +01:00
Blaz Kristan
49ceac1ac7 Add "RGB2Go Tetra" Ethernet 2024-02-09 22:21:14 +01:00
Blaz Kristan
276a93605d Multiupdate
- allow DMX for S2 & C3 (ESPDMX, needs testing)
- (debug) string cleanup & optimisation
- WLED_BRAND for AP SSID
2024-02-09 22:15:29 +01:00
Blaz Kristan
0150c3fe23 Undo flash string in DMX 2024-02-08 23:35:00 +01:00
Blaz Kristan
34674501c3 Remove throttling from UI 2024-02-08 19:33:08 +01:00
Blaz Kristan
f6206d4c30 Web server string optimisation
(saves 140B of RAM on ESP8266)
ETag bugfix
2024-02-08 19:32:23 +01:00
Blaz Kristan
6dcd9596a2 Prevent JSON buffer clear after failed lock attempt
(alternative to #3743)
2024-02-07 18:58:56 +01:00
Blaz Kristan
e165838e54 PIR readme update. 2024-02-07 18:03:58 +01:00
Blaž Kristan
eae1707e97 Merge pull request #3750 from Moustachauve/product-data-0_15
Allow product information to be specified at build time
2024-02-07 13:20:35 +01:00
Christophe Gagnier
ed2950f73b Allow product information to be specified at build time 2024-02-07 02:09:03 -05:00
Blaz Kristan
7eae8f68d8 Merge branch 'main' into 0_15 2024-02-06 14:47:20 +01:00
Blaž Kristan
0ab2d18b52 Merge pull request #3729 from DedeHai/harmonic-random-palette-generator
added function to generate random palette based on harmonic color theory
2024-02-06 13:16:05 +01:00
Blaz Kristan
8ab621bc91 Another unsigned 2024-02-06 11:43:57 +01:00
Blaz Kristan
41e51bbeb5 Configuration item for harmonic palettes
Comment cleanup
2024-02-06 11:06:23 +01:00
Blaz Kristan
66d9e8c038 Merge branch '0_15' into harmonic-random-palette-generator 2024-02-06 10:53:44 +01:00
Blaz Kristan
f5e47b2b74 Fix compiler warning 2024-02-06 10:17:53 +01:00
Blaz Kristan
678a823e8b PULLDOWN fix 2024-02-05 22:21:12 +01:00
Blaz Kristan
246746a82e Multi PIR usermod 2024-02-05 22:13:32 +01:00
Blaz Kristan
00038453e1 Fix preset sorting 2024-02-03 19:24:08 +01:00
Blaz Kristan
9ce485eade Ignore missing remote.json 2024-02-03 14:40:45 +01:00
Blaz Kristan
8a6ff5a42b UI fixes and refinements 2024-02-03 14:40:28 +01:00
Woody
1eaac0072d Add a separate folder for .gz release files 2024-02-03 00:44:38 +01:00
Woody
35716a7e4c Cache usermods in wled-ci.yml 2024-02-01 20:44:46 +01:00
Damian Schneider
e0f89beebb slight change to color parameters
added more white, changed function return value of fully random palette function
2024-02-01 20:06:48 +01:00
Blaz Kristan
b8bf2a707c Remove obsolete usermods
- mode sort
- 4LD (non ALT)
- Rotary encoder (non ALT)
2024-02-01 18:53:55 +01:00
Woody
7d616be8f4 Update setup-node in wled-ci.yml 2024-02-01 18:41:21 +01:00
Blaz Kristan
0a7e9f9f8f Build bump and ghanglog update 2024-02-01 18:36:10 +01:00
Blaz Kristan
226e188903 Merge branch '0_15' of https://github.com/aircoookie/WLED into 0_15 2024-02-01 18:33:23 +01:00
Blaž Kristan
590d454119 Merge pull request #3718 from WoodyLetsCode/GitHub-Actions
Update GitHub Actions workflow
2024-02-01 18:26:13 +01:00
Blaž Kristan
06d5bd799f Merge pull request #3732 from wled-install/patch-1
UM Audioreactive: add two compiler options
2024-02-01 18:24:39 +01:00
Woody
7fe6541b7c Merge branch '0_15' into GitHub-Actions 2024-02-01 18:05:39 +01:00
Blaž Kristan
0f30fa5fb9 Merge pull request #3702 from Aircoookie/trim-platformio_ini
Trim platformio.ini & add info to sample
2024-02-01 17:17:46 +01:00
Blaz Kristan
2c362315ad Rename sample 2024-02-01 17:09:55 +01:00
Blaž Kristan
7dd79edc52 Merge pull request #3734 from WoodyLetsCode/tooltip
Improvements for tooltips
2024-02-01 17:07:52 +01:00
Blaž Kristan
3d6f25a9d3 Merge pull request #3732 from wled-install/patch-1
UM Audioreactive: add two compiler options
2024-02-01 17:07:00 +01:00
Blaž Kristan
b3c21feba3 Merge pull request #3699 from WoodyLetsCode/cdata
Update dependencies for cdata.js and make some improvements
2024-02-01 17:05:19 +01:00
Blaž Kristan
fe54fadbf8 Merge pull request #3709 from Aircoookie/multiwifi
Implement multiple WiFi
2024-02-01 17:04:18 +01:00
Blaž Kristan
caa0722d49 Merge pull request #3715 from WoodyLetsCode/nodelist
Allow nodes buttons to be opened in new target or copy ip address
2024-02-01 17:00:21 +01:00
Blaž Kristan
fee32622f1 Merge pull request #3489 from WoodyLetsCode/clock-overlay
Show clock overlay only if all LEDs are solid black
2024-02-01 16:54:26 +01:00
Blaz Kristan
d1910e4274 Merge branch '0_15' into multiwifi 2024-02-01 16:49:55 +01:00
Blaž Kristan
45eb11d7f4 Merge pull request #3721 from Aircoookie/temporary-AP
Temporary AP
2024-02-01 16:44:41 +01:00
Blaž Kristan
874179fa75 Merge pull request #3625 from m-wachter/ESP32-POE-WROVER
Add support for Olimex ESP32-POE-WROVER.
2024-02-01 16:41:40 +01:00
Blaž Kristan
8b16cb4bae Merge pull request #3580 from itstefanjanos/feature/add-APA106-led
Add APA106 support
2024-02-01 16:41:02 +01:00
Woody
777ed55c21 Add tooltip for toggle freeze & label 2024-01-31 22:36:09 +01:00
Woody
fcafd8b05e Improved tooltips 2024-01-31 22:35:10 +01:00
Blaz Kristan
5f1cadfea4 Merge branch '0_15' into feature/add-APA106-led 2024-01-31 17:21:55 +01:00
wled-install
917a981096 Update audio_reactive.h 2024-01-31 06:34:15 +01:00
wled-install
89f8b6060f Update readme.md 2024-01-31 06:33:48 +01:00
wled-install
345346315a Update readme.md 2024-01-30 22:59:29 +01:00
wled-install
f1c27e1798 Update readme.md 2024-01-30 22:56:09 +01:00
wled-install
4316024dc7 Update audio_reactive.h 2024-01-30 22:51:18 +01:00
Damian Schneider
ca05aa84ff changed randomness and added optimizations
-added fully random palette function ('the old way', currently just used for initialization)
-changed randomness values to make it a little less random
-added 10% chance for pastel color palette
-now using swap() from std library for shuffeling
-changed function name
-moved update check from loadPalette() to handleRandomPalette() saving CPU cycles
2024-01-30 22:28:40 +01:00
Blaz Kristan
d10d7dc298 upload speed and clarifications 2024-01-30 19:44:10 +01:00
Blaz Kristan
063af1dbc7 core description fix 2024-01-30 19:26:37 +01:00
Damian Schneider
ef6fe43251 random palette transitions with set transition time 2024-01-29 22:14:26 +01:00
Damian Schneider
2659055c31 fixed typos 2024-01-29 20:47:09 +01:00
Damian Schneider
f5ed757780 added some minor fixes
-fastled flags
-gamma correction
-pass by reference instead of pointer
2024-01-29 20:47:09 +01:00
Damian Schneider
e114b842ba fixed initialisation or random palette 2024-01-29 20:47:08 +01:00
Damian Schneider
12e2116acb bugfix, need to initialize the random palette to something useful 2024-01-29 20:47:08 +01:00
Damian Schneider
bccc97d25f fixed include, bugfix in random palette handling 2024-01-29 20:47:08 +01:00
Damian Schneider
a9bcc75733 added function to generate random palette based on harmonic color theory 2024-01-29 20:47:08 +01:00
Blaz Kristan
7b87475af8 Fix random palette transitions. 2024-01-29 19:06:41 +01:00
Michael Wachter
2ac218886a Add support for Olimex ESP32-POE-WROVER.
There is a version of the Olimex ESP32-POE board with an ESP32-WROVER
module which has a the ethernet clock connected to a different IO than
the version with an ESP32-WROOM module.

This commit adds a new runtime selectable variant for the WROVER version.
2024-01-28 17:54:19 +01:00
Blaz Kristan
97503897f0 New effect: 2D Rotozoomer 2024-01-28 15:09:40 +01:00
lost-hope
7e06e32cb6 Usermod Klipper Percentage: fix error with slashes on non windows devices 2024-01-27 23:26:30 +01:00
Blaz Kristan
15b813c6af Build bump & changelog update 2024-01-27 21:22:25 +01:00
Blaž Kristan
a71c9107bd Merge pull request #3683 from TripleWhy/rotatingPalletteEffect
Rotating 2D Palette effect
2024-01-27 20:04:36 +01:00
Blaž Kristan
4c2110189b Merge pull request #3682 from Aircoookie/supersync
Use strip.now instead of millis() in effects
2024-01-27 14:06:26 +01:00
Blaz Kristan
df750c2a71 Fix for single wifi 2024-01-27 08:39:54 +01:00
Blaz Kristan
3eb412b750 Add rescan & selection on disconnect 2024-01-26 18:38:56 +01:00
Blaz Kristan
5c7b7e4182 Constant & override 2024-01-26 15:31:09 +01:00
Frank
2b0fad87d2 Merge pull request #3722 from lost-hope/main
Usermod Klipper Percentage: Fix for include paths (windows backslash vs. linux slash)
2024-01-26 11:41:02 +01:00
Blaz Kristan
8817d41275 Wrong return value 2024-01-25 19:57:04 +01:00
Blaž Kristan
04ef3f9496 Merge pull request #3723 from Derek4aty1/dnaSpiralFix
DNA Spiral Effect Speed Fix
2024-01-25 19:52:14 +01:00
Blaz Kristan
fbe26e13ae Remove erroneous wifi selection 2024-01-25 19:46:47 +01:00
Blaz Kristan
4408dffa87 Better invalid password handling
Changed function return value
2024-01-25 19:42:23 +01:00
Derek4aty1
546192865c DNA Spiral Effect Speed Fix 2024-01-25 11:21:16 -06:00
lost-hope
7afa550ba4 Usermod Klipper Percentage: fix error with slashes on non windows devices 2024-01-25 17:55:41 +01:00
Woody
21a9372320 fix clock overlay display 2024-01-25 12:14:44 +01:00
Woody
f4a2eec984 Use a reference instead of segment object copy 2024-01-25 11:33:40 +01:00
Woody
94b9455c9c closes Aircoookie/WLED#984
Implements option to show clock overlay only if all LEDs are solid black
2024-01-25 11:33:36 +01:00
Woody
c41c71c8c1 add bin.gz firmware for ESP02 to artifacs (#4) 2024-01-24 21:22:54 +01:00
Blaz Kristan
dde647c570 Required fix 2024-01-24 20:53:17 +01:00
Blaz Kristan
445a89ba6e Try hard to release memory 2024-01-24 20:49:22 +01:00
Blaz Kristan
07495f6621 Merge branch '0_15' into temporary-AP 2024-01-24 20:22:50 +01:00
Blaz Kristan
5952edc550 Some fixes 2024-01-24 19:52:41 +01:00
Woody
b66a038a2f Change path separator 2024-01-24 17:15:06 +01:00
Woody
df1c8a64e5 Update GitHub Actions workflow
This also adds a WLED_RELEASE_NAME for esp32s3dev_8MB_PSRAM_opi
2024-01-24 16:11:51 +01:00
Blaz Kristan
3e2aebcd10 Remove regression
Init wifi for scan
Always save WiFi name
2024-01-24 15:43:59 +01:00
TripleWhy
0d279cb4dd Add some comments 2024-01-24 15:38:50 +01:00
Woody
3942a76d15 Fix #3708 2024-01-23 21:00:44 +01:00
Blaz Kristan
1bebf3d3d6 Optimise wifi scan
- prioritize strongest signal
- prune removed networks
- fill present networks
2024-01-23 20:44:43 +01:00
Blaz Kristan
d5f54c240a Debug pin fix 2024-01-22 21:01:57 +01:00
Blaz Kristan
8868ecd11a Cleanup 2 2024-01-22 20:48:03 +01:00
Blaz Kristan
8a31c57bfa Fix getActiveSegmentsNum
Limit rotation to +-90 deg (swapping sin/cos & limit angle)
Shift palette shift
2024-01-22 19:38:13 +01:00
muebau
7e2cce4a8d Tetris AI usermod 2024-01-21 17:28:10 +01:00
Blaz Kristan
bfb217c203 Implement multiple WiFi
- similar to #3705
- solves #2845, #2974, #852, #1228
2024-01-21 00:30:15 +01:00
Blaz Kristan
593e55af95 Cleanup. 2024-01-20 23:29:45 +01:00
Blaz Kristan
29af62f956 Fix for 1D & remove segment ID 2024-01-20 14:55:22 +01:00
Blaž Kristan
2b022e1871 Update platformio.ini
Added WROVER model and removed flash options for ESP32-S2
2024-01-19 14:18:54 +01:00
Woody
783a4d3996 old line break style 2024-01-18 21:23:29 +01:00
Woody
ddfe925f8c rename test 2024-01-18 21:23:29 +01:00
Woody
1735bcab21 fix wled banner color in cdata.js 2024-01-18 21:23:29 +01:00
Woody
ff6cacf766 npm update 2024-01-18 21:23:28 +01:00
Woody
2a72eae77f cdata.js: Better console print messages 2024-01-18 21:23:28 +01:00
Woody
39fb7fdfe3 Add test for -f and --force argument 2024-01-18 21:23:28 +01:00
Woody
e0facf35c8 refactored tests 2024-01-18 21:23:28 +01:00
Woody
73d48c8ac4 remove html-minify-ui option 2024-01-18 21:23:28 +01:00
Woody
5080059143 Rebuild if a cdata.js has been modified 2024-01-18 21:23:28 +01:00
Woody
90d5b77d74 more minifying 2024-01-18 21:23:28 +01:00
Woody
e0f987328b add new test 2024-01-18 21:23:28 +01:00
Woody
04c3a925cc Fix test on Github Actions
This needed more time on Github
2024-01-18 21:23:27 +01:00
Woody
219b29991b Update wled-ci.yml 2024-01-18 21:23:27 +01:00
Woody
5120045459 refactor cdata.js 2024-01-18 21:23:27 +01:00
Woody
3bca4a73f4 More tests for cdata 2024-01-18 21:23:27 +01:00
Woody
b4857ab036 Automatically test cdata.js 2024-01-18 21:23:27 +01:00
Woody
f3ae041691 Add first unit tests for cdata.js 2024-01-18 21:23:27 +01:00
Woody
a84627a465 Update dependencies for cdata.js 2024-01-18 21:23:27 +01:00
Blaz Kristan
78aeca6399 Trim platformio.ini & add info to sample 2024-01-18 18:28:01 +01:00
Blaz Kristan
5dd8f0a0b7 typo 2024-01-17 23:39:33 +01:00
Christian Schwinne
9378fc7276 Merge remote-tracking branch 'origin/0_15' into gif 2024-01-16 21:53:08 +01:00
Blaz Kristan
3a0d8069b6 Bus type clarifications
- expansion of digital types
- updated macros
- mem calc function
2024-01-16 21:02:08 +01:00
Blaz Kristan
bab42014a4 Fix for #3693 2024-01-16 19:35:18 +01:00
Blaz Kristan
74fed5695f Fix for #3693 2024-01-16 19:34:23 +01:00
Blaz Kristan
3be368c333 A few more overrides 2024-01-14 21:04:18 +01:00
Blaz Kristan
a4a8e2614e Release WLED 0.14.1 2024-01-14 18:33:27 +01:00
Blaz Kristan
58eb151ba1 Use strip.now instead of millis() in effects
AKA "supersync" from WLED MM fork
2024-01-14 17:51:48 +01:00
Blaz Kristan
21d21ea7f0 Orange flash fix (#3196) for transitions 2024-01-14 17:40:04 +01:00
Blaz Kristan
45dc5e236d Override identifier 2024-01-14 17:38:29 +01:00
dependabot[bot]
0597eeed6b Bump urllib3 from 1.26.15 to 1.26.18 (#3455)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.15 to 1.26.18.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.15...1.26.18)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-14 15:58:51 +01:00
Christian Schwinne
0a66fe196a Merge remote-tracking branch 'origin/0_15' into pr/3580 2024-01-14 15:08:13 +01:00
Woody
3f21b4aa7d Add own background image upload (#3596)
* Add own bg image upload

* Fix undefined issue in settings UI
2024-01-14 14:16:32 +01:00
TripleWhy
b97186c5bf Rotating palette effect 2024-01-13 18:49:17 +01:00
Blaz Kristan
874b24fb32 WLED time overrides 2024-01-13 13:06:00 +01:00
Blaz Kristan
97889b5e55 Fix for audio palettes 2024-01-12 20:45:04 +01:00
Woody
4b134194cf Better sorting and naming of static palettes 2024-01-12 19:44:25 +01:00
Blaž Kristan
24b60a25d5 Merge pull request #3674 from WoodyLetsCode/cpal
Better sorting and naming of static palettes in the Custom Palette Editor
2024-01-12 18:57:01 +01:00
Blaž Kristan
3e069376a7 Merge pull request #3666 from WoodyLetsCode/pio
Ignore autogenerated files with binary array for the Web UI and fix caching bug
2024-01-12 16:52:33 +01:00
Woody
5bdb2c9e86 Fix bug where some changes were not recognized 2024-01-12 00:02:53 +01:00
Woody
71b0c5f805 Update wled-ci.yml 2024-01-12 00:02:53 +01:00
Woody
a1f62e7a1f Add result file check to isCached function 2024-01-12 00:02:53 +01:00
Woody
186c40801a Delete html_*.h files 2024-01-12 00:02:52 +01:00
Woody
bf867e84d6 Update .gitignore 2024-01-12 00:02:44 +01:00
Woody
27035a8e1d Better sorting and naming of static palettes 2024-01-11 23:13:26 +01:00
Blaž Kristan
db3770c3e5 Merge pull request #3673 from netmindz/animartrix
Add ANIMartRIX usermod
2024-01-11 22:06:31 +01:00
Will Tatam
46337ca554 Add ANIMartRIX usermod 2024-01-11 20:20:53 +00:00
Blaž Kristan
4f0f288000 Merge pull request #3621 from zanhecht/patch-2
Use canvas instead of CSS gradient for liveview
2024-01-11 20:41:35 +01:00
Blaz Kristan
8060bae1b8 Width fix 2024-01-11 20:37:51 +01:00
Blaz Kristan
ea32c97b82 Fix for #3672 2024-01-11 20:24:59 +01:00
Blaz Kristan
99efbd30f1 ColoOrderMap W channel swap
& cleanup
2024-01-11 20:22:42 +01:00
Frank
a9eb7cb4fd udp realtime - improve robustness against short packets (fix for #3672)
when only two bytes were received in a packet, the "for" condition `packetsize -3` would underflow, leading to an infinite loop.
2024-01-11 18:07:23 +01:00
Blaz Kristan
a11cab0f88 Fix for #3665 2024-01-10 19:41:51 +01:00
Blaz Kristan
447324b59f Fix for #3665 2024-01-10 19:40:59 +01:00
Blaz Kristan
e580e815f0 Fix .gitignore 2024-01-10 18:52:46 +01:00
Blaž Kristan
5fc00840f2 Merge pull request #3554 from ezcGman/ledmaps-realtime
En-/disable LED maps when receiving realtime data
2024-01-10 18:25:41 +01:00
ezcGman
ff59dcd66e Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime 2024-01-10 05:11:44 +01:00
zanhecht
0a1d82de2a Remove legacy CSS gradient code from liveview.htm
Reduce file size by removing legacy CSS gradient code and moving drawing operations to a separate function
2024-01-09 19:27:45 -05:00
Blaz Kristan
26837645ac Add PWM frequency selection in settings 2024-01-09 21:54:21 +01:00
Janos Stefan
c318699d6a Merge branch 'feature/add-APA106-led' of https://github.com/itstefanjanos/WLED into feature/add-APA106-led 2024-01-09 21:32:40 +01:00
Janos Stefan
e5caab635a Remove compiled html headers. 2024-01-09 21:31:25 +01:00
Janos Stefan
d5f96295ff Add APA106 support 2024-01-09 21:30:41 +01:00
Blaz Kristan
4a6c78aaf3 npm 2024-01-09 19:11:45 +01:00
Blaž Kristan
c4d214f5c0 Merge pull request #3598 from WoodyLetsCode/pio
Automatically build UI before compiling
2024-01-09 19:05:04 +01:00
Blaž Kristan
1ed7e6cb1c Merge pull request #3611 from Aircoookie/suspend
Suspend strip during operations
2024-01-09 18:33:44 +01:00
Blaz Kristan
6b7f80f24a Merge branch '0_15' into suspend 2024-01-09 18:30:27 +01:00
Blaz Kristan
220217561a Possible fix for #3589 & partial fix for #3605 2024-01-09 18:20:20 +01:00
Frank
75e857a510 npm run build 2024-01-09 11:57:34 +01:00
Frank
052bdd8eb0 fix for #3655
make WS2814 explicit in LED driver drop-down menu
2024-01-09 11:54:46 +01:00
Britt Gresham
9e54de8a8a Set 2 values between each segment option
Due to the midi interface being difficult/impossible to increment on
values of 1 because it has 7-bits of granularity, this commit moves all
the bitfields for configuring segment options left by one which
guarantees that every option has 2 values next to each other.

This allows midi controllers to more easily select an individual segment
option for 2D arrays.
2024-01-08 11:16:55 -08:00
Britt Gresham
fd2809e367 Replace bitshifts with masks and division 2024-01-08 11:16:55 -08:00
Britt Gresham
18874c2069 Remove unneeded floor call on segment option channel 2024-01-08 11:16:55 -08:00
Britt Gresham
115eb0ddef Add additional segment options when controlling over e1.31
Before this commit it was only possible to control mirror and reverse on
a 1d segment. All of the other options for 2d effects could not be set
and thus they would be kept disabled.

This commit replaces the Effect Option dmx channel with a bitfield which
allows for each segment option to be individually toggled depending on
which bit is set in the field. Backwards compatibility has been
maintained with existing 1d segment options.
2024-01-08 11:16:55 -08:00
Blaž Kristan
9940258725 Merge pull request #3654 from willmmiles/mpu6050-upgrade
Upgrade the MPU6050 usermod
2024-01-08 19:32:36 +01:00
Blaž Kristan
74e14a4fc3 Merge pull request #3656 from WoodyLetsCode/documentation
Make loadBg() more readable
2024-01-08 19:28:18 +01:00
Blaž Kristan
90ea386c62 Merge pull request #3658 from WoodyLetsCode/colorPicker
Fix that color picker is not centered on screens with width between 1024px and 1249px
2024-01-08 19:24:53 +01:00
Woody
a5b132dfd7 Fix that color picker is not centered
Color Picker was not centerd on screens with width between 1024px and 1249px
2024-01-08 14:20:02 +01:00
Woody
157debf8e4 Make loadBg() more readable 2024-01-07 23:51:38 +01:00
Woody
74a5528f17 Small refactor of isCached function in cdata.js 2024-01-07 23:14:24 +01:00
Woody
21de9e938a Rebuild if command line argument is set 2024-01-07 22:06:20 +01:00
Will Miles
9c4d3cd6e2 platformio.ini: Add MPU6050 library dep 2024-01-07 15:50:15 -05:00
Will Miles
0616d184e0 Add GyroSurge usermod
This usermod applies the IMU data to create a "surge" effect when
the device is moved.
2024-01-07 15:44:11 -05:00
Will Miles
6f8b3a6242 usermod_list: Add IMU usermod 2024-01-07 15:44:11 -05:00
Will Miles
9a006dc84a usermod_mpu6050: Add options and outputs
Upgrade the MPU6050 usermod to provide configuration settings for
interrupt pin selection and calibration, a polled mode, and data
output for consumption by other usermods.
2024-01-07 15:44:11 -05:00
Will Miles
d2dbaf52a1 usermod_mpu6050: Fix debug prints
The MPU6050 library happens to choose the same defines as WLED, which
collide and result in nothing printing.   Un- and re-define the macros
to work around this.
2024-01-07 13:48:41 -05:00
Woody
0a9145cd3c add caching for cdata.js 2024-01-07 01:06:52 +01:00
Woody
e778b02c0c Automatically build UI before compiling 2024-01-07 01:06:52 +01:00
Blaz Kristan
8fb5f0ef3c Changelog update v0.14.1-b3 2024-01-06 20:34:31 +01:00
Blaz Kristan
43f5e4360d Changelog update
Remove obsolete semaphore
2024-01-06 20:28:05 +01:00
Blaž Kristan
cdc8640218 Merge pull request #3648 from willmmiles/json-response-locking
Expand JSON buffer lock scope to entire web reply
2024-01-06 17:16:33 +01:00
Blaz Kristan
21f8d7a967 Bump 2024-01-06 17:04:56 +01:00
Blaž Kristan
801d92bbba Merge pull request #3648 from willmmiles/json-response-locking
Expand JSON buffer lock scope to entire web reply
2024-01-06 17:01:34 +01:00
Will Miles
77116172e4 serveJson: Fix possible memory leak
Ensure we delete the response if it's not locked
2024-01-06 10:24:05 -05:00
Will Miles
9d3c0f4ff0 serveJson: Ensure semaphore scope lasts until reply is done
Extend the JSON response class to hold the global JSON buffer lock
until the transaction is completed.

Fixes #3641
2024-01-06 10:09:07 -05:00
Will Miles
6382d2b730 Add C++-style guard class for JSON Buffer lock
Add JSONBufferGuard, an RAII lock guard class for JSONBufferLock
analogous to std::lock_guard.  This permits binding the guard to a scope,
such as an object life cycle or function body, guaranteeing that the
lock will be released when the scope exits.
2024-01-06 10:05:18 -05:00
Blaž Kristan
6ad4493a91 Merge pull request #3639 from WoodyLetsCode/caching
Improve ETag Caching
2024-01-04 19:16:56 +01:00
Blaz Kristan
f070dc5527 Cosmetic & needsUpdate() 2024-01-04 17:40:23 +01:00
Blaz Kristan
fc6e7c81d3 Merge branch '0_15' into suspend 2024-01-04 17:33:07 +01:00
Woody
59a725c52c Use uint16_t eTagSuffix instead of String 2024-01-03 23:39:45 +01:00
Frank
51b3d7cb4a Merge pull request #3569 from raymondhardy/ESP32-S3-WROOM-1-N16R8
new buildenv for esp32s3dev_16MB_PSRAM_opi dev board (LilyGo T7-S3)
2024-01-03 22:20:01 +01:00
Frank
3baff4e675 Merge pull request #3572 from drasch/fix/esp32c3-2mb-flash-size
fix(esp32c3-2mb): correct flash size for c3 board with only 2MB
2024-01-03 22:18:24 +01:00
Blaž Kristan
06911e7ad0 Merge pull request #3642 from peterpociask/patch-1
Update README.md
2024-01-03 21:16:38 +01:00
PeterP
4e0f3e35db Update README.md
Pointed link to current directions for compiling WLED
2024-01-03 15:08:02 -05:00
Woody
fd6ce57003 Improve ETag Caching
This also adds support for ETag caching for the settings pages
Also fixed some issues with the previous caching not being RFC 7232 compliant.
2024-01-03 18:53:54 +01:00
Blaz Kristan
4f55be4f19 Bugfix #3632 2024-01-01 23:21:22 +01:00
Blaz Kristan
bd20c83919 Bugfix #3632 2024-01-01 23:14:45 +01:00
Blaz Kristan
48f8a45031 Last minute adjustments & fixes 2023-12-31 18:05:21 +01:00
Istvan Meszaros
680cec5abb Make palette editor mobile friendly. 2023-12-30 19:49:08 +01:00
Blaž Kristan
e8b3c66c21 Merge pull request #3617 from imeszaros/cpal-mobile
Make palette editor more mobile friendly
2023-12-30 18:43:49 +01:00
Blaz Kristan
ecdc3be52e Changlog update 2023-12-30 11:56:21 +01:00
Blaž Kristan
301bdf2186 Merge pull request #3610 from Aircoookie/psram-4-json
Allow PSRAM (SPI RAM) to be used for JSON buffer
2023-12-30 11:00:53 +01:00
Blaz Kristan
1c1b67e000 Full per-port ABL implementation and bugfix.
Update of BusManager class (static)
2023-12-29 23:07:29 +01:00
Blaz Kristan
662870baf4 Changlog update, b2 release 2023-12-29 10:35:44 +01:00
Blaz Kristan
bc85520f5e Merge branch '0_15' into suspend 2023-12-28 23:38:42 +01:00
Blaz Kristan
d3be7a3edf Merge branch '0_15' into psram-4-json 2023-12-28 23:38:27 +01:00
Blaz Kristan
6cd0da821a Reduce heap fragmentation when switching ledmaps 2023-12-28 23:32:47 +01:00
Blaz Kristan
1333c41811 Slight tweak to reduce footprint 2023-12-28 20:05:02 +01:00
zanhecht
55eceb4080 Fix Firefox loading order, more resilient fallback to gradient method 2023-12-28 13:06:13 -05:00
Blaz Kristan
e95629f827 Remote preset cancles playlist 2023-12-27 20:14:51 +01:00
Blaz Kristan
6332ee6edb Effect buffer optimisations
setMode() fix for selecting gap
UI error messages
2023-12-27 19:36:25 +01:00
zanhecht
901d56f898 Use canvas instead of CSS gradient for liveview
Allows for "pixel perfect" liveview instead of diffused view, to better match what's shown at https://kno.wled.ge/features/effects/. This will make it easier to see what the LEDs are doing, although it may not be as accurate a representation for installations with diffused LEDs. Includes fallback to CSS gradient method for browsers that don't support canvas.
2023-12-27 13:20:22 -05:00
Istvan Meszaros
010c3494fd Make palette editor mobile friendly. 2023-12-26 11:09:20 +01:00
Blaz Kristan
5ebc345e95 Possible bugfix for #3609 #3616 2023-12-25 17:47:39 +01:00
Blaz Kristan
b3a768a04b Remove check for strip 2023-12-25 12:29:12 +01:00
Blaz Kristan
f414af4d82 Fix incorrect compare 2023-12-25 12:27:27 +01:00
Frank
b743ca8eb1 Merge pull request #3615 from srg74/patch-2
Update readme.md
2023-12-24 20:51:43 +01:00
srg74
a3a5bffce4 Update readme.md
Fixed typo
2023-12-24 12:10:51 -05:00
Blaz Kristan
7971f3cbd8 Fix for saving config. 2023-12-23 22:56:07 +01:00
Blaz Kristan
d1b80aa4d4 Beta2 2023-12-23 21:13:01 +01:00
Blaz Kristan
08d9f7d967 Fix for #2922 2023-12-23 21:05:01 +01:00
Blaz Kristan
5f62b4a89d Fix for #2922 2023-12-23 20:58:55 +01:00
Blaž Kristan
776502e6db Merge pull request #3606 from WoodyLetsCode/welcome
Fix bug that welcome page was not shown
2023-12-23 20:27:20 +01:00
Frank
39e0a1fb9e Merge pull request #3612 from Aircoookie/sunset-fix
workaround for invalid sunrise/sunset times (#3601)
2023-12-23 20:26:02 +01:00
Broersma
5ed02d2f0d Merge branch 'upstream/0_14_2' into usermod_v2_HttpPullLightControl_0.0.5 2023-12-23 13:47:42 +01:00
Frank
72e864b013 sunrise/sunset: fix for ambiguous error value
sunset = 0 is a valid result, as the function result is in UTC and not local time .
Example: local time is UTC-8, local sunrise = 08:00am => getSunriseUTC()  = 0.

So we cannot use "0" for "invalid". Using UINT16_MAX resolves the problem, and even allows to simplify calculateSunriseAndSunset() a bit.
2023-12-23 13:13:10 +01:00
Frank
5ab012163e workaround for #3601
if case of invalid or impossible sunset/sunrise results, retry with the previous day. max 3 days back, to prevent infinite loops and far-away results.
2023-12-22 23:28:58 +01:00
Blaz Kristan
1900686bc4 Bump 2023-12-22 15:49:51 +01:00
Blaz Kristan
809a294f9d Fix Pixel Magic button. 2023-12-22 15:43:31 +01:00
Blaz Kristan
cf3f6ede72 Suspend strip during operations 2023-12-22 15:39:07 +01:00
ezcGman
b76a90304d Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime 2023-12-22 13:19:44 +01:00
Woody
7af5b24b03 Fix bug that welcome page was not shown 2023-12-21 22:17:43 +01:00
Blaz Kristan
1f81fb9284 Implement JSON buffer in PSRAM to free up DRAM. 2023-12-21 21:30:17 +01:00
Blaz Kristan
4e105492ca Retry on failed JSON load.
Throttle for ESP8266
This is a band-aid for ESP8266 JSON corruption and not a proper fix.
2023-12-21 21:02:53 +01:00
Blaž Kristan
abf7dd5fa8 Merge pull request #3587 from WoodyLetsCode/search-scroll-top
Scroll to first search result on search
2023-12-21 20:49:44 +01:00
Blaž Kristan
6c877b6d44 Merge pull request #3597 from WoodyLetsCode/inline
Inline iro.js and rangetouch.js
2023-12-21 20:43:29 +01:00
Xaver
86d2998dc0 Add reference to old loading of iro.js and rangetouch.js 2023-12-20 11:30:28 +01:00
Woody
201daf8ff3 Remove /iro.js and /rangetouch.js 2023-12-19 22:40:24 +01:00
Woody
1140f5f6cb Update version to 2312190 2023-12-19 21:18:33 +01:00
Woody
0a91d60677 add onload event to body 2023-12-19 21:12:07 +01:00
Woody
5cd8f5681e Remove unused feedback function
This was probably forgotten to remove in commit d6c0642a02
2023-12-19 20:41:56 +01:00
Xaver
b2babd9502 inline iro.js and rangetouch.js 2023-12-19 16:52:15 +01:00
Blaz Kristan
10faaaf531 Build bump & changelog 2023-12-18 21:52:22 +01:00
Blaž Kristan
7642c5a50d Merge pull request #3529 from Aircoookie/0_14_1
0.14.1-beta
2023-12-18 21:20:12 +01:00
Blaz Kristan
42dba3170d Fix for #3593 2023-12-17 22:16:57 +01:00
Blaz Kristan
5c90a742ba Fix for #3593 2023-12-17 22:15:28 +01:00
Blaz Kristan
9e57ef074d Simplify PIR usermod
- remove periodic updates
- immediately trigger MQTT
- call mode chang to CALL_MODE_BUTTON
2023-12-17 12:56:30 +01:00
Blaz Kristan
9e9b1c3c98 Fix for incorrect move of MQTT publish 2023-12-17 12:14:44 +01:00
Blaz Kristan
13d5deddec Fix buffer overwrite in PIR MQTT 2023-12-17 11:34:44 +01:00
Blaž Kristan
8522760c70 Merge pull request #3591 from WoodyLetsCode/caching
Fix ETag caching
2023-12-16 13:31:07 +01:00
Blaž Kristan
5bc2282ac5 Merge branch '0_15' into caching 2023-12-16 13:27:50 +01:00
Blaz Kristan
2944b2a8f6 Merge branch '0_15' into temporary-AP 2023-12-16 13:07:40 +01:00
Blaž Kristan
264480b9bc Merge pull request #3586 from WoodyLetsCode/aircoookie-link
Add link to Aircoookie in Info
2023-12-16 13:04:54 +01:00
Blaž Kristan
7d52cc46dc Merge pull request #3590 from WoodyLetsCode/style
Send empty page if skin.css does not exist
2023-12-16 13:03:39 +01:00
Blaž Kristan
37c9fd278c Merge pull request #3511 from WoodyLetsCode/simple-mode
New implementation of the simplified UI
2023-12-16 13:02:18 +01:00
Blaz Kristan
3d6fe0a565 Reduce memory fragmentation 2023-12-16 12:38:15 +01:00
Frank
da488f76d2 LDR_Dusk_Dawn: use pinManager, check ldrPin before use (quick-fix for #3490) 2023-12-15 21:58:05 +01:00
Frank
6d28de77d1 npm run build
refreshing all UI files
2023-12-14 20:47:58 +01:00
Frank
a8bd46c521 bugfix - unusable pins on pico32 boards (#3573)
According to the technical manual, GPIO 16 + 17 are used for onboard flash, so cannot be used by WLED.

example buildenv:

[env:esp32_pico]
extends = env:esp32dev_qio80
board = pico32
2023-12-14 20:36:05 +01:00
Frank
1ec3a74d4c Manila Time is the same as CST (solves #3517)
PHST abbreviation added for clarity.
2023-12-14 19:44:36 +01:00
Blaz Kristan
076449a33d Strings in flash 2023-12-14 18:34:00 +01:00
Blaz Kristan
1b5cc2abf1 Button handling
- debug messages
- verify touch GPIO
2023-12-14 18:32:54 +01:00
Blaz Kristan
b176225910 Add Domoticz MQTT API
- to PIR sensor
- to Dallas temperature
2023-12-14 18:30:24 +01:00
Frank
082d1eea48 oappend robustness improvement
obuf is reset to nullptr in some cases
2023-12-14 15:58:45 +01:00
Woody
e99dfbae0d Fix ETag caching 2023-12-14 14:41:08 +01:00
Frank
d6735bed4f comment clean-up (cosmetic) 2023-12-14 13:53:56 +01:00
Woody
b024d93fa0 Send empty page if skin.css does not exist
This has the advantage that we do not need to send the 404 error page every time
2023-12-14 13:21:09 +01:00
Frank
dbe8554724 code spell checking - part3 (usermods)
if you can spell Fahrenheit, you can't spell Celsius. And vice versa :-)
2023-12-14 03:52:06 +01:00
Frank
9f79e64678 code spell checking - part2 (dependencies) 2023-12-14 03:50:22 +01:00
Frank
f513cae66e code spell checking - part1 (core)
I've found a code spellchecker, so this is what can be corrected easily. Changes are only affecting comments, readme and a few user-visible strings. So no functional impact expected.
2023-12-14 03:49:54 +01:00
Woody
37b807210e Scroll to first search result on search 2023-12-13 21:42:24 +01:00
Xaver
15e26ba929 Add link to Aircoookie in Info 2023-12-13 11:34:25 +01:00
Woody
db1795981f Fix dialog backdrop blur on Safari 2023-12-13 00:38:13 +01:00
Woody
2a40baf509 Update backdrop-filter blur value in index.css 2023-12-13 00:24:56 +01:00
Woody
2dbf72e452 Better implementation of dialog 2023-12-12 23:57:20 +01:00
Blaz Kristan
67ae716c60 JSON HTTP error handling 2023-12-12 15:45:57 +01:00
Janos Stefan
8dfb130d19 Remove compiled html headers. 2023-12-11 12:23:45 +01:00
Janos Stefan
2a42fea32a Add APA106 support 2023-12-11 09:26:20 +01:00
Blaz Kristan
f69edefddf Segment syncing debug info 2023-12-10 10:12:58 +01:00
Blaz Kristan
6f3b5fc559 Add JSON API for AP toggle 2023-12-10 09:59:36 +01:00
Blaz Kristan
7275a34e1f Partial fix for #3578 2023-12-09 22:39:26 +01:00
Blaz Kristan
687e2ecaaa Merge branch '0_15' into simple-mode 2023-12-09 19:41:36 +01:00
Blaz Kristan
64312aedae npm and minor tweak 2023-12-09 19:29:32 +01:00
Blaz Kristan
391876e557 Autowhite cleanup
Fix for USC8904 hasWhite()
2023-12-09 19:03:33 +01:00
Blaz Kristan
cb95a7d418 Autowhite cleanup
Fix for UCS8904 hasWhite().
2023-12-09 18:58:45 +01:00
Woody
830f806dee Fix segments not be displayed in simplified ui 2023-12-08 12:17:28 +01:00
Woody
21c2316f6b Minor optimizations 2023-12-08 11:41:00 +01:00
Woody
930a1ae450 Fix dialog scrollbar on Firefox 2023-12-07 17:09:56 +01:00
Woody
aec331b5a6 Add selected palette and effect names to dropdown 2023-12-07 14:58:33 +01:00
Woody
1db6c281b1 Hide buttons for pixel art and custom palettes 2023-12-07 13:11:34 +01:00
ezcGman
5b70ca81a7 Dropped RLM again from HTTP API 2023-12-06 21:42:17 +01:00
ezcGman
d00df785a5 Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime 2023-12-06 21:41:34 +01:00
Woody
d0c6e7a285 Add check if UI was already simplified 2023-12-06 19:20:58 +01:00
Woody
058995a0b6 fix selected effect position 2023-12-06 18:57:34 +01:00
Woody
fd3be887b4 Add dropdown for effects 2023-12-06 17:48:14 +01:00
skinnyquiver
84802d9065 [fix] Uses extends as per softhack007 comment 2023-12-05 10:36:31 -06:00
David Rasch
90d696d826 fix(esp32c3-2mb): correct flash size for c3 board with only 2MB 2023-12-05 10:54:32 -05:00
skinnyquiver
aeb9e2ad9f [fix] Removes additional default envs line 2023-12-04 19:24:35 -06:00
skinnyquiver
26ab1bfd4f [Feat] Adds new esp32s3dev_16MB_PSRAM_opi dev board to work with LilyGo T7_s3 ESP32-S3-WROOM-1-N16R8 2023-12-04 19:17:15 -06:00
Woody
23d44cb28b Update top position in .dialog CSS
for better mobile appearance
2023-12-04 20:42:33 +01:00
Broersma
de4b352495 Fix AsyncClient hangs 2023-12-02 16:23:21 +01:00
Blaz Kristan
d635117194 Bugfix ledtype 2023-12-02 12:15:57 +01:00
Blaz Kristan
c0412d368e SEGLEN bugfix if default map1D2D not defined
- comments
2023-12-02 00:48:49 +01:00
Blaz Kristan
7ec30f0796 FX:
- Matrix bugfix
- Lissajous metadata fix
2023-12-02 00:47:16 +01:00
Blaz Kristan
9815a55221 Bugfix #3561 2023-12-02 00:45:35 +01:00
Blaz Kristan
7c108e5128 Bugfix for SEGENV if defult map1D2D not defined 2023-12-02 00:44:30 +01:00
Blaz Kristan
4873031c37 Bugfix #3561 2023-12-02 00:39:43 +01:00
Blaz Kristan
15d23870c1 Tootip bugfix 2023-12-01 16:29:05 +01:00
Woody
2abbf7e762 Hide palette dialog if not available 2023-12-01 15:31:28 +01:00
Woody
1578aa7cb6 Finalize rebase 2023-12-01 14:09:02 +01:00
Woody
f2230751e7 Update padding of palette dialog 2023-12-01 11:57:38 +01:00
Woody
8fc0dda26d Reset scrolling when opening pallet dialog 2023-12-01 11:57:38 +01:00
Woody
0ab71badfa Clear palette search when dialog is opened 2023-12-01 11:57:38 +01:00
Woody
0f24d924f9 Update background color of palette dialog 2023-12-01 11:57:38 +01:00
Woody
518a0de95f minor tweak 2023-12-01 11:57:38 +01:00
Woody
fa5648c0c3 Remove hideD class to use hide class instead 2023-12-01 11:57:38 +01:00
Christophe Gagnier
bd620a764d Fix width issue with simplified UI due to desktop mode leftovers 2023-12-01 11:53:46 +01:00
Christophe Gagnier
cff42b5d27 Improve palette list resizing a bit 2023-12-01 11:53:46 +01:00
Christophe Gagnier
25eef2a40e Show palette selection in a dialog 2023-12-01 11:51:50 +01:00
Woody
db276d5f1f moved segcont simplification to simplifyUI() 2023-12-01 11:51:50 +01:00
Blaz Kristan
ce0d906c35 Dev mode fix. 2023-12-01 11:51:49 +01:00
Blaz Kristan
520826abc0 Minor tewaks. 2023-12-01 11:51:49 +01:00
Woody
5e1d6014d5 Fix color picker 2023-12-01 11:51:49 +01:00
Woody
32af17317c minor improvements 2023-12-01 11:51:49 +01:00
Woody
3e7cc8a0a0 add comment for simplifyUI() 2023-12-01 11:51:49 +01:00
Woody
f717ce52fa Display effect mode text on small screens 2023-12-01 11:50:07 +01:00
Woody
d880f3c628 Add palette list dropdown 2023-12-01 11:50:07 +01:00
Woody
0a97717b35 Add simplified segments 2023-12-01 11:50:07 +01:00
Woody
029403ea10 Only Effect Search should stay on top 2023-12-01 11:50:07 +01:00
Woody
e4ec65622f Enable simplifiedUI by default 2023-12-01 11:50:07 +01:00
Woody
3ee3b97255 Remove old simplifiedUI code and update cdata.js 2023-12-01 11:09:42 +01:00
Woody
a3dd6ce891 simplifiedUI moved to index.js 2023-12-01 11:09:11 +01:00
Woody
0c97d7701e Remove no longer needed code for simplifiedUI 2023-12-01 10:55:14 +01:00
Woody
b852b6f55c Add simplifiedUI to info object 2023-12-01 10:55:14 +01:00
Woody
d3b7b857a4 Fix palette list shadow of selected option
Fix padding and margin in pallist element

Fix palette list shadow of selected option
2023-12-01 10:55:13 +01:00
Woody
63ad3f9290 Show brightness slider 2023-12-01 10:55:13 +01:00
Woody
40cc30e054 Remove unnecessary comment in simple.js 2023-12-01 10:55:13 +01:00
Woody
23374e98ae Added preset quick load before palette list 2023-12-01 10:55:13 +01:00
Woody
40f544fffc Reimplemented simplified UI 2023-12-01 10:52:45 +01:00
ezcGman
4fc69c9a2c Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime 2023-11-29 20:14:51 +01:00
ezcGman
2e5a485804 Realtime LED Maps: Feedback applied 2023-11-29 20:12:31 +01:00
Blaz Kristan
2d10b5be90 from #3555 2023-11-29 13:46:35 +01:00
Blaž Kristan
b0d0bb7953 Merge pull request #3555 from srg74/patch-1
Update readme.md
2023-11-29 13:42:43 +01:00
Blaž Kristan
8c69b85280 Merge pull request #3540 from WoodyLetsCode/search
Improve search and filter functionality
2023-11-29 13:41:38 +01:00
Blaz Kristan
9d6d1e4ff8 npm 2023-11-29 13:37:37 +01:00
Blaz Kristan
e71c72b4a2 Remove re-seeding FastLED random8/random16 in FX 2023-11-29 13:33:10 +01:00
Blaž Kristan
bf4b29b3e3 Merge pull request #3552 from TripleWhy/seedRandom16
Seed FastLED's RNG
2023-11-29 13:30:06 +01:00
Blaz Kristan
8e0809ceba Code size reduction 2023-11-29 11:56:47 +01:00
Broersma
230af48899 Fixing parsing only VALID JSON, in the past, when invalid JSON, the WLED runtime would crash 2023-11-28 12:04:41 +01:00
ezcGman
9dc459192e Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime 2023-11-28 11:49:53 +01:00
Blaz Kristan
8de2301c6b Usermod transition change 2023-11-28 10:46:04 +01:00
Blaz Kristan
f66b343edd Possible fix for #3541 2023-11-28 10:42:18 +01:00
srg74
ff82d36e94 Update readme.md
Fix typo
2023-11-27 22:47:07 -05:00
Blaz Kristan
c3e937f5e0 Fix for #3514 2023-11-27 20:58:21 +01:00
TripleWhy
25c5e823d9 Seed FastLED's random functions during startup
This allows effects or color palettes that use FastLED's RNG to be
different each time the device is powered on.
2023-11-27 18:44:09 +01:00
TripleWhy
528b8b1271 Use FastLED's random functions instead of arduino's for all effects 2023-11-27 18:18:47 +01:00
Blaz Kristan
b88344a6c0 Second attempt at #3541 2023-11-27 14:24:07 +01:00
Blaz Kristan
9e135cc81d Hide transitions if not enabled. 2023-11-27 13:39:52 +01:00
Blaz Kristan
72ef288357 Fix for #3514 2023-11-27 13:34:35 +01:00
Blaz Kristan
426ac29ca5 Possible fix for #3541 2023-11-27 13:27:52 +01:00
Woody
ceb330e3e4 Do not hide filter menu if filter is active 2023-11-26 18:15:00 +01:00
Woody
7ea8f741f2 Make code more readable 2023-11-26 17:35:29 +01:00
Woody
443c9fba03 Fix search input focus issue 2023-11-26 17:07:42 +01:00
Blaž Kristan
0227f79bd7 Merge pull request #3547 from micw/feature/wiz-smart-button-0.15
Support for wiz smart button
2023-11-25 19:17:36 +01:00
Michael Wyraz
2812eaa13d Support for wiz smart button 2023-11-25 16:42:39 +01:00
Woody
cb293fcdb3 Fix filter hiding on chrome 2023-11-24 13:48:12 +01:00
Woody
706428fe98 Fix filterFx function calls 2023-11-24 13:21:03 +01:00
Woody
698f5f951e Fix search function behavior when filter is active 2023-11-24 13:04:29 +01:00
Woody
155c12f657 Improve search and filter functionality 2023-11-24 11:24:34 +01:00
ezcGman
a36c731d15 En-/disable LED maps when receiving realtime data 2023-11-23 17:13:13 +01:00
Blaz Kristan
6a793536dd Add button type: Touch (switch) #3537 2023-11-22 15:35:11 +01:00
Blaz Kristan
27532a4237 Add new AP type to prevent user frustration. 2023-11-22 15:30:04 +01:00
Blaz Kristan
467f69f50e Switch off AP after 5min
- when no clients are connected in "No connection after boot" mode
2023-11-21 17:23:51 +01:00
Frank
32e724e744 Merge pull request #3536 from Aircoookie/ntp_errorchecking
NTP validation, and rejecting malformed responses (related to #3515)
2023-11-20 21:13:35 +01:00
Frank
5fb891c495 indentation fix2 2023-11-20 19:24:04 +01:00
Frank
d56cefdc7a indentation fix 2023-11-20 19:20:18 +01:00
Frank
80c67d37c0 bufix: ntp query when NTP gets enabled from UI
when NTP got enabled via UI, WLED would wait up to 12 hours before issuing the first NTP request.
2023-11-20 15:13:39 +01:00
Frank
1e29d9463e validate NTP responses (fixes #3515)
* purge old (not yet processes) NTP responses
* validate server responses before updating WLED time
* purge receive buffer when package is rejected (avoids mem leak on esp32)
2023-11-20 12:24:34 +01:00
Blaz Kristan
75f6a53269 Fix (#3522) 2023-11-18 18:50:19 +01:00
Blaz Kristan
b5a8f3156c Bugfix (#3522) 2023-11-18 18:49:29 +01:00
Blaž Kristan
de245c08ce Merge pull request #3483 from ajotanc/pxm_update
Update Pixel Magic Tool
2023-11-18 18:34:55 +01:00
Blaž Kristan
76a7f25083 Merge pull request #3522 from martinez20m/fix_ir_repeat
Fix repeatable action for ir json
2023-11-18 18:29:46 +01:00
Blaz Kristan
d9a96fbb29 Bugfix (#3533) 2023-11-18 18:24:22 +01:00
Blaz Kristan
16617660c3 Bugfix (#3533) 2023-11-18 18:22:47 +01:00
Blaž Kristan
a83d9a075f Merge pull request #3508 from Moustachauve/fix-settings-cache
Fix settings caching on some browsers
2023-11-17 08:48:21 +01:00
Christophe Gagnier
eca3fb1e19 Revert "Implement front-end strategy to prevent caching"
This reverts commit 51dfa9a247.
2023-11-16 21:21:09 -05:00
Blaz Kristan
41bc799c3f 0.14.1 changelog 2023-11-16 20:37:03 +01:00
Blaz Kristan
44726c7411 Changelog 0.14.1-b1 2023-11-16 19:34:53 +01:00
Blaz Kristan
8f7f9ec367 Feature: Per-port ABL 2023-11-15 19:37:07 +01:00
Blaz Kristan
21de8f2284 Effect: 2D Matrix gap fix 2023-11-15 18:05:44 +01:00
Blaz Kristan
15797a89e7 Bugfix (#3526) 2023-11-15 18:04:54 +01:00
Blaz Kristan
c340a1d47f Bugfix (#3526) 2023-11-15 18:04:14 +01:00
Broersma
71cec39bc4 update to 0.0.4 includes SHA1 hash instead of old 10digit hash 2023-11-15 17:24:05 +01:00
Broersma
882542318c Update to v0.0.3, allowing all WLED JSON giving much more possibilities 2023-11-13 22:05:15 +01:00
Marcin Skiba
7238ef4f55 Fix repeatable action for ir json 2023-11-13 12:28:05 +01:00
Blaz Kristan
1049d65621 Changelog update 2023-11-12 14:21:50 +01:00
Blaž Kristan
552ae836e9 Merge pull request #3501 from TripleWhy/spookierEyes
A spookier version of Halloween Eyes
2023-11-12 14:01:56 +01:00
Blaz Kristan
1852c0a88c Merge branch '0_15' into spookierEyes 2023-11-12 12:49:02 +01:00
Blaz Kristan
d0d399bdfc Revert to comparing _data for double buffering
- warning: test for potential FPS drop (regression)
2023-11-12 12:45:28 +01:00
Blaz Kristan
3975fe0f02 Unload playlist on Wiz remote preset button press 2023-11-12 12:41:14 +01:00
Blaž Kristan
0739cfc240 Merge pull request #3498 from chrisburrows/multi-relay-settings
Allow more compile time settings for multi-relay
2023-11-10 19:54:41 +01:00
Chris Burrows
f31bf4f7c9 Updated readme 2023-11-10 17:36:48 +00:00
Blaz Kristan
f413671915 Focus fix. 2023-11-09 17:14:40 +01:00
Christophe Gagnier
e67a210e95 Implement back-end strategy to prevent caching
By setting the response header "Cache-Control" to "no-store" and setting "Expires" to 0, we make sure the browsers and place calling this never store it in cache.
2023-11-08 23:46:31 -05:00
Christophe Gagnier
51dfa9a247 Implement front-end strategy to prevent caching
By adding a random string to the path of the js file every time, we make sure to never hit the browser cache.
2023-11-08 23:45:48 -05:00
Blaz Kristan
7c121b8ba6 Dissolve fix (#3502) 2023-11-08 18:42:43 +01:00
Blaz Kristan
ae92a5c25e Dissolve fix (#3502) 2023-11-08 18:41:46 +01:00
Blaz Kristan
fabd3b8421 Better reverse proxy support. 2023-11-08 18:40:52 +01:00
Chris Burrows
94d754e63a Allow more compile time settings 2023-11-07 16:06:03 +00:00
Blaz Kristan
f869542a47 Changelog update. 2023-11-06 20:39:58 +01:00
Blaz Kristan
2b616b688d Implement global JSON API boolean toggle. 2023-11-06 20:08:45 +01:00
TripleWhy
0925ea6f9c Add some comments 2023-11-04 16:12:22 +01:00
TripleWhy
87b5565679 Minor simplification 2023-11-04 16:12:10 +01:00
TripleWhy
adcecf969a Simplify casting a bit, where possible 2023-11-04 15:54:21 +01:00
TripleWhy
f3831665d4 Fix type name 2023-11-04 15:48:22 +01:00
Blaz Kristan
9db8d44654 Sort presets by ID 2023-11-04 09:51:25 +01:00
Blaz Kristan
e1075a3bbf Sort presets by ID 2023-11-04 09:39:08 +01:00
TripleWhy
3b6f499fc5 Reduce EyeData size by a few bytes 2023-11-02 18:31:58 +01:00
TripleWhy
2c1fbe103b Spookier version of Halloween Eyes 2023-11-02 18:12:18 +01:00
Blaž Kristan
1543862f3b Merge pull request #3490 from JeffWDH/main
Add LDR sensor dusk/dawn preset control Usermod
2023-11-02 16:47:00 +01:00
JeffWDH
5b7b34a9f0 Add LDR sensor dusk/dawn preset control Usermod 2023-11-02 11:20:08 -04:00
Blaž Kristan
fb6271eecf Merge pull request #3496 from WoodyLetsCode/power-supply
Fix wrong power supply info
2023-11-01 10:35:57 +01:00
Blaz Kristan
031526b619 Correction 2023-11-01 10:29:52 +01:00
Blaz Kristan
e42ca2dbf2 Fix #3496 2023-11-01 10:28:57 +01:00
Blaz Kristan
4f5816f42e Merge branch '0_14_1' into power-supply 2023-11-01 10:26:42 +01:00
Blaz Kristan
555d0d3378 Npm & version comment 2023-11-01 10:23:57 +01:00
Blaž Kristan
1495b756d3 Merge pull request #3481 from WoodyLetsCode/random-bg-img
Improved random bg image and added random bg image options
2023-10-31 10:27:47 +01:00
Blaz Kristan
7f78d00b97 Tweaks 2023-10-31 10:21:00 +01:00
Blaz Kristan
bfd58b3cdf Merge branch '0_15' into random-bg-img 2023-10-31 09:24:08 +01:00
Blaz Kristan
e260b9473a Bump build 2023-10-31 09:20:54 +01:00
Blaž Kristan
ccc56d446f Merge pull request #3484 from WoodyLetsCode/settings-page
Show 2D Configuration button by default
2023-10-31 09:17:50 +01:00
Blaz Kristan
31a4e38bc0 Shave a few bytes. 2023-10-30 13:43:50 +01:00
Woody
284366e6bb fixed wrong power supply info 2023-10-29 19:04:54 +01:00
Blaz Kristan
9c6dda9bd2 Segment copy bugfix
Audio palette modification
2023-10-29 11:27:17 +01:00
Blaz Kristan
e5f6f8dfa7 Twinklefox & Twinklecat fix 2023-10-28 21:04:19 +02:00
Blaz Kristan
0232117de5 Twinklefox fix
Tooltip tuning
2023-10-28 21:02:49 +02:00
Blaz Kristan
96700fe3d1 Fix for udp sync (#3487) 2023-10-27 17:49:48 +02:00
Blaz Kristan
367a4e17a2 Fix udp sync (fix for #3487) 2023-10-27 17:48:19 +02:00
Blaz Kristan
eba0d7c1e0 Remove loggong. 2023-10-27 16:53:08 +02:00
Blaz Kristan
341a4a0d60 Fix sticky top. 2023-10-27 16:35:03 +02:00
Blaz Kristan
d116424241 Filter dropdown. 2023-10-26 22:09:46 +02:00
Blaz Kristan
db881ee011 Small optimisations.
2D liveView (non-WS) core
soundSim fix
2023-10-25 20:27:01 +02:00
Woody
34bed44a9b Hide 2D Configuration if 2D is not compiled in 2023-10-25 18:33:31 +02:00
Xaver
d431aa4b59 Show 2D Config button by default 2023-10-25 08:33:07 +02:00
Alerson Jorge
2512bebc62 Corrections
- CSS adjustments
- Removal of some html
- Correction of CORS error when using the file locally, it was unable to generate the images that are saved in WLED
- Among others that I don't remember now
2023-10-24 18:56:12 -03:00
Alerson Jorge
309dbd7585 Fixies
- Correction in animation generation that was actually breaking
- Button to return to WLED if pxmagic.htm is accessed via url (http://), if accessed via external (file://) the button will not show
- Adjustments to CSS and some features
2023-10-24 13:28:33 -03:00
Alerson Jorge
a1f28caa8e Update Pixel Magic Tool
Reducing the size of HTML/CSS/Javascript
2023-10-24 12:52:06 -03:00
Woody
4204393337 Merge branch '0_15' into random-bg-img 2023-10-23 22:21:01 +02:00
Blaz Kristan
789e34702b Pixel Magic logo 2023-10-23 21:06:53 +02:00
Blaz Kristan
47bc1bf88d Merge branch '0_14_1' into 0_15 2023-10-23 20:18:55 +02:00
Blaz Kristan
9867227ccd Increase IRAM at the expense of cache for ESP8266 2023-10-23 19:30:44 +02:00
Blaz Kristan
26302d478e Shave a few bytes. 2023-10-23 19:26:02 +02:00
Blaž Kristan
0decf94c9c Merge pull request #3480 from knarfd/0_14_1
Add #HH and #MM time options for ScrollingText effect
2023-10-23 19:20:17 +02:00
knarfd
0ae78efd43 Update FX.cpp 2023-10-23 18:28:47 +02:00
Woody
b5af6b0bf9 added options for random bg image 2023-10-23 17:30:15 +02:00
Blaž Kristan
3eabefd3d6 Merge pull request #3466 from WoodyLetsCode/fix-effect-jumping
Fix jumping of selected effect on refresh
2023-10-22 19:12:49 +02:00
Woody
7ff6a6e0e7 updated html_ui.h via npm run build 2023-10-22 18:26:52 +02:00
Woody
94dc611024 Merge pull request #1 from WoodyLetsCode/0_14_1
update to 0.14.1
2023-10-22 18:20:24 +02:00
Woody
0b28107432 Merge branch 'fix-effect-jumping' into 0_14_1 2023-10-22 18:19:15 +02:00
Blaz Kristan
fe717dad7f Possible fix for:
- #3382
- #3312
2023-10-22 17:54:00 +02:00
Blaz Kristan
fb3816e2e5 Possible fix for:
- #3382
- #3312
2023-10-22 17:53:16 +02:00
Blaz Kristan
535bf4c848 npm 2023-10-22 12:37:27 +02:00
Blaž Kristan
1fc60b0682 Merge pull request #3460 from mountainash/fix/broken-asset-links
Fixed broken Alphacoders hosted assest asset links
2023-10-22 11:41:15 +02:00
Mountain/\Ash
302f1ee8e3 removed: past Easter event 2023-10-22 11:02:26 +02:00
Mountain/\Ash
42aec56b8e refactor: removed trailing whitespace 2023-10-22 11:02:26 +02:00
Mountain/\Ash
199c00c59b fix: image URLs moved on alphacoders 2023-10-22 11:02:26 +02:00
Blaž Kristan
107bb14555 Merge pull request #3296 from ajotanc/pxmagic
Updating pxmagic and WLED UI
2023-10-21 20:22:06 +02:00
Blaz Kristan
5820792013 Revert changes. 2023-10-21 20:12:22 +02:00
Blaz Kristan
0e20248494 Fix gitignore. 2023-10-21 20:01:12 +02:00
Blaz Kristan
c4f4b247bc Merge branch 'main' into 0_15 2023-10-21 19:52:49 +02:00
Blaz Kristan
0d66bc49c2 Merge branch 'main' into 0_14_1 2023-10-21 19:52:29 +02:00
Blaž Kristan
bdc78a826f Merge pull request #3464 from ajotanc/new_feature
UI tooltips (interface improvements)
2023-10-21 19:27:01 +02:00
Blaz Kristan
6570062e61 Slight tweaks. 2023-10-21 19:18:45 +02:00
Woody
820facb833 Removed unnecessary text 2023-10-21 18:13:01 +02:00
Alerson Jorge
a933fcf7e2 Optimisations, and fix variable multiplier in tooltip() 2023-10-20 19:13:45 -03:00
Alerson Jorge
2d3039c6a2 Fix 2023-10-20 18:22:13 -03:00
Alerson Jorge
aca01044f4 Add brand
Since PXM will not open internally but on another page from the button, I decided to add the logo again if it's not a problem of course.. Just so I don't run out of information
2023-10-20 18:20:28 -03:00
Blaz Kristan
dffd1b1d69 Optimisations.
- tooltip everywhere
- smaller footprint
- fix brightness div
2023-10-20 21:32:39 +02:00
Alerson Jorge
14fc64f2f1 Fix
Checkbox fixes added
2023-10-20 12:20:49 -03:00
Woody
04791d06d0 hide URL field when Random BG image is checked 2023-10-20 15:58:25 +02:00
Alerson Jorge
a485451328 Fix tooltip
Messages showing correctly according to their respective effect.
2023-10-20 09:27:00 -03:00
Woody
c7d399c122 fix effect jumping on refresh
fix effect jumping on refresh

fix jumping of selected effect on refresh
2023-10-20 12:08:11 +02:00
Alerson Jorge
df155bed89 Merge branch 'new_feature' of https://github.com/ajotanc/WLED into new_feature 2023-10-19 16:39:17 -03:00
Alerson Jorge
3ee3630d22 Correction
Correction of the sliders in the `setEffectParameters()` function to eliminate the need to update the old tooltip span.
2023-10-19 16:39:00 -03:00
Alerson Jorge
6b2911b8c8 Merge branch '0_15' into new_feature 2023-10-19 15:20:32 -03:00
Blaz Kristan
d474200d7f Power button override (solves #3431)
Simple CSS optimisation.
2023-10-19 18:54:54 +02:00
Alerson Jorge
cc6f6277f6 Squashed commit of the following:
commit 1dab26bcbc
Author: Christian Schwinne <dev.aircoookie@gmail.com>
Date:   Thu Oct 19 13:29:46 2023 +0200

    Update Discord invite links to point to guidelines channel
2023-10-19 13:49:52 -03:00
Alerson Jorge
0521e988bc UI interface improvements 2023-10-19 12:47:37 -03:00
Alerson Jorge
832ff39eb6 Revert "UI interface improvements"
This reverts commit 134798e82f.
2023-10-19 12:45:41 -03:00
Alerson Jorge
134798e82f UI interface improvements
Improvements in tooltip creation
2023-10-19 12:41:08 -03:00
Alerson Jorge
b6f43966ea Some functionality improvements 2023-10-19 09:30:28 -03:00
Christian Schwinne
1dab26bcbc Update Discord invite links to point to guidelines channel 2023-10-19 13:29:46 +02:00
Blaz Kristan
afa7be6fdc CSS optimisation 2023-10-17 20:55:10 +02:00
Blaž Kristan
36290c20aa Merge pull request #3445 from Moustachauve/ota-lock-post-fix
Update response code when access is denied
2023-10-17 06:29:43 +02:00
Alerson Jorge
c33c7eb68e Correction related to enabling and disabling PXM in the User Interface 2023-10-16 19:27:11 -03:00
Alerson Jorge
5da33afecd Corrections made, added in a very accessible place
I added the possibility of using the tooltip on buttons (.btn) with the span inside the button;
Adjusted the tooltip css to center 100% in the middle
Some cleaning and correction of sele
2023-10-16 19:09:43 -03:00
Blaz Kristan
a49b49aaa9 Request throttling
UI/UX improvements
2023-10-16 18:34:51 +02:00
Christophe Gagnier
225fd0d05b Update response code when access is denied
Having the wrong pin would result in a server error (500). The more appropriate error code for that would be 401.
This also changes the page that asks for users to login from 200 to 401.
2023-10-16 03:19:14 -04:00
Alerson Jorge
c43b4f9cf0 Merge branch 'main' into pxmagic 2023-10-16 01:22:41 -03:00
Alerson Jorge
3581f4c87e Modifications 2023-10-16 01:18:00 -03:00
Alerson Jorge
7a4e0cc850 Revert "Modifications"
This reverts commit ba49da75de.
2023-10-16 01:15:21 -03:00
Alerson Jorge
ba49da75de Modifications 2023-10-16 01:10:40 -03:00
Blaz Kristan
f329a5950e Speed optimisations. 2023-10-15 13:06:40 +02:00
Blaž Kristan
d95158003c Merge pull request #3368 from tetele/usermod-ssdr-leading-zero
Usermod SSDR - allow configurable leading zero
2023-10-14 20:50:53 +02:00
Blaz Kristan
1be6223a31 Pixelmagic optimisation
Filter tooltips
2023-10-14 20:44:11 +02:00
Blaz Kristan
76178b423e Fix pixel magic 2023-10-14 18:10:37 +02:00
Blaz Kristan
195e537499 Merge branch '0_14_1' into 0_15 2023-10-14 17:39:20 +02:00
Blaž Kristan
418abc2b0a Merge pull request #3414 from DanCaveman/max-fan-pct-to-pwm-fan-usermod
added the max fan pct to the PWM-Fan usermod.
2023-10-14 17:31:38 +02:00
Blaz Kristan
277f0346f2 0.14.1 alpha 1 2023-10-13 20:42:19 +02:00
Blaz Kristan
6148cbb122 Merge branch 'main' into 0_14_1 2023-10-13 20:40:42 +02:00
Frank
3847bfc41a npm run build
plus fixing a small typo in VERSION
2023-10-13 13:55:13 +02:00
Frank
783424dd26 version bump 0.14.0 (release) 2023-10-13 13:45:25 +02:00
Blaz Kristan
4c1861dd27 Merge branch 'main' into 0_15 2023-10-12 23:08:32 +02:00
Blaz Kristan
7f6486c77d Custom palette gamma
Mode blending option
Optimisations
2023-10-12 23:06:39 +02:00
Blaz Kristan
1b2a50f9a3 Minor optimisation 2023-10-12 16:15:16 +02:00
Frank
5dadf92a62 also change second discord link in readme
seems this was missing in the previous PR.
2023-10-11 21:09:56 +02:00
Frank
76821addd7 Merge pull request #3437 from chrishultin/fix_discord_invite
Updating "Discord" invite to point to #general
2023-10-11 21:07:22 +02:00
Christopher
a769c55c72 Updating "Discord" invite to point to #general 2023-10-11 09:58:58 -06:00
Blaz Kristan
347ec91bfc notify() bugfix 2023-10-08 22:44:30 +02:00
Frank
4245767357 fix for partly uninitialized sound sync packets (audioreactive)
audioSyncPacket contains four "invisible" padding bytes added by the compiler. These need to be initialized to zero, as future versions of the protocol will make use of these fields.
2023-10-08 19:54:14 +02:00
Frank
74d196ad50 npm run build
chores
2023-10-06 16:37:12 +02:00
Frank
3c4649748d Merge pull request #3420 from mountainash/fix/duplicate-viewport-declaration
Remove duplicate `viewport` declaration, put lang=en into the right place
2023-10-06 16:27:25 +02:00
Frank
22985900a8 Merge pull request #3425 from mountainash/fix/git-ignore
.gitignore Reordered & grouped
2023-10-06 16:26:04 +02:00
Daniel Kaufman
86300a8e3c code review suggestions to make the code more efficient and cleaner 2023-10-05 09:49:00 -05:00
Mountain/\Ash
32ab2ae201 Allow /wled00/html_*.h files 2023-10-05 11:55:48 +02:00
Mountain/\Ash
23e4a2e28e Reordered & grouped 2023-10-05 10:26:51 +02:00
Mountain/\Ash
40515e62ac Ignoring HTML build output 2023-10-05 10:21:24 +02:00
Daniel Kaufman
b56490650c fix for maxPWMValuePct being ignored 2023-10-05 00:37:51 -05:00
Mountain/\Ash
b5751795b5 Fix: lang moved to the correct HTML element 2023-10-04 21:42:15 +02:00
Mountain/\Ash
43d6151506 Fix: removing duplicate viewport declaration
- removed unneeded self-closing slash
2023-10-04 21:37:10 +02:00
Daniel Kaufman
8ccfb606c0 added the max fan pct to the PWM-Fan usermod. This allows high speed (loud fans) like delta fans to cap at a maximum percentage to keep noise down. 2023-10-03 12:42:51 -05:00
Blaz Kristan
3b74cd5676 Merge branch 'main' into 0_15 2023-10-02 21:20:20 +02:00
Frank
26e766ee19 Merge pull request #3406 from Aircoookie/sunset_accuracy_fix
fix for #3400 - wrong sunset time 00:00
2023-10-02 19:58:06 +02:00
Blaz Kristan
6f96dc8f23 Gamma correction for custom palettes (#3399).
Bugfix for audio palettes.
2023-10-01 21:15:14 +02:00
Frank
1c3fdb73fb optimization: only use "float" math functions
- saves 5KB flash and some RAM
-allow to build with -D WLED_USE_UNREAL_MATH, to restore old behaviour and save another 6KB flash
2023-10-01 19:04:30 +02:00
Blaz Kristan
332be7edd6 Build bump. 2023-10-01 13:38:10 +02:00
Blaz Kristan
76e0e935f0 Merge branch 'bugfix' into 0_15 2023-10-01 13:27:18 +02:00
Blaz Kristan
7e6eb65950 Fix for #3403 2023-10-01 13:26:31 +02:00
Blaz Kristan
b0a56a431b Fix for #3405 2023-10-01 13:04:05 +02:00
Frank
166316e0c5 fix for #3400
replace low_accuracy math functions (sint_t, cos_t, atan_t, ...) with standard libm functions that have higher accuracy.
2023-09-30 23:34:02 +02:00
Alerson Jorge
4194e66d81 Corrections
It was missing to upload this file in the commit.

- PXMagic is enabled by default in the Preset tab, and can be disabled in Settings, UI session
2023-09-28 12:41:52 -03:00
Alerson Jorge
c9b9d86892 Corrections
Topic 1, 2
I made the change, took it off the website and put it in the Preset section under the +Preset, +Playlist buttons, it was in a good location.

Topic 3, 4
It reloads because it needs the updated information so that it can create the preset correctly with all the information generated from the selected image.

Topic 5
The change has already been made, it just hasn't gone up yet, it's default upload

Topic 6, 7
Fixed
2023-09-28 09:41:48 -03:00
Alerson Jorge
f2d00e6e42 Merge remote-tracking branch 'upstream/main' into pxmagic 2023-09-28 09:10:47 -03:00
Alerson Jorge
acfc166a11 Corrections 2023-09-28 09:09:42 -03:00
Blaz Kristan
3255382132 Add JSON override for ESP-NOW remote. 2023-09-27 20:39:26 +02:00
Blaz Kristan
25831bfb60 Codename "Ray of light" 2023-09-26 20:34:52 +02:00
Blaz Kristan
d011ca0626 Merge branch 'main' into 0_15 2023-09-24 16:59:27 +02:00
Blaz Kristan
5eadbe7ecd FX update
- Meteor: trail & 0.13 behaviour
- Meteor Smooth: train & 0.13 behaviour
- Scrolling Text: rotation
2023-09-24 16:48:59 +02:00
Frank
ea7e0c6204 npm run build
regenerate UI files from latest sources.
2023-09-23 21:22:14 +02:00
Frank
2dcb126e6d version bump 0.14.0-b6
beta release preparation.
2023-09-23 21:08:11 +02:00
Frank
438525e8ec AR: use bandpass filter for analog input
Many bad quality analog mics are not centered properly at 1.6V, but stuck at 0V or stuck at 3.3V in silence. The bandpass filter removes DC offsets and improve signal quality.
2023-09-23 16:48:45 +02:00
Frank
eb66a403d9 Merge pull request #3377 from christianpatterson/audioreactive-initialize-i2ssource-bugfix
Fix ES8388Source & ES7243 initialization.
2023-09-19 16:32:10 +02:00
Frank
26ac612474 fix wrong signature of SPH0654::initialize()
* debug messages added to different initializers
* SPH0654::initialize() was having a wrong signature: uint8 instead of int8.

C++ can be a real bastard ;-)
2023-09-19 15:27:41 +02:00
Blaz Kristan
2e28df3e8a Merge 'main' to 0_15 2023-09-18 21:28:43 +02:00
Frank
43613e3b10 Matrix effect speedup
Typically, more than 50% of pixels are black. 
This optimization avoids to fade and rewrite already black pixels.
2023-09-18 15:56:50 +02:00
Frank
555dd2e726 matrix: fix for a corner case (e.g. gapmaps)
workaround for a corner case; if the reference pixels falls into a "gap" then gPC returns BLACK. Solutions is to reject BLACK.
2023-09-18 15:34:53 +02:00
Frank
3260f46543 bugfix for #3375
* improves robustness of the Matrix effect, by dynamically adjusting the "reference color" used to identify "falling code" head pixels.
* a bit faster, as I've removed the need to scan all pixels a second time for "black screen" detection.

Its still not perfect, and the main loop could be simplified a lot by leveraging on the fact that all changes actually happen in the top row, and "falling" is actually just moving everything down by one pixel.
2023-09-18 14:57:15 +02:00
Christian Patterson
f9de23402a Remove obsolete I2C parameters from AudioSource::initialize and all overriding methods. 2023-09-17 19:10:18 -05:00
Christian Patterson
9e155cf94a Fix ES8388Source & ES7243 initialization.
Update ES8388Source::initialize and ES7243::initialize method signatures to match I2SSource::initialize so that when initialize is called on a AudioSource pointer the child class's method is used.
2023-09-17 14:12:20 -05:00
Blaz Kristan
dcace43ce2 Merge branch 'main' into 0_15 2023-09-17 20:39:13 +02:00
Frank
527e3d6cd0 Merge pull request #3373 from Aircoookie/ripple-tweak
2D Ripple and Meteor effect tweak
2023-09-17 18:48:43 +02:00
Blaz Kristan
befce5b887 Typo fix and preset reload after restore 2023-09-16 20:29:32 +02:00
Blaz Kristan
9929c96650 Restore corrupt presets from backup 2023-09-16 14:41:47 +02:00
Blaz Kristan
c7d45c28cf Meteor effect change
- remedy for #3374
2023-09-16 12:30:57 +02:00
Blaz Kristan
87cc3fd714 2D Ripple effect tweak
for #3370
2023-09-16 00:21:10 +02:00
Frank
282d58a6fe audioreactive: stack size tuning
This gives ~3KB extra free heap on -S2.
2023-09-14 18:26:57 +02:00
Blaz Kristan
b4aec91d67 Bugfix 2023-09-12 23:44:18 +02:00
Blaz Kristan
d2a149ee23 Version 2023-09-12 17:07:31 +02:00
Blaz Kristan
8a72f94b3d Merge branch 'main' into 0_15 2023-09-12 17:02:40 +02:00
Blaz Kristan
fc4ed1c50b Fix for #3369 2023-09-12 16:48:32 +02:00
Blaz Kristan
ae1d0a18f3 Separate mode blending option 2023-09-12 06:17:06 +02:00
tetele
9709ca331e Backwards compatible default value 2023-09-11 16:25:36 +03:00
tetele
b4a9641c31 Add option for leading zero 2023-09-11 15:59:04 +03:00
Blaz Kristan
cc68e6b6e6 Squashed commit of the following:
Remove sync receive
Disallow 2D effects on non-2D segments
Optimisations
Sync clarification
AR palettes
Return of 2 audio simulations
Bugfix in sync #3344
    - remove excessive segments
    - ignore inactive segments if not syncing bounds
    - send UDP/WS on segment change
    - pop_back() when removing last segment
Add pairing support for ESP-NOW sync
Reduce string RAM footprint
UDP parse optimisation
Make WizMote work with sync.
ESP-NOW wireless sync POC.
    - caveat: devices have to be on the same channel
    - clashes with WizMote handling ATM
2023-09-10 18:52:14 +02:00
Frank
60c47cfca1 npm run build
regenerated UI files
2023-09-10 16:59:31 +02:00
Frank
720abd4e04 version bump 0.14.0-b5
preparations for releasing -beta5
2023-09-10 16:54:59 +02:00
Frank
b4fe694d1b esp32 buildenv with audioreactive
To make it better readable and prevent copy&paste errors, all needed flags can be referenced from the "esp32" buildenv:
  ${esp32.AR_build_flags}
  ${esp32.AR_lib_deps}
2023-09-10 16:30:04 +02:00
Frank
c117785554 8266 optional build flags to increase IRAM
related to #3364
2023-09-10 02:00:09 +02:00
Maximilian Mewes
a9d6a15924 Update Classes 2023-09-09 21:50:30 +02:00
Frank
e9723de6c3 minor updates for audioreactive
* remove "not supported" warning on -S2
* minor tweaking of beat detector
* optimized parameters for arduinoFFT
* fixed a few implicit "double" promotions
* minor UDP protocol optimizations
* small optimization for fft task create / suspend
* completely remove analogmic settings for -S3/-S2/-C3 where analog is not supported

changes were already tested extensively in the MM fork.
2023-09-09 21:07:20 +02:00
Maximilian Mewes
b8c61b5236 Move battery types to a separate folder 📁 2023-09-09 21:01:55 +02:00
Frank
da0cf01eee fixing a few implicit promotions to double
any expression with at least on "double" is evaluated as double, which is slow.
2023-09-09 20:48:17 +02:00
Maximilian Mewes
b77e1eb94b Merge remote-tracking branch 'origin/main' into usermod-battery-update2023 2023-09-08 23:17:23 +02:00
Blaz Kristan
e40f266042 Better bugfix in mode blending when _t is unallocated 2023-09-08 16:01:11 +02:00
Frank
69fb15d3cb debug message optimizations for 8266
as discussed in previous commit.
2023-09-08 14:06:57 +02:00
Frank
188956a4af bugfix for random crash when switching between presets
this is a band-aid fix for random crashes when switching between presets with multiple segments - crossfade disabled.

!! adding type initializers fixed it for me on -S3, however I still see (less frequent) crashes on esp32, due to heap corruption.

It took me hours to get a meaningful stackdump:

assert failed: heap_caps_free heap_caps.c:360 (heap != NULL && "free() target pointer is outside heap areas")

Backtrace: 0x40084ee1:0x3ffb2570 0x4008e341:0x3ffb2590 0x40094709:0x3ffb25b0 0x4008534a:0x3ffb26e0 0x40094739:0x3ffb2700 0x400e9037:0x3ffb2720 0x400e917c:0x3ffb2740 0x400eaeeb:0x3ffb2760 0x40117ec5:0x3ffb27c0 0x401184ea:0x3ffb2800 0x4013509d:0x3ffb2820

  #0  0x40084ee1:0x3ffb2570 in panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c:402
  #1  0x4008e341:0x3ffb2590 in esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:128
  #2  0x40094709:0x3ffb25b0 in __assert_func at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/assert.c:85
  #3  0x4008534a:0x3ffb26e0 in heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:360
      (inlined by) heap_caps_free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/heap/heap_caps.c:345
  #4  0x40094739:0x3ffb2700 in free at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/heap.c:39
  #5  0x400e9037:0x3ffb2720 in Segment::deallocateData() at wled00/FX_fcn.cpp:189
  #6  0x400e917c:0x3ffb2740 in Segment::resetIfRequired() at wled00/FX_fcn.cpp:206
      (inlined by) Segment::resetIfRequired() at wled00/FX_fcn.cpp:203
  #7  0x400eaeeb:0x3ffb2760 in WS2812FX::service() at wled00/FX_fcn.cpp:1216 (discriminator 2)
  #8  0x40117ec5:0x3ffb27c0 in WLED::loop() at wled00/wled.cpp:115 (discriminator 3)
  #9  0x401184ea:0x3ffb2800 in loop() at C:/src/wled00/wled00.ino:20
  #10 0x4013509d:0x3ffb2820 in loopTask(void*) at C:/Users/user/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:50

ELF file SHA256: 18c20b536f4c6ef4
2023-09-08 12:06:23 +02:00
Frank
c7dd4a7f2b potentiometer: check that pin supports ananlogread
newer esp32 frameworks will throw lots of warnings when trying to read from a non-analog pin.
2023-09-07 18:55:13 +02:00
Frank
111f1729c9 Update CHANGELOG.md
small correction
2023-09-07 17:51:28 +02:00
Blaz Kristan
164372b46a Update changelog 2023-09-07 16:32:59 +02:00
Frank
1af3794fed Merge pull request #1039 from pjhatch/PJH_ADD_Linearbounce
Pjh add linearbounce
2023-09-06 11:14:43 +02:00
Blaz Kristan
885f4ded0c Merge branch 'main' into PJH_ADD_Linearbounce 2023-09-05 21:20:55 +02:00
Frank
9bb018d8d9 bump to build 2309050 2023-09-05 19:15:22 +02:00
Frank
58187e00e6 optional ball trails (rolling balls) 2023-09-05 19:11:44 +02:00
Frank
5110a8c636 Squashed commit of the following:
commit 84148ad07a
Author: Blaz Kristan <blaz@kristan-sp.si>
Date:   Sun Sep 3 12:34:17 2023 +0200

    Implement palette colors

commit af3c8f66f7
Author: Blaz Kristan <blaz@kristan-sp.si>
Date:   Tue Aug 1 18:18:41 2023 +0200

    revert wled00.ino

commit 3097a1b17e
Author: Blaz Kristan <blaz@kristan-sp.si>
Date:   Tue Aug 1 18:13:37 2023 +0200

    minor aesthetic fixes

commit 54b80f74b2
Author: Blaz Kristan <blaz@kristan-sp.si>
Date:   Tue Aug 1 18:09:32 2023 +0200

    remove unused variable

commit 9a78d28cd7
Merge: 56a74bc5 1ed81793
Author: Blaz Kristan <blaz@kristan-sp.si>
Date:   Tue Aug 1 18:08:29 2023 +0200

    Merge branch 'main' into PJH_ADD_Linearbounce

commit 56a74bc54c
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sat Aug 15 12:34:13 2020 -0500

    Update FX.cpp

    Added the improvements suggested by Gregor Hartmann

commit a20358b61b
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sun Jul 12 08:33:48 2020 -0500

    Adding 2 ball track modes

    With and without collisions

commit 341d9d1697
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sun Jul 5 14:55:14 2020 -0500

    Update FX.cpp

    Still 1 bug to fix - this was a test.

commit 9cee424383
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sun Jul 5 14:53:14 2020 -0500

    Update FX.cpp

commit 37cb51cfd6
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Thu Jul 2 14:16:25 2020 -0500

    Adding Collision

    A couple of bugs still need sorting

commit 84b7bfb989
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sun Jun 28 19:59:46 2020 -0500

    update for lost balls

    Added some protection - so that when intensity is lowered and raised some time later balls that have moved way off the track are recovered.

commit 04d17e4839
Author: pjhatch <66844564+pjhatch@users.noreply.github.com>
Date:   Sun Jun 28 19:43:56 2020 -0500

    Added Ball Track V1

    In this version the balls bounce of the edges and do not interact with one another.
2023-09-05 18:39:51 +02:00
Frank
ddbe883d47 Merge branch 'fx-blending' 2023-09-05 18:37:55 +02:00
Frank
945ac82b6a fix small typo in MQTT override code
bracket was on wrong position, resulting in this warning:

wled00/set.cpp:357:79: warning: value computed is not used [-Wunused-value]
     strlcpy(mqttGroupTopic, request->arg(F("MG")).c_str(), MQTT_MAX_TOPIC_LEN)+1;
2023-09-05 17:15:12 +02:00
Blaz Kristan
84148ad07a Implement palette colors 2023-09-03 12:34:17 +02:00
Blaž Kristan
25553a28a1 Merge pull request #3351 from PSandro/pr_info_time
show current local time in info page ⏲️
2023-09-02 20:52:33 +02:00
Blaz Kristan
c2f5846a8e Add optional compile flag 2023-09-02 20:20:51 +02:00
Blaž Kristan
3f98e9451a Merge pull request #3348 from djasonic/staircase-toggle-pr 2023-09-02 18:52:16 +02:00
Blaž Kristan
6c72194346 Add compile time MQTT override (#3354)
- for max server name length
- for max topic length

Fix for #3353
2023-09-02 01:05:45 +02:00
Dimitry
822dd24756 Add Internal Temperature usermod (#3246)
* Add Internal Temperature usermod

* Fix line endings

* Update readme

* Format readme
2023-09-01 19:43:21 +02:00
Blaz Kristan
262ed38429 Fix for #3352 2023-08-31 19:10:22 +02:00
Sandro Pischinger
5ff66ce4dd recreate html_ui.h & html_simple.h 2023-08-30 20:58:32 +02:00
Sandro Pischinger
ca73b8e0b8 rename 'Current local time' -> 'Time' 2023-08-30 20:57:54 +02:00
Sandro Pischinger
2d49ace0e3 recreate html_ui.h & html_simple.h 2023-08-30 20:45:05 +02:00
Sandro Pischinger
d52f22044e Revert "recreate web ui files"
This reverts commit 2bf052aac9.
2023-08-30 20:43:22 +02:00
Sandro Pischinger
2bf052aac9 recreate web ui files 2023-08-29 23:52:32 +02:00
Sandro Pischinger
a79c9d5f4f info page: add time 2023-08-29 23:44:08 +02:00
Blaz Kristan
6f9bcf1858 Merge branch 'main' into fx-blending 2023-08-28 17:59:02 +02:00
Blaz Kristan
d1b00ba95d Bugfix.
- feed WDT even if strip is updating
- provide custom palette names
- handle interface cooldown properly
- rotary encoder ALT fix for custom palettes
2023-08-28 17:58:30 +02:00
Frank
bb45bee7f8 oappend() debug message when buffer is full
oappend() silently discards strings when the buffer is full, leading to strange effects like half-working UI pages.

The new debug message will help developers to understand what could be wrong.
2023-08-27 23:01:55 +02:00
Jason Cobb
246f0b21fd staircase toggle power on/off option bool 2023-08-26 22:19:52 -05:00
Blaz Kristan
394443b6d1 Merge branch 'main' into fx-blending 2023-08-25 18:34:56 +02:00
Blaz Kristan
fc1dd2daac Fix for #3346 2023-08-25 18:34:11 +02:00
Blaz Kristan
ba1b6f321e Button bugfix. 2023-08-23 14:50:46 +02:00
Blaz Kristan
06402cf1c6 Making buffer fix easy to maintain and portable.
Thanks to @softhack007
2023-08-17 17:10:29 +02:00
Blaz Kristan
dfc33389d8 Optimisation. 2023-08-17 16:46:31 +02:00
Blaz Kristan
4e83752655 Merge branch 'main' into fx-blending 2023-08-17 16:24:47 +02:00
Blaz Kristan
7e28718681 Too long metadata string bugfix. 2023-08-17 16:24:16 +02:00
Blaz Kristan
bf452e922a Playlist saving bugfix.
Fixes #3324
2023-08-16 22:11:16 +02:00
Blaz Kristan
4911a74cac Scrolling text enhancement.
- breaking change
- remove leading 0 checkmark
- add reverse scroll checkmark
- add vertical scroll if text fits into segment (intensity ==0 or ==255)
- rotated characters
- leading 0 check added to short texts (i.e. #DDMM0)
Fixes #3322
2023-08-16 21:02:00 +02:00
Blaž Kristan
a2bda5a4db Merge pull request #3317 from chroma-tech/group-masks-api
Add send and receive groups to json api
2023-08-14 13:01:16 +02:00
Shlomo Zippel
800abc605f Add send and receive groups to json api 2023-08-13 11:44:02 -07:00
Blaz Kristan
ac83b67632 Cleaner transition code.
Fixed skipped pixel flashing.
2023-08-12 12:45:11 +02:00
Blaz Kristan
00bc7dccb9 Merge branch 'main' into fx-blending 2023-08-12 11:36:40 +02:00
cschwinne
04aa9f0e61 Release of WLED beta 0.14.0-b4 2023-08-11 23:11:08 +02:00
Blaz Kristan
353e97a4c1 Clear status pixels 2023-08-11 00:48:32 +02:00
Blaz Kristan
7b28387bb4 Comments from Aircoookie addressed 2023-08-09 17:23:21 +02:00
Christian Schwinne
1889fe23c5 Merge branch 'main' into fx-blending 2023-08-09 16:58:21 +02:00
Blaz Kristan
9832fbe042 Segment reset 2023-08-08 20:40:19 +02:00
Blaz Kristan
084070475d Chasing memory corruption/leaks. 2023-08-07 16:50:18 +02:00
Blaz Kristan
cb42ca8765 FX optimisation 2023-08-06 19:11:44 +02:00
Frank
45d7e66488 effects bugfix: prevent crash when SEGLEN==1
* Blurz and a few other effects would crash (or behave unexpectedly) for single pixel segments
* replaced a few "MAX" by "max", because MAX will evaluate its arguments twice so its very inefficient.
2023-08-05 23:33:50 +02:00
Blaz Kristan
93a1616933 Blend tweaking. 2023-08-05 21:01:06 +02:00
Blaz Kristan
9a87a2ff0d Blending 2023-08-05 17:35:14 +02:00
Blaz Kristan
bdff05feaf Palette blending optimisation. 2023-08-05 13:53:12 +02:00
Blaz Kristan
937e3d0b94 FX blending POC 2023-08-05 13:50:08 +02:00
Blaz Kristan
8503aba583 Better random palette handling.
Remove unnecessary debug timing.
2023-08-03 22:28:53 +02:00
Blaz Kristan
bb8223d4ff Soap bugfix. 2023-08-02 22:01:15 +02:00
Blaz Kristan
af3c8f66f7 revert wled00.ino 2023-08-01 18:18:41 +02:00
Blaz Kristan
3097a1b17e minor aesthetic fixes 2023-08-01 18:13:37 +02:00
Blaz Kristan
54b80f74b2 remove unused variable 2023-08-01 18:09:32 +02:00
Blaz Kristan
9a78d28cd7 Merge branch 'main' into PJH_ADD_Linearbounce 2023-08-01 18:08:29 +02:00
Frank
5df197e814 disable ESP-NOW remotes in ethernet build (will crash without wifi) 2023-08-01 13:11:06 +02:00
Frank
5fe09e9787 esp-now remote: fix crash with AP = Always
initialize ESPNOW only when Wifi (STA or AP) is running
2023-08-01 11:53:32 +02:00
cschwinne
6be5360bdd Remove temp workaround 2023-08-01 00:48:18 +02:00
cschwinne
2b9007958b Merge branch 'main' into gif 2023-07-31 18:26:35 +02:00
Aircoookie
2f9c126d34 GIF Error codes 2023-07-31 18:13:03 +02:00
Frank
1ed817932b esp-now remote: reduce number of exported functions
too many global variables and functions ... this makes stuff 'static' that can remain at file scope
2023-07-30 21:47:18 +02:00
Aiden
0ccadb246f Add WireGuard VPN usermod (#3270)
* added wireguard VPN usermod

* add example PIO override & edit readme

* add contact information and improve usermod performance
2023-07-27 11:35:52 +02:00
dependabot[bot]
b67235a7e5 Bump certifi from 2022.12.7 to 2023.7.22 (#3301)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.12.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2022.12.07...2023.07.22)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-26 16:29:21 +02:00
Christian Schwinne
93853613bd Merge pull request #3280 from Aircoookie/alt-buffer
Bus-level global buffering
2023-07-25 17:01:49 +02:00
Frank
1ecb4fedcc 2D Drift: minor optimization
moving "t/20" out of the main loop gives some speedup.
2023-07-21 16:09:01 +02:00
Frank
c8fdf3731a upgrade to FastLED 3.6.0
changes from 3.50 to 3.6.0:
* bugfixes
* removed "register" keyword
* some speedups
* explicit bool() and uint32_t() operators, see https://github.com/FastLED/FastLED/issues/819

FX.cpp:  bugfix for "wled00/FX.cpp:4906:36:
error: cannot convert 'CRGB' to 'uint32_t' {aka 'unsigned int'} in initialization"
2023-07-20 22:36:47 +02:00
Frank
f8e766ffc0 add -S3 PSRAM (qio_opi) to nightly builds 2023-07-20 22:21:02 +02:00
Frank
050489dd80 allow Lolin Wifi Fix on -S3 2023-07-20 22:09:48 +02:00
Frank
2db966ba47 Improvements for -S3 with PSRAM
qio_opi:   PSRAM  8MB or 16MB
qio_qspi:  PSRAM  2MB or 4MB

fun fact: _opi and _qspi modes both require a special bootloader.
2023-07-20 22:09:14 +02:00
Frank
aa54d65f63 upgrade -S3/-S2/-C3 to platform 5.3.0
platform 5.3.0 = arduino-esp32 v2.0.6 + esp-idf v4.4.3

--> you will need new bootloader files for arduino-esp32 v2.0.6

--> coredumps are supported now, if you leave 64Kb of flash at the end of your partitions file (see example in wled_esp32_8MB.csv)
2023-07-20 21:39:25 +02:00
Alerson Jorge
37dc17ae15 Correction 2023-07-20 13:50:32 -03:00
Alerson Jorge
cd6b3d7dee Merge remote-tracking branch 'upstream/main' into pxmagic 2023-07-20 13:32:35 -03:00
Alerson Jorge
aec0bc5029 Updating pxmagic and WLED UI 2023-07-20 13:20:13 -03:00
Alerson Jorge
e010e67717 Revert "Updating pxmagic and inserting it in the WLED UI with option to enable and disable."
This reverts commit 44197d91c6.
2023-07-20 12:30:02 -03:00
Alerson Jorge
44197d91c6 Updating pxmagic and inserting it in the WLED UI with option to enable and disable. 2023-07-20 12:25:16 -03:00
cschwinne
e3ee48b52e Deallocate relay, button and IR pins prior to reallocation in JSON config parser (#3294) 2023-07-19 18:02:57 +02:00
cschwinne
8ccf349458 Always repaint NPB buffer on brightness change
Fix bus re-init causing full brightness (every show() now attempts to set the brightness, bus will ignore this if it stays the same)
2023-07-19 17:25:25 +02:00
cschwinne
2fce15db94 Restore brightness immediately after show() 2023-07-19 16:22:34 +02:00
Blaz Kristan
0cf50e8000 FX Fireworks optimisation 2023-07-19 16:06:41 +02:00
cschwinne
5b9630cf46 Repaint NPB buffer on brightness updates 2023-07-19 13:50:09 +02:00
Blaz Kristan
7dcbb409a9 Trying to solve ABL bug.
(no more pulsing)
2023-07-18 23:33:28 +02:00
Blaž Kristan
286e057fae Merge pull request #3216 from netmindz/AC-ES8388
ES8388 Support
2023-07-18 18:48:40 +02:00
Will Tatam
7d4fe341f1 Remove direct setup for I2C from ES8388 driver 2023-07-18 17:21:45 +01:00
Will Tatam
76acb7bb58 Merge branch 'main' into AC-ES8388 2023-07-18 16:36:42 +01:00
Frank
5ef7cd7bdd blur bugfix
turns out that fastLED 3.6.0 has an explicit uint32_t operator that returns RGBA, however  3.5.0 does not have this and the conversion returned only the "red" component".
2023-07-18 13:12:52 +02:00
Frank
ebb4628e66 Minor correction (slider names)
"Time delay" is actually "speed" - bigger values make the effect run faster.
2023-07-18 13:12:52 +02:00
Frank
0928060c75 blur bugfix
turns out that fastLED 3.6.0 has an explicit uint32_t operator that returns RGBA, however  3.5.0 does not have this and the conversion returned only the "red" component".
2023-07-18 11:29:08 +02:00
Frank
d8f9a9a03c Minor correction (slider names)
"Time delay" is actually "speed" - bigger values make the effect run faster.
2023-07-17 20:38:34 +02:00
Blaz Kristan
abfb8bbc34 Fix (almost good) for unbuffered ABL calculations. 2023-07-17 17:06:04 +02:00
Blaz Kristan
82e01f7b17 Fixed ABL calculation. 2023-07-17 16:15:17 +02:00
dependabot[bot]
a97609e920 Bump semver from 5.7.1 to 5.7.2 (#3289)
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-15 20:10:32 +02:00
Blaz Kristan
f1e1bd41b9 Slight optimisation in BusDigial::getPixelColor() 2023-07-14 15:58:03 +02:00
Blaz Kristan
57d35858d8 Merge branch 'main' into alt-buffer 2023-07-14 15:39:18 +02:00
Blaz Kristan
0b956c66c1 changelog update 2023-07-14 13:07:33 +02:00
Blaž Kristan
b1dfa1db61 Merge pull request #3291 from Aircoookie/onoff-nodes
Add ability to toggle devices from nodes view.
2023-07-14 12:41:15 +02:00
Blaz Kristan
cb579ecc62 Broadcast change. 2023-07-14 11:07:35 +02:00
cschwinne
ae235aa58c Fix UI handling of in-between inactive segments 2023-07-14 01:12:19 +02:00
Blaz Kristan
6302056182 Add ability to toggle devices from nodes view. 2023-07-13 22:21:15 +02:00
cschwinne
5e20abd7f1 Move segment bounds queuing to WS2812FX 2023-07-13 13:08:36 +02:00
Frank
72a72dbc88 proper rounding of FPS 2023-07-13 12:49:19 +02:00
cschwinne
4766666913 Static queued segment bounds
(saves 180 bytes of RAM)
Fixed segment index not increasing on inactive segments
2023-07-13 03:09:42 +02:00
Blaz Kristan
fa6070c680 Multiple updates:
- additional debug timings
- removed local leds[] buffer
- async segment bounds change (crashes seen otherwise)
- added isActive() check to Segment drawing methods
- ABL simplification
- palette option for Black hole (FX)
- (possible) crash mitigation is Segment handling (rapid preset changes)
2023-07-12 20:52:34 +02:00
cschwinne
6267d11e51 Fix compilation and ABL scaling 2023-07-09 12:32:28 +02:00
Christian Schwinne
822298ab66 Merge branch 'main' into alt-buffer 2023-07-09 11:31:02 +02:00
Blaz Kristan
2ad3ab7f0d Correct scaling for peek. 2023-07-06 22:48:13 +02:00
Blaz Kristan
f437fd6cd6 Code readability.
Fix for peek.
Loop timing.
2023-07-06 21:16:29 +02:00
Frank
42b247756a blur speedup
it seems that SEGMENT.blur() is the main bottleneck for many 2D effects.

This change optimizes performance of the function:
* avoid to re-write unchanged pixels
* early exit when blur_amount == 0 (=nothing to do)
* use _fast_ types where possible

I've seen up to 20% speedup with this change.
2023-07-06 19:51:37 +02:00
Frank
fbbf2d5eb3 2DPlasmaball - optimize out float 2023-07-06 19:07:09 +02:00
Frank
788a276616 fix power calculation for NeoPixelBusLg
power estimation results from estimateCurrentAndLimitBri() were too low (example: estimated 1.3Amp, measured 1.6Amp). This change corrects the power calculation. Due to the changed behavior of getPixelColor, powerSum must be used as-is, not scaled down again by brightness.
2023-07-06 19:06:31 +02:00
Frank
196779ffb6 XY: minor bugfix
properly handle width=0 OR height=0
2023-07-06 09:54:12 +02:00
Blaz Kristan
59a144baed Disable global buffer on ESP8266 by default
Remove global dependency from Bus class and subclasses
Remove timings
2023-07-05 23:57:46 +02:00
Blaz Kristan
ad825b80b0 Added a few debug timings. 2023-07-05 17:16:54 +02:00
Frank
45a0061660 reverting _restaurationBri change
see previous discussion
2023-07-05 14:26:09 +02:00
Frank
8831c76fb4 restoreColorLossy small optimization
minor optimizations that give up to 10% speedup in my tests
* use "fast" integer types (where possible)
* replaced _bri with _restaurationBri (no use of globals)
2023-07-04 16:22:19 +02:00
Blaz Kristan
66616e1cab Some timings added. 2023-07-03 21:13:01 +02:00
Frank
fa281a0df0 ABL optimization
this optimization avoids to apply brightness two times .

NeoPixelBusLg has already applied global brightness at sPC. Due to internal working of the Lg bus, its sufficient to only post-apply scaling, and set the new (scaled) brightness for the next frame.
2023-07-03 19:23:57 +02:00
Frank
d48a96599f prevent races on leds buffer (looptask vs. async_tcp)
I still see strange crashes in setPixelColor/GetpixelColor, which ssem to come from race conditions between async_tcp (change presets) and looptask (strip.service).
To make the situation better, its important that any global pointers are reset to NULL immediately after free().
2023-07-03 19:15:50 +02:00
Frank
7de7ef8e8c fix some crashes when changing presets
This fixes some of the crashes I had when changing presets.

still not a full solution ...
2023-07-03 17:00:43 +02:00
Frank
406a254523 inactive segments robustness improvement
* Avoid uint16 underflow in width() and height(): stop > start is possible, and means "inactive segment".

Without these checks, it was possible that width() and height() produce VERY large values due to underflow.
2023-07-03 15:43:47 +02:00
Frank
eabd6f60ef soudsim bugfix
FFT_MajorPeak was just going from 0..255.
Now it simulates the full range from 21hz ... 8Khz
2023-07-03 15:07:14 +02:00
Frank
e416d06aa9 Merge pull request #3274 from Aircoookie/ABL_hotfixPlus
some optimizations for ABL hotfix
2023-07-03 14:36:46 +02:00
Frank
65e073e6b8 de-optimization
first version still cased some flickering.
This de-optimization makes LEDs more stable.
2023-07-03 14:01:45 +02:00
Frank
45ac0d5dc6 fix for #3276
due to `if (strip.isUpdating()) return;` reading the encoder did not happen in time if the strip was active - with high number of LEDs, this means "always updating". Similar observation that we had with the audioreactive usermod, and similar solution.
2023-07-02 19:14:32 +02:00
Blaz Kristan
c9ef034ab8 Build bump/fix 2023-07-02 13:43:29 +02:00
Titanium177
c89f38f4f8 Edited Metadata for effect 5 & 8 to be availible on just 1 Pixel (PWM) (#3275) 2023-07-01 23:18:02 +02:00
Blaz Kristan
858b57d77a Return of local leds[] 2023-07-01 21:48:30 +02:00
Frank
9b87892036 optimization for ABL hotfix
* adding an optional parameter to setBrightness(). ApplyPostAdjustments() will only be called if `immediate=true`. Only ABL will use immediate=true, to ensure electrical safety of equipment.

This allows some optimizations of performance, as ApplyPostAdjustments() is time consuming.

* busses.setBrightness(bri) --> applied to all future pixels (fast, lossless)
* busses.setBrightness(bri, true) --> applied directly to all previously set pixels (slower, lossy)
2023-07-01 20:09:52 +02:00
cschwinne
ed69692f08 Dynamic 2023-07-01 15:36:41 +02:00
cschwinne
7119999df8 Gamma and speed control 2023-07-01 13:20:10 +02:00
cschwinne
c16462a0ce Experimental GIF support 2023-06-30 23:59:29 +02:00
Blaz Kristan
272f96b405 Double buffering at bus level. 2023-06-30 21:12:59 +02:00
Andre Lackmann
3e519001a3 Removed current cycle assignment that clears current value (#3262) 2023-06-30 15:03:32 +02:00
Blaz Kristan
f442aad962 Misc.
- larger stack buffer for oappend
- increase max segment name for ESP32
2023-06-27 16:01:20 +02:00
Christian Schwinne
fa9b151c36 Slightly more efficient buffer copy to busses 2023-06-27 01:57:05 +02:00
Christian Schwinne
481bd6f57a Add WiFi network scan RPC command to Improv Serial (#3271) 2023-06-27 01:51:44 +02:00
Blaž Kristan
f015227fc8 Missing WS connection fallback for liveview (#3267)
* Missing WS connection fallback for liveview
- fix for #3250

Remove (conditional WLED_ENABLE_LEGACY) legacy URI

Replace /sliders with /?sliders

* Merge liveview and liveviewws pages

Remove /url string subpage
Enable /json/live by default

* WS retry count
Removed appended ws from URL

* Also reset WS retries on successful WS connection

---------

Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
2023-06-27 01:51:24 +02:00
Christian Schwinne
61ba16b779 Global buffer and ABL fixes 2023-06-27 00:38:30 +02:00
Christian Schwinne
f6e86bfcf8 First global buffer iteration 2023-06-26 22:12:32 +02:00
Christian Schwinne
498dd76730 Decouple segment led buffer from global led buffer 2023-06-26 18:16:38 +02:00
Christian Schwinne
ebd909dfe7 Remove obsolete Visual Studio files 2023-06-26 00:17:34 +02:00
Blaz Kristan
067ed1258b Temporary bugfix for #3264 2023-06-24 21:04:46 +02:00
Blaz Kristan
ef3c72a24f Fix for #3265 2023-06-23 23:49:54 +02:00
Blaz Kristan
b257f476c9 Bugfix for #3259 2023-06-22 19:06:07 +02:00
Alerson Jorge
d3af2be79a Adding Pixel Magic Tool to WLED (#3249)
* Adding Pixel Magic Tool to WLED

* Revert "Adding Pixel Magic Tool to WLED"

This reverts commit b4f08fa8d5.

* Adding Pixel Magic Tool to WLED

* Corrections and performance improvements

* Remove IE compatibility tag

(saves a few bytes and IE10 is over 10 years old and unsupported)
Correct HTML language attribute
(Chrome would show a popup asking to translate from Portugese)

* Corrections and performance improvements

* Enable pxmagic by default

---------

Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
Co-authored-by: Christian Schwinne <cschwinne@gmail.com>
2023-06-22 11:26:24 +02:00
Christian Schwinne
94aeb19245 Enable pxmagic by default 2023-06-22 11:18:58 +02:00
Clayton Sims
e4ee392c27 Support for ESP-NOW Wireless Remote Control (#3237)
* Initial checkin for ESP-NOW remote feature

* cleanup irrelevant comment

* don't bring in espnow package includes when feature disabled

* Formatting and removing inaccurate call mode hardcoding

* Fork ESP Now code by platform (8266 v. esp32)

* compiled html update

* Disable ESP-NOW remote by default on ESP32 until tested

* Enable ESP-NOW remote for ESP32

* Rename ESP NOW define

---------

Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
2023-06-22 10:06:19 +02:00
Blaz Kristan
cf48ad06ed New SPI display SSD1309 for 4LD.
Fixed global I2C usage (no pin allocation in usermods).
Enabled option dor Multi relay.
2023-06-21 23:31:15 +02:00
Will Tatam
63df85f7f9 AC lacks i2sMaster param to I2SSource 2023-06-19 13:33:46 +01:00
Will Tatam
b29611509e AC lacks ERRORSR_PRINTLN 2023-06-19 13:33:16 +01:00
Will Tatam
dd1cf0ec56 AC lacks ERRORSR_PRINTF 2023-06-19 13:27:54 +01:00
cschwinne
c04c73bbd7 WS logic: No resending, improved ESP8266 stability
Update ESP8266 core to 3.1.2
2023-06-18 01:07:50 +02:00
Alerson Jorge
0d287283d4 Corrections and performance improvements 2023-06-16 20:21:59 -03:00
Blaz Kristan
4ea5723b7f Enhance pin dropdowns.
- add pins for PCF8574 (POC)
- bugfix for saving
Reduced maximum relays to 8.
Changed MultiRelay config parameter name.
2023-06-16 22:06:26 +02:00
Aircoookie
ea964124d6 Remove IE compatibility tag
(saves a few bytes and IE10 is over 10 years old and unsupported)
Correct HTML language attribute
(Chrome would show a popup asking to translate from Portugese)
2023-06-16 12:02:09 +02:00
Blaz Kristan
75244853c1 Fix for #3251 2023-06-16 10:24:56 +02:00
Alerson Jorge
c361c34b16 Corrections and performance improvements 2023-06-15 22:10:54 -03:00
Aircoookie
264b3a785b Code style: define constants for settings subpage IDs 2023-06-15 23:58:22 +02:00
Frank
bb15e1d8ac minor comment update
Small corrections in Lissajous comments
2023-06-15 09:30:44 +02:00
Alerson Jorge
68860ae866 Adding Pixel Magic Tool to WLED 2023-06-14 19:38:11 -03:00
Alerson Jorge
61637f12c7 Revert "Adding Pixel Magic Tool to WLED"
This reverts commit b4f08fa8d5.
2023-06-14 19:34:12 -03:00
Blaz Kristan
7538649e81 Add optional leading 0 on time and date for Scrolling Text
- replaces #2994
2023-06-14 21:58:32 +02:00
Blaz Kristan
31efbe915e Minor string optimisation. 2023-06-14 20:45:00 +02:00
Frank
9e69627626 2D Lissajous improvements
* allow user to control rotation speed (c3 slider)
* preserve accuracy by performing division _after_ multiplication: " (i * speed) / 32", instead of " i * (speed / 32)"
* proper rounding of "map" results, for better visual appearance
* avoid division by zero in map() function
2023-06-14 20:21:43 +02:00
Aircoookie
dd9da2853a Support settings pin unlock via JSON
Also supports locking by providing any incorrect pin
2023-06-14 11:53:39 +02:00
Alerson Jorge
b4f08fa8d5 Adding Pixel Magic Tool to WLED 2023-06-13 19:42:16 -03:00
Blaž Kristan
670461c66f Merge pull request #3238 from Aircoookie/beta-3
Beta 3
2023-06-13 21:38:10 +02:00
Blaz Kristan
f6092b9128 Build bump & updated changelog 2023-06-13 21:10:11 +02:00
Blaz Kristan
a690cb36ff changelog 2023-06-12 22:29:55 +02:00
Blaz Kristan
5ca8f4a3aa Merge branch 'pin-dropdown' into beta-3 2023-06-12 22:22:47 +02:00
Blaz Kristan
ba6e2f0a54 Pin dropdown updates for LED pins.
Updated pxmagic
2023-06-12 19:21:14 +02:00
Blaz Kristan
149f4e38a0 Merge branch 'main' into dev-2 2023-06-11 09:54:44 +02:00
Blaz Kristan
b5ee170726 Merge branch 'main' into beta-3 2023-06-11 09:53:39 +02:00
Blaž Kristan
04961880fe Merge pull request #3242 from jkoelker/mitigate_xss
fix(settings): mitigate xss
2023-06-11 09:52:19 +02:00
Blaz Kristan
e22e8ffa0e npm 2023-06-11 09:44:15 +02:00
Jason Kölker
d18d800947 fix(settings): mitigate xss
Mitigate XSS on wifi scanning from injecting arbitrary code by using
`textConent` instead of `innerHTML`.

Partially Fixes #3233
2023-06-10 23:40:02 +00:00
Blaz Kristan
3ca58ee65f Pin dropdowns POC.
NeoPixelBusGammaMethod POC.
PixelMagic POC.
Button reassign POC.
2023-06-10 20:43:27 +02:00
Blaz Kristan
21387b9a83 Bugfix download backup json 2023-06-08 09:41:38 +02:00
Blaz Kristan
ccb0d491ed Port bugfix. 2023-06-08 07:14:03 +02:00
Blaz Kristan
daa3200713 Sync page bugfix 2023-06-08 07:06:23 +02:00
Blaz Kristan
fec2d1f7ee Bugfix
- respect Settings PIN lock in /json/cfg
2023-06-07 21:43:32 +02:00
Blaz Kristan
eb8e95723c Bugfix reverse proxy path detection 2023-06-07 21:37:54 +02:00
Blaž Kristan
999bec19f1 Merge pull request #3232 from david-sawatzke/ws2801_eth_fix
Fix WS2801 output on boards with ethrnet
2023-06-06 21:18:17 +02:00
Blaz Kristan
dfb8de2349 Fix for #3204 2023-06-06 20:56:33 +02:00
David Sawatzke
59f1cdcc82 Fix WS2801 output on boards with ethrnet (similar to #2542)
and the corresponding fix d1fed11d0d
2023-06-06 16:34:22 +02:00
Blaz Kristan
3eb8be6239 Bump version and update changelog 2023-06-04 20:14:10 +02:00
Blaz Kristan
7dfc4a651d Merge branch 'main' into beta-3 2023-06-04 20:11:27 +02:00
Blaz Kristan
189d145393 Merge branch 'main' into beta-3 2023-06-04 18:43:28 +02:00
Blaz Kristan
26bec11d76 Reverse proxy support. 2023-06-04 18:40:29 +02:00
Blaz Kristan
1e7071bff3 Transition bugfix. 2023-06-04 18:36:46 +02:00
Blaz Kristan
92390d1d59 Bugfix in DDP handling. 2023-06-04 17:55:29 +02:00
Blaz Kristan
b9b072119b Add pin mode. 2023-06-03 22:46:17 +02:00
Blaz Kristan
b6d9fd8030 Usermod fixes
- 4LD: prevent corruption on fast Rotary changes
- Rotary: implement ISR for I2C reading
2023-06-03 17:01:29 +02:00
Aircoookie
d383bc93c7 Changelog update
Reduce width of ethernet mode dropdown
2023-06-02 10:51:37 +02:00
Sebastian
af88c68fca Buttons: Trigger on button press (instead of release) if all configured presets are the same (#3226)
* Buttons: Trigger when pressing if all configured presets are the same

* Add debounce for immediate rising-edge short press

---------

Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
2023-06-02 10:51:16 +02:00
Blaz Kristan
24537c4fdc Debug data for rotary. 2023-06-01 22:19:09 +02:00
Blaz Kristan
130f495fb6 Bugfix multi relay. 2023-06-01 22:17:41 +02:00
Sebastian
9d22a06969 Changes for allowing Alexa to change light color to White when auto-calculating from RGB (#3211)
* Changes for allowing Alexa to change light color to White when auto-calculating from RGB

* Update alexa.cpp

Indention

* Do not rely on global auto white override

(gets white mode from segment light capabilities)

* alexa.cpp: Removed unnecessary whitespaces

---------

Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
2023-05-31 20:12:17 +02:00
dvdavide
e3783e0236 Fix for displaying 1bpp bmp files (usermod EleksTube IPS) (#2988)
* Fix for displaying 1bpp bmp files

* EleksTubeIPS optimizations

* Fixed incorrect paletteSize

* stray tab

---------

Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
2023-05-31 20:11:30 +02:00
Justin Mutter
a5161eb7f1 Use constant for mDNS name to allow setting from my_config.h (#3145) 2023-05-31 17:35:43 +02:00
Blaz Kristan
82e448de7c Beta-3 changes
- remove I2C init  from usermods
- PCF8574 (&co) port expander support
- refactor PIR &  Rotary encoder & 4LD
- reboot race condition
- optimisations
2023-05-30 19:36:14 +02:00
Blaž Kristan
680afe972e Merge pull request #3220 from Aircoookie/feature
Feature implementation
2023-05-30 16:52:13 +02:00
Blaž Kristan
69ab2ce402 Merge branch 'main' into feature 2023-05-30 16:20:20 +02:00
Blaz Kristan
4374930065 npm build 2023-05-30 16:18:11 +02:00
Blaz Kristan
9f3520cba5 Update comments. 2023-05-30 16:09:51 +02:00
Blaz Kristan
d20cdc099d Merge branch 'main' into feature 2023-05-30 15:55:39 +02:00
Blaž Kristan
926e9ff3de Merge pull request #3171 from Aircoookie/seg-groups
Add support for segment sets (groups of segments)
2023-05-30 15:53:39 +02:00
Frank
70c277d8a1 bugfix: don't hide sound sim options for "double note" effects
There was is a typo in this line - apparently the "\u" was missing, so the search string was interpreted as octal char instead of unicode.
2023-05-30 13:23:26 +02:00
Blaz Kristan
0a5aac724a Merge branch 'main' into seg-groups 2023-05-29 21:35:52 +02:00
Christian Schwinne
bb91d5495f Merge branch 'main' into feature 2023-05-29 21:31:40 +02:00
Blaz Kristan
995d94c124 Repeat segment button fix 2023-05-29 21:23:11 +02:00
Aircoookie
ee7036f13d CSS tweaks
Fix repeat segment button remaining hidden
Fix third segment row (offset) alignment in 1D mode
Keep disabled sound simulation modes as comment for reference
New local var for 2D seg UI, improves code legibility
2023-05-29 21:06:10 +02:00
Blaz Kristan
5a8a8dc292 Feature implementation
- #2236
  - #1984
Better PSRAM handling
platformio.ini update
On/Off bus handling
2023-05-28 22:50:19 +02:00
coral
7d84de6690 Fix errors in DDP implementation (#3193)
* fix DDP spec

* Adjust DDP type byte to latest spec

Allow receiving of RGBW DDP with either old or new bits per channel value

---------

Co-authored-by: Aircoookie <21045690+Aircoookie@users.noreply.github.com>
2023-05-26 14:58:40 +02:00
dependabot[bot]
3520f9e9c2 Bump requests from 2.28.2 to 2.31.0 (#3213)
Bumps [requests](https://github.com/psf/requests) from 2.28.2 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.2...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-26 12:32:59 +02:00
Blaz Kristan
b2df7981a9 Add support for PCF8574 I2C port expander
- for Multi Relay usermod.
2023-05-24 23:40:23 +02:00
TroyHacks
9831e7bc3b Warnings about AudioKit rubbish 2023-05-23 23:49:57 +01:00
TroyHacks
90e37439e5 Better ES8388 init and mic support 2023-05-23 23:49:40 +01:00
TroyHacks
65f2490e89 It's offically the LyraT, not Lyra-T. 2023-05-23 23:49:29 +01:00
TroyHacks
c14a921e5a Mic settings for ES8388. Also ALC, pass-thru, etc. 2023-05-23 23:49:14 +01:00
TroyHacks
2bc8ffefce Some fixes for LyraT and also better inits/docs 2023-05-23 23:46:37 +01:00
TroyHacks
b88d8c85cb ES8388 init optimizations and fixes 2023-05-23 23:42:01 +01:00
Ewoud
693f52d984 Merge pull request #5 from netmindz/ES8388
WiP - ES8388
2023-05-23 23:41:46 +01:00
Blaz Kristan
56a3bff42e Multi-packet MQTT fix.
Solves #3205
2023-05-23 18:37:24 +02:00
Blaz Kristan
bffeec1615 Remove PSRAM use from global LED buffer. 2023-05-21 18:37:18 +02:00
Frank
e4a9f115cb fx functions: avoid memory corruption
* PSRAM_Allocator was missing the "reallocate" method, which lead to undefined behaviour when dynamic JSON doc needed to grow/shrink
* Segment::setUpLeds() quickfix for length() == 0 (should not happen, but it did happen for me once)
* leds in PSRAM causes major slowdown on wrover boards - disabled.
2023-05-21 14:33:25 +02:00
Frank
a717238f76 espalexa robustness improvements
* prevent string buffer overflows (stack corruption)
* avoid division by zero (program might crash)
* avoid log(0) which is undefined, too
* use faster math routines for float (logf, powf)
2023-05-21 13:21:38 +02:00
Blaz Kristan
4a567ab97c Merge branch 'main' into seg-groups 2023-05-15 17:06:38 +02:00
Blaz Kristan
90431b662b Rename "group" to "set" 2023-05-15 17:06:29 +02:00
Blaz Kristan
1c8f349a62 Bugfix.
- prevent LED flash on realtime end
2023-05-14 20:30:57 +02:00
Blaz Kristan
217004c70c Bugfix.
- disbled transitions/crossfade prevented segment off
2023-05-14 18:18:09 +02:00
Blaž Kristan
a75608628e Merge pull request #3199 from Aircoookie/serg-eth
Serg74 ethernet board.
2023-05-13 15:29:13 +02:00
Blaž Kristan
33130f39ee Merge pull request #3190 from Aircoookie/octopus
Octopus & Waving Cell 2D effects
2023-05-13 15:27:16 +02:00
Blaz Kristan
cae43e97cd Corner fix 2023-05-13 15:17:49 +02:00
Blaz Kristan
cdfc0f6b71 Temperature usermod rewrite 2023-05-11 17:33:09 +02:00
Blaz Kristan
bf6a18a414 Bugfix
- SHT enable/disable crash
2023-05-10 21:09:28 +02:00
Blaz Kristan
16b66afa7a Octopus offset 2023-05-10 21:06:48 +02:00
Frank
9e446210fb refresh build number 2023-05-09 17:57:17 +02:00
Frank
b0118d2d57 use size_t as file index type (might prevent corruption)
* use size_t instead of uint16_t -> prevents random behaviour (corruption) in case that JSON files get larger than 64Kbytes.
* use a constant for max large file space (was UINT16_MAX)
* reduced the scope of some functions and variables to "static" - avoids name clashes and may support better optimization by the compiler
2023-05-09 17:44:26 +02:00
Frank
bc90309dd6 fix error message in latest platformio
fix for "Error: Invalid environment name 'codm-controller-0.6-rev2'. The name can contain alphanumeric, underscore, and hyphen characters (a-z, 0-9, -, _)"
2023-05-09 17:34:30 +02:00
Frank
52c4093fb0 minor bugfix for usermod_v2_Battery.h
missing semicolon - caused compile errorsin debug mode.
2023-05-08 20:59:57 +02:00
Blaz Kristan
b47c12cbee Serg74 ethernet board. 2023-05-08 08:48:52 +02:00
Blaž Kristan
fb14bc6016 Merge pull request #3116 from Erwin-Repolust/main
Changing voltage calculation to a weighted running average
2023-05-07 10:20:26 +02:00
Blaz Kristan
cd6862b1a7 Merge branch 'main' into octopus 2023-05-06 12:56:35 +02:00
Blaz Kristan
3d9160f2fa Merge branch 'main' into seg-groups 2023-05-05 23:01:17 +02:00
Blaž Kristan
157a5d9902 Merge pull request #3164 from werkstrom/cpal
Custom Palette Editor
2023-05-05 22:44:52 +02:00
Blaz Kristan
f4972e2be2 Code size reduction.
Save in hex notation.
2023-05-05 22:37:47 +02:00
Blaz Kristan
85c8e6ba42 Merge branch 'main' into cpal 2023-05-05 21:35:18 +02:00
Blaž Kristan
8e79bd8785 Merge pull request #3162 from wled-install/main
Add LAN8720 reset and new ethernet board
2023-05-05 21:32:06 +02:00
Frank
1ace7ce254 Merge pull request #3194 from billythekid/patch-1
Update palettes.h (typo in a comment)
2023-05-05 20:08:09 +02:00
Blaz Kristan
a00be5b60c Improved Tartan FX 2023-05-03 21:43:21 +02:00
Billy
aabe8d1d5e Update palettes.h
just a typo-fix
2023-05-02 21:52:39 +01:00
Blaz Kristan
3da086438b Add rotating to Octopus
Soap optimization
2023-05-02 11:16:24 +02:00
Blaz Kristan
c257c86387 Fix for mirroring 2023-05-01 20:43:03 +02:00
Blaz Kristan
ff3ae14c29 Merge branch 'main' into octopus 2023-05-01 19:23:12 +02:00
Frank
cd82a34392 fixing github CI builds for -S3/-S2/-C3
explicitly adding `toolchain-riscv32-esp @ 8.4.0+2021r2-patch5` seems to do the trick.

Suggested here:
* https://github.com/platformio/platform-espressif32/issues/1081#issuecomment-1518601054
2023-05-01 16:54:30 +02:00
Blaz Kristan
baacd55910 Minor UI fix 2023-05-01 14:17:52 +02:00
Blaž Kristan
511b7c4d92 Merge pull request #3142 from xxv/xxv/dancing-shadows-default-color
Set Dancing Shadows default palette to Party
2023-04-30 18:43:04 +02:00
Blaz Kristan
f38851b7c6 Merge branch 'main' into cpal 2023-04-30 17:52:28 +02:00
Blaz Kristan
432c5837f0 Bugfix
- WiFi power for Lolin S2 & C3 (use -DLOLIN_WIFI_FIX)
- web response buffer size (corruption when websockets not used)
2023-04-30 17:30:36 +02:00
Blaz Kristan
cc599f544a Tweak in Soap. 2023-04-30 13:28:04 +02:00
Blaz Kristan
e886c85134 Tweaks. 2023-04-30 13:25:08 +02:00
Blaz Kristan
05eb716b85 Noise array bugfix.
Fire2012 tweak.
2023-04-30 13:22:42 +02:00
Blaz Kristan
61eb7b0a6a Waving Cell FX 2023-04-29 17:04:16 +02:00
Blaz Kristan
f0dade5856 Uneven matrix fix. 2023-04-29 15:51:25 +02:00
Henrik
8567f6b13c Ability to use static palettes as templates 2023-04-29 13:28:45 +02:00
Blaz Kristan
b740316918 Soap fix 2023-04-29 11:11:03 +02:00
Blaz Kristan
2119d08543 Octopus 2D effect
- by Stepko
2023-04-28 22:00:35 +02:00
wled-install
599ff66522 Add files via upload 2023-04-28 17:15:31 +02:00
wled-install
6d2eb04ada Add files via upload 2023-04-28 17:13:50 +02:00
Blaz Kristan
0aea75edb7 NeoPixelBus 2.7.5
UI bugfix
2023-04-28 16:52:48 +02:00
Mattstir
2ca8231ab4 Improve indent (#3118)
* Improve indent

Improve indent, so its more allignend and correctly indented according to logic groups

* Spaces to tabs

---------

Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
2023-04-28 01:40:51 +02:00
Blaž Kristan
e00116551c Add Ucs890x support and swaps NeoPixelBrightnessBus with NeoPixelBusLg (#3091)
* Add UCS890x support.

* Fixes

* Update NeoPixelBus to 2.7.3 for UCS8904 support.
Update ESP8266 core to 4.1.0

* ESP8266 compile fixes.
- use PlatformIO framework and toolchain
- add compiler warning suppression
- remove IRAM_ATTR to fit in IRAM

* Replace NeoPixelBrightnessBus with NeoPixelBusLg
Resolves #3087

* Update to NPB 2.7.4

* Internal NPB color conversions.

* Fix errors due to merge with SPI Hz methods

Regenerate settings page HTML

---------

Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
2023-04-28 01:28:57 +02:00
cschwinne
4d55e05b07 Fix CI properly
Small 2D Soap FX optimizations
2023-04-28 00:51:34 +02:00
Blaž Kristan
9ff3f85432 Allow SPI clock speed selection. (#3173)
* Allow SPI clock speed selection.

* Bump NPB to 2.7.4
2023-04-28 00:27:19 +02:00
Blaz Kristan
65c584aeda 2D enhancement (internal)
- move() wrapping
- dual addPixelColorXY()
2023-04-27 17:31:55 +02:00
Blaž Kristan
2540a2dfd9 Soap, new 2D effect (#3184)
* Soap, new 2D effect

* Fix Soap FX on matrices with edges < 8 LEDs

* Add palette support to Soap FX

---------

Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
2023-04-27 01:22:33 +02:00
Blaz Kristan
70e9187bcb Merge branch 'main' into seg-groups 2023-04-26 19:50:22 +02:00
Blaz Kristan
5e2fa13471 Bugfix.
- allow saving of reboot preset
- return Spread slider
2023-04-26 19:47:12 +02:00
Blaž Kristan
4f8610f895 Merge pull request #3134 from strikeout/DMX_MODE_PRESET_FIX
Fixes DMX_MODE_PRESET preset and brightness selection via DMX controller
2023-04-26 19:30:14 +02:00
Blaz Kristan
95f9e97af8 typeOf bugfix 2023-04-26 14:45:39 +02:00
Marcos Castro
695b073080 Apply correct iOS scroll to all tabcontent (#3182) 2023-04-26 10:53:49 +02:00
Stefan Riese
3a28935bfe Wordclock - Issue with "Norddeutsch" (#3161)
* - fix word clock for "viertel vor" and "viertel nach"
- adjust wording of parameters

* - revert changes for parameter names

* enclose JSON property strings in F() macro to reduce RAM usage.

* add parameter info for "norddeutsch" and "LedOffset"
2023-04-26 10:53:18 +02:00
Christian Schwinne
468ed1a9ce Restore Github actions CI build (#3187)
* Update dependencies

* Do not fail fast

* Disable ESP32 variant CI builds
2023-04-26 10:52:54 +02:00
Blaz Kristan
a6052d7900 Update info text. 2023-04-25 14:27:33 +02:00
Blaz Kristan
e42836b07f Allow hex strings for palette 2023-04-25 13:02:09 +02:00
Henrik
16373919d4 Removed as requested 2023-04-23 21:36:19 +02:00
Henrik
92f9c908f6 Custom palettes now editable 2023-04-23 21:32:52 +02:00
Henrik
480e1e17c8 Error on missing css file 2023-04-23 11:40:07 +02:00
Blaz Kristan
274f5f2f1f Bugfix. 2023-04-22 16:06:13 +02:00
Blaz Kristan
02d4f9cbba Merge branch 'main' into seg-groups 2023-04-20 17:21:20 +02:00
Blaz Kristan
d10daf0991 Bugfix
- skip regular button handling while waiting for analog read
2023-04-17 16:25:05 +02:00
Blaz Kristan
8c9656b799 Cleanup. Return after upload. 2023-04-14 18:33:03 +02:00
Blaz Kristan
396ea3d0ee Add webserver cpal support 2023-04-14 17:21:07 +02:00
Blaz Kristan
3efee4a855 Merge branch 'main' into cpal 2023-04-14 17:16:20 +02:00
Blaz Kristan
ece6759fa7 UI update. 2023-04-14 17:15:02 +02:00
Frank
246d945f39 another "inner var shadows outer var"
Seems this is not causing bugs, however its still bad style to re-define existing vars in an inner loop. Solved to improve code readability.
2023-04-14 14:13:45 +02:00
Frank
4a3bc486d0 two more "shadowed locals"
In these case, there seem to be no bug, but  simply renaming the "inner" variables improves code readability.
2023-04-14 13:09:25 +02:00
Frank
996d041581 bugfix for art-net transmit
art-net transmit was not sending out LEDs, but only transmitted headers repeatedly (thanks @troyhacks for noticing).

Actually such problems can be found by newer compilers, so i've added the warning option to [esp32_idf_V4].

wled00/udp.cpp: In function 'uint8_t realtimeBroadcast(uint8_t, IPAddress, uint16_t, uint8_t*, uint8_t, bool)':
wled00/udp.cpp:824:40: warning: declaration of 'byte buffer [12]' shadows a parameter [-Wshadow=compatible-local]
         byte buffer[ART_NET_HEADER_SIZE];
                                        ^
wled00/udp.cpp:720:85: note: shadowed declaration is here
 uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8_t *buffer, uint8_t bri, bool isRGBW)  {
2023-04-14 11:39:12 +02:00
Frank
d48e4adcd4 CI build fix
seems that NPB 2.7.4 introduces new incompatibilities that break our gh build action.
2023-04-13 12:16:32 +02:00
Blaz Kristan
7f84b7ab83 Merge branch 'main' into seg-groups 2023-04-12 15:37:56 +02:00
Blaz Kristan
3e26bd6a17 Quick compile fix.
- ESP32 DMA HSPI method in NeoPixelBus requires IDF 4.4.1
2023-04-12 15:35:27 +02:00
Henrik
e964c62907 Fixes 2023-04-12 09:15:38 +02:00
Blaz Kristan
fbb4965263 Merge branch 'main' into seg-groups 2023-04-11 21:40:29 +02:00
Blaz Kristan
88139d95a7 Build bump. 2023-04-11 21:35:44 +02:00
Blaz Kristan
5875b1988b Change log update 2023-04-11 21:34:43 +02:00
Blaž Kristan
2a2091595b Merge pull request #3153 from Aircoookie/ipad-pcmode
iPad/tablet with 1024 pixel UI PC mode.
2023-04-11 21:11:19 +02:00
Blaz Kristan
d77883dd7a Merge branch 'main' into ipad-pcmode 2023-04-11 21:03:09 +02:00
Blaz Kristan
adea7dadec Bugfix.
- top buttons not working on mobile
2023-04-09 23:58:24 +02:00
Blaz Kristan
cf4ce2dc08 Revert float none. 2023-04-09 23:55:53 +02:00
Henrik
e74dfb2ba6 Small adjustments to UI mainly 2023-04-09 16:49:41 +02:00
Henrik
aaea9ff018 Added info on usage of IDs 2023-04-09 14:18:22 +02:00
Blaz Kristan
206b88eba2 Bugfix.
- top buttons not working on mobile
2023-04-09 11:06:42 +02:00
Henrik
8f5373f034 Custom Palette Creator 2023-04-08 20:02:49 +02:00
Blaz Kristan
dfa0a16487 Reduce sound sim options to increase 2D mapping. 2023-04-04 17:16:50 +02:00
Blaz Kristan
8b9f6f49ef Minor CSS tweaks 2023-04-04 15:53:03 +02:00
Blaz Kristan
bcac978810 Merge branch 'main' into seg-groups 2023-04-02 18:17:47 +02:00
Blaž Kristan
d17a41f7f1 Merge pull request #3155 from werkstrom/patch-1
Adjustments to Pixel Art Converter
2023-04-02 18:13:22 +02:00
Blaz Kristan
503f71f004 Npm run build 2023-04-02 18:07:48 +02:00
Blaz Kristan
4543288ea7 Merge branch 'ipad-pcmode' into seg-groups 2023-04-02 18:05:59 +02:00
Henrik
9307105b3f Redone in Patch-1 2023-04-02 13:52:20 +02:00
Henrik
567daf9946 Merge branch 'Aircoookie:main' into patch-1 2023-04-02 13:35:31 +02:00
Blaz Kristan
558b22c36a POC: Implemented segment groups (4).
Sacrificed 1 bit on sound simulation and 1D to 2D mapping each.
2023-04-01 23:40:43 +02:00
Blaz Kristan
f076dddfe3 Filter updates. 2023-04-01 11:02:49 +02:00
Frank
af44730418 platformio.ini minor cleanups
- fixed a few typos, trailing spaces and bad alignments
- added the previous 8266 platform packages as a comment, just in case
- [env:esp32dev_V4_qio80] is actually "dio" --> renamed to [env:esp32dev_V4_dio80]
- all esp32dev targets use the same ${esp32.platform} now (3.2.0 would not compile any more)
2023-03-31 15:44:21 +02:00
Blaz Kristan
4ec1140cb4 Optimizations & bugfix. 2023-03-31 13:26:03 +02:00
Blaz Kristan
2a5d20058f iPad/tablet with 1024 pixel UI PC mode.
Optimizations.
2023-03-30 21:35:23 +02:00
Frank
51f38e0a76 Merge pull request #3144 from Aircoookie/esp8266-core
ESP8266 core 4.1.0, ESP32 core 5.2.0 (S2,S3,C3)
2023-03-30 00:24:43 +02:00
Frank
54eb42d658 build env for -C3 with only 2MB flash
based on proposal from  in PR #2951 by @andyshinn.
2MB does not allow to have an OTA partition, so this feature is disabled.
2023-03-30 00:20:01 +02:00
Frank
a7a6f4cec6 small re-organization of build flags
* -Wno-attributes added to common flags
* USB_MSC and USB_DFU flags moved to common board sections (does not make sense with WLED to ernable these)
2023-03-30 00:03:04 +02:00
Christian Schwinne
3968a8e0dc Attempt fixing GitHub actions ESP8266 build (#3151)
(explicit toolchain version)
2023-03-28 23:19:00 +02:00
Blaz Kristan
9e8ff27a7f Change log update 2023-03-27 15:49:02 +02:00
Blaz Kristan
7dd3d2b040 Merge branch 'main' into esp8266-core 2023-03-26 10:20:09 +02:00
Blaz Kristan
13678cb8d5 Add adjustable Random Cycle time.
- solves #3147
2023-03-25 21:28:30 +01:00
Frank
890aa6f9ac experimental esp32 buildenv with platform = espressif32@5.2.0
experimental ESP32 buildenv using ESP-IDF V4.4.x / arduino-esp32 v2.0.5
Warning: this build environment is not stable!!
2023-03-22 00:46:27 +01:00
Frank
646cf44b83 moved register override into 8266 section,
so it cannot destroy builds for ESP32 devices
2023-03-22 00:06:25 +01:00
Frank
bf789ca97b minor cleanup 2023-03-21 23:36:50 +01:00
Frank
9b90ff10f4 buildenv improvements for -S3/-S2/-C3
- corrected some broken references
- added `platform_package =` --> use default packages
- renamed env:esp32c3 to env:esp32c3dev to avoid confusion
- added lolin_s2_mini to CI builds
2023-03-21 23:15:08 +01:00
Blaz Kristan
0cc719a823 Remove "register" override 2023-03-21 20:01:16 +01:00
Blaz Kristan
4cd026dfe9 ESP8266 core 4.1.0, ESP32 core 5.2.0 (S2,S3,C3)
NeoPixelBus 2.7.3 (adding UCS890x support)
2023-03-21 17:28:04 +01:00
Aiden
3120b49dba Add some Athom devices (#3114)
Add some compile configurations for Athom's devices
2023-03-20 23:44:12 +01:00
Christian Schwinne
fb1999c474 Merge pull request #3107 from Aircoookie/onepx-segment
Tweaks & bugfixes.
2023-03-20 23:42:30 +01:00
Steve Pomeroy
2c37961f7b Set Dancing Shadows default palette to Party 2023-03-19 17:37:29 -04:00
Frank
1abc863f82 comment updated
Also "Serial JSON" is not possible when reading from RX pin is disabled.
2023-03-19 15:51:39 +01:00
Frank
c9be03c0bc typo 2023-03-19 14:48:47 +01:00
Frank
fd89209233 adding WLED_DISABLE_ADALIGHT (issue #3128
This flag disables reading commands from serial interface (RX = gpio 3)

Add -D WLED_DISABLE_ADALIGHT to your custom pio build environment.
2023-03-19 14:42:01 +01:00
Blaz Kristan
2e362fbb64 Fix for #3074 2023-03-19 14:26:54 +01:00
Blaz Kristan
11b687cdc2 Float vs. double. 2023-03-19 11:24:59 +01:00
Blaz Kristan
747c920420 Bugfix.
- white overrides & CCT
2023-03-19 11:23:59 +01:00
Blaž Kristan
cac51737cb Merge pull request #3138 from codekane/mpu6050_imu 2023-03-19 07:38:44 +01:00
Ryan Horricks
7789379914 Fix typing to resolve build errors after installing the mpu6050_imu usermod. 2023-03-18 18:29:19 -06:00
Blaz Kristan
08e2bfe9a2 Scale 2D peek for large matrices. 2023-03-18 18:22:31 +01:00
strikeout
56a854ec88 limit max. selectable preset ID to 250, according to WLED capabilities 2023-03-17 13:40:21 +01:00
strikeout
de4ff4e58d Fixes preset and brightness selection via DMX controller to DoS WLED, now same packets are discarded 2023-03-16 17:56:29 +01:00
Frank
991c2afedb adding wled00.ino.cpp to gitignore
to avoid future accidents in GH Desktop
2023-03-16 13:10:33 +01:00
Frank
cded92662f workaround for issue #3128 2023-03-16 13:08:34 +01:00
Erwin Repolust
2c3fa0fd8f added function for voltage reads 2023-03-16 01:33:57 +01:00
Erwin Repolust
ec08432f92 added voltage multiplier to gui and set defaults 2023-03-14 01:44:41 +01:00
Blaz Kristan
1bab4d6937 Merge branch 'main' into onepx-segment 2023-03-12 13:14:22 +01:00
Blaz Kristan
d1fed11d0d Fix for #2542.
UI rebuild.
2023-03-12 13:10:40 +01:00
Blaž Kristan
e96053e268 Merge pull request #3121 from troyhacks/2023-03-10-Art-Net_Transmit
Art-Net transmit support for network LEDs
2023-03-11 22:50:07 +01:00
Blaž Kristan
9b98cbb894 PROGMEM for header 2023-03-11 22:35:22 +01:00
Blaž Kristan
349578fb6e whitespace cleanup 2023-03-11 22:33:06 +01:00
Blaz Kristan
7c186e4fcc Fix for smaller number of pixeld than matrix size. 2023-03-11 15:03:28 +01:00
TroyHacks
a4fcbb9f67 Art-Net transmit support for network LEDs
Like DDP, this allows WLED to address network systems using the Art-Net protocol.

Universe starts at zero, because that's the first universe in Art-Net.

Works with RGB. It's coded to also work with RGBW, but I couldn't find a great place to enable it without mucking with things I don't understand.
2023-03-10 13:29:00 -05:00
Blaz Kristan
763b64cc57 Combat low memory condition on ESP8266. 2023-03-10 15:20:50 +01:00
Blaž Kristan
d57e6c5bf2 Merge pull request #3106 from lost-hope/klipper
Usermod: Klipper percentage
2023-03-10 14:14:31 +01:00
Blaz Kristan
80711cc00a Whitespace. 2023-03-10 14:08:52 +01:00
Erwin Repolust
8b61b9ebfe Added code for esp8266 2023-03-10 01:28:04 +01:00
Erwin Repolust
e00e778bce Less operations and better readable 2023-03-08 03:54:48 +01:00
Erwin Repolust
81e70925c4 Changed to running average to improve accuracy 2023-03-08 03:24:16 +01:00
Blaz Kristan
ddd32bd600 Multiple fixes.
- compiler warning fixes (gcc17)
- revert min heap size to 8k
- fix form submitting in 2D settings
- remove IRAM_ATTR for ESP8266 core 4.1.0
2023-03-05 22:56:14 +01:00
Frank
2713573b9b Delete wled00.ino.cpp
accident
2023-03-05 22:38:36 +01:00
Frank
cf2e8bbc0b update build nr
and npm run build
2023-03-05 22:35:59 +01:00
Frank
bc56c1a0e1 bugfixes
* xml.cpp: correct type for checkbox global led buffer" (was not shown correctly)
* fx.cpp: 2D floating blobs - correct swapped x/y coordinates (did not render correctly on non-square matrix)
2023-03-05 22:30:08 +01:00
Blaz Kristan
bfbf7af411 Revert palette conditional load.
Playlist load bugfix.
2023-03-03 19:57:09 +01:00
Blaz Kristan
c151221d12 UI fixes & revert forcing ULTRAWHITE for on/off bus
Reduce min heap for 8266
2023-03-02 18:21:55 +01:00
Blaz Kristan
b8489724ef Slider BG fix. 2023-02-28 23:04:12 +01:00
Blaz Kristan
7a2f556682 Bugfix for 1 pixel segment capabilities. 2023-02-28 19:08:41 +01:00
Blaz Kristan
92d883db87 Bugfix for 1D setup.
- incorrcet max segment length calc
2023-02-28 15:25:11 +01:00
lost-hope
cb931d7af0 Merge branch 'main' of https://github.com/Aircoookie/WLED into klipper 2023-02-27 21:21:45 +01:00
Soeren Willrodt
6b54b57cb9 fixing the PR conflict 2023-02-27 21:01:32 +01:00
Blaz Kristan
1ca4348ca0 Add Segment functions hasRGB() and hasWhite()
Makes code cleaner.
2023-02-25 17:58:51 +01:00
Blaz Kristan
3ca7006e3a Tweaks & bugfixes.
One pixel segment handling.
- added 0D FX metadata (1 pixel effects)
- ignore palettes for White only segment
- ignore color for non-RGB & non-White segment (on/off)

Bugfix
- proper auto segment creation
- hide palettes for non RGB segments
- some tweaks for #2984
- force Solid for some FX (causing crash) on 1 pixel segment

UI Optimisations
- slider tooltips
- tiny bit smaller tooltips
- hide segment power if only one segment
- gap between sliders
2023-02-25 09:41:15 +01:00
lost-hope
339d2a7bf3 Added spreading from center and fixed the enable 2023-02-23 19:47:27 +01:00
mx
0d3debf9b9 sACN/E1.31 Port Priority (#3052)
* Added E1.31 port priority handling #768

* Ignore E1.31 data when priority doesn't match #768

* Enable E1.31 priority handling for WLED_ENABLE_DMX

* Only handle e131Priority for P_E131 protocol

* Corrected comments

* Highest priority package first handling

* Removed obsolete code & comments

* Improved comments

* Reduce priority timeout to be uint8_t

* Optimized code & comments

* E1.31: Ignore non-zero start code and preview data
These are not level data, they have other purposes

* Style change cca41508 preview & ignore non-zero start code

---------

Co-authored-by: RichardTea <31507749+RichardTea@users.noreply.github.com>
2023-02-21 17:13:15 +01:00
underritoSR
7f74a4f4b5 removing DLS for CST_TimeZone_GMT-6 (#3082)
* removing DLS for CST_TimeZone_GMT-6

* Adjust Mexico timezone name

---------

Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
2023-02-21 17:09:04 +01:00
Christian Schwinne
220718cb58 Remove Blynk support (#3102)
Change default palette for Railway to Colors 1 and 2
2023-02-21 17:07:32 +01:00
dependabot[bot]
be2acbd3eb Bump cacheable-request and nodemon (#3089)
Removes [cacheable-request](https://github.com/jaredwray/cacheable-request). It's no longer used after updating ancestor dependency [nodemon](https://github.com/remy/nodemon). These dependencies need to be updated together.


Removes `cacheable-request`

Updates `nodemon` from 2.0.4 to 2.0.20
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.4...v2.0.20)

---
updated-dependencies:
- dependency-name: cacheable-request
  dependency-type: indirect
- dependency-name: nodemon
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-21 16:48:00 +01:00
Christian Schwinne
9249c74b7b Merge pull request #3088 from Aircoookie/led-gaps
LED matrix gaps
2023-02-21 16:46:58 +01:00
lost-hope
2b87817ba2 enabled IP Change and updated the Readme 2023-02-19 09:08:40 +01:00
Blaz Kristan
883c0f9dfe Bugfix
- gamma value not showing
2023-02-17 20:36:35 +01:00
Blaz Kristan
3ffc58d442 Bugfix
- segment capabilities on 2D segments and ledmaps
- UI segment update
- auto segment creation 2D + 1D
2023-02-15 20:36:54 +01:00
Blaz Kristan
1bb4b0156f Bugfix 2023-02-14 20:25:26 +01:00
Blaz Kristan
92d2be3f5e Add ledmap names
Bugfix
- reset segments upon 2D ledmap allocation error
- fix invlid 2D segments
2023-02-14 17:11:58 +01:00
Blaž Kristan
a7cded21f7 Merge branch 'main' into led-gaps 2023-02-14 14:28:10 +01:00
Christian Schwinne
74156b7ed8 Support white addressable LED strips (#3073)
* Support white addressable LED strips

* Various white handling tweaks

Allow RGB controls for white-only busses depending on AWM (makes palette-only FX work on non-RGB addressable busses)
Fixed RGB controls hidden if segment contained any non-RGB bus (even though there is also an RGB bus in that segment)
New Max auto white mode
Added hasCCT() bus method
Rename methods to be clearer
WS2811 White getPixelColor fix()

* Fix merge conflict (bus manager cpp)
2023-02-14 01:33:06 +01:00
Blaz Kristan
821f320347 Add user selectable Gamma
Add panel visualisation (@ewoudwijma, #3090)

Bugfix:
- PIR onStateChange() ignored until inited
- remove matrix orientation
- ignore removing ledmap 0 if 2D
- _globalLeds size
2023-02-12 13:18:30 +01:00
Blaz Kristan
eee9274098 Bugfix.
- compiler warnings
- loading nonexistent default ledmap in 2D will revert to built ledmap
- making autosements after 2D set up change
2023-02-11 18:41:30 +01:00
Blaz Kristan
8dd1f89225 Update.
- allow ledmap selection in UI
- upload gap file
- expand matrix generator
2023-02-10 19:49:43 +01:00
Blaž Kristan
f2459ea904 Add ability to use SHT temp. sensor in PWM fan 2023-02-10 09:33:27 +01:00
Blaz Kristan
e51f7bfbff LED matrix gaps. 2023-02-09 20:15:55 +01:00
Ulrich Baumann
e2215ced34 allow alternative northern style ("viertel vor ..." instead of (#3085)
"dreiviertel ..")

Co-authored-by: Uli Baumann <github@uli-baumann.de>
2023-02-09 00:23:53 +01:00
Blaz Kristan
b14c8e82a0 Bugfix.
- correct WLED_DEBUG_PORT override
2023-02-08 10:25:59 +01:00
Blaz Kristan
e7d50d2614 Bugfix.
- respect net debug on/off state
2023-02-08 10:18:41 +01:00
Blaž Kristan
bca92883d2 Merge pull request #3081 from Aircoookie/usermod-enhance
Usermod enhancements
2023-02-06 07:25:24 +01:00
dependabot[bot]
ed865e38de Bump http-cache-semantics from 4.1.0 to 4.1.1 (#3076)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-05 23:52:48 +01:00
Blaž Kristan
dec45109d3 Refactor busmgr (#3079)
* Refactor bus manager.

* Fix for net debug

* Fix 8266 compile

* Move bus static members to proper cpp

---------

Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
2023-02-05 23:48:43 +01:00
Blaz Kristan
48c267c5c1 Bugfix. 2023-02-05 17:57:22 +01:00
Blaz Kristan
c041d39cab Usermod enhancements
- added onStateChange() callback
- added examples & comments to usermod_v2_example.h
- PIR sensor cancels countdown on state change
2023-02-05 12:23:05 +01:00
Blaz Kristan
52c18e77ae Compile fix for net_debug 2023-02-04 23:59:28 +01:00
Blaz Kristan
52a189cdd2 Playlist bugfix.
- another attempt at #3058
2023-02-04 10:56:07 +01:00
Blaž Kristan
dca8a47da8 Dual mode 2D + 1D with auto segment creation. (#3060)
* Dual mode 2D + 1D with auto segment creation.

* Bugfix.
- stop when seglen
2023-02-01 19:30:56 +01:00
Christian Schwinne
6be9317fd7 Merge pull request #3037 from Aircoookie/indentation
Whitespace/indentation cleanup.
2023-02-01 16:07:30 +01:00
Christian Schwinne
bee99ca8d0 Merge branch 'main' into indentation 2023-02-01 15:57:58 +01:00
cschwinne
48dc89cf13 Fix merge conflict (apply changes from 901ce23) 2023-02-01 15:55:44 +01:00
Blaž Kristan
fc7f609234 Disable 1D/2D mapping for individual pixel control 2023-01-31 12:49:36 +01:00
Blaz Kristan
0bed9b3c2e FX tweak.
- Fireworks 1D
2023-01-30 23:10:45 +01:00
Blaz Kristan
31fa73518b Bugfix. #3064 2023-01-30 17:11:14 +01:00
Blaz Kristan
c6fd11157a Bugfix.
- incorrect palette blending in Palette effect (#3055)
2023-01-29 11:58:47 +01:00
Blaz Kristan
ca73a57de7 Bugfix.
- reduce playlist repetition count on save #3058
2023-01-29 11:27:14 +01:00
Henrik
38a545af92 Fix regen on out format change 2023-01-26 16:11:54 +01:00
Blaž Kristan
b91b340afd Update changelog. 2023-01-25 13:18:54 +01:00
Blaz Kristan
8e7b1c97df Merge branch 'fx-upd' 2023-01-24 21:13:12 +01:00
Blaz Kristan
c9c55fe0c9 Bump version to 0.14.0-b2 2023-01-24 21:08:26 +01:00
Blaz Kristan
d553160d65 Update to changelog 2023-01-24 20:41:10 +01:00
Blaž Kristan
b8a4df2f50 Merge pull request #3042 from werkstrom/patch-1
WLED PixelArtCreator
2023-01-24 18:56:05 +01:00
Blaz Kristan
36edbf6ea9 Merge branch 'main' into patch-1 2023-01-24 18:49:49 +01:00
Blaz Kristan
f966535ea9 Fix resize input on segment load. 2023-01-24 17:15:38 +01:00
Blaz Kristan
07cc26a144 Merge branch 'main' into fx-upd 2023-01-24 16:39:49 +01:00
Blaz Kristan
178c4d15b7 Bugfix.
- missing Transpose (seglen)
- reduce flickering for static text (ScrollingText FX #3050)
2023-01-24 16:35:31 +01:00
Henrik
b0b68c695c Size optimizations and cleanup 2023-01-23 21:30:55 +01:00
Blaž Kristan
219a3658d6 Code compression. 2023-01-23 11:41:41 +01:00
Henrik
d2310fc2ea Revert changes 2023-01-22 21:12:03 +01:00
Henrik
3fe0ccd934 Added ability 2 output minified htm file 4 testing 2023-01-22 20:28:23 +01:00
Henrik
f902ebadcc UI, simpler process, get more data from device 2023-01-22 18:47:34 +01:00
Blaz Kristan
57323af167 Reset segments on 2D set-up change. #3028
Bugfix for 2D segment creation.
2023-01-22 11:29:31 +01:00
Blaz Kristan
20b0b5fc8e Boost tweaking. 2023-01-21 22:38:04 +01:00
Henrik
bb72b8cc93 Segment selection and touch ups 2023-01-21 16:33:59 +01:00
Blaz Kristan
fec5516da9 Fire 2012 boost. 2023-01-21 15:39:59 +01:00
Henrik
ec9a092751 - Removed unused code
- Changed rendering of large preview image
2023-01-21 12:10:22 +01:00
Maximilian Mewes
f78f8b6b12 Exposing the Battery state to JSON API - Part 2 2023-01-21 01:44:50 +01:00
Maximilian Mewes
f97b79bc16 Exposing the Battery state to JSON API - Part 1 2023-01-21 00:39:51 +01:00
Maximilian Mewes
42c8a77755 Merge branch 'main' into usermod-battery-update2023 2023-01-20 23:25:13 +01:00
Blaz Kristan
c692cc6a70 Inline fixes. 2023-01-20 22:33:30 +01:00
Blaz Kristan
2b8d8d4e9c Merge branch 'main' into pixart 2023-01-20 16:23:51 +01:00
Blaz Kristan
2ae8032ace Compile fix. 2023-01-20 16:22:19 +01:00
Blaz Kristan
c4416584de Merge branch 'patch-1' into pixart 2023-01-20 15:53:56 +01:00
Blaž Kristan
86d8b49113 Pixelart
- full implementation
2023-01-20 14:40:45 +01:00
Blaz Kristan
7a5d870f67 DJ Light optimisation.
GoL mutations.
cleanup.
2023-01-19 22:22:24 +01:00
Henrik
b43459232a Create file for PixelArtCreator 2023-01-19 22:09:47 +01:00
Frank
e2b4e60c9e pulser bugfix and minor optimizations
* pulser bugfix: " % cols" was missing so the effect would simply run out of visible range
* float math: use optimized functions: sqrtf, fabsf
* two more comments where code could be optimized, but I'm not sure what is thecorrect solution
2023-01-19 12:26:14 +01:00
Blaz Kristan
17543535e3 FX update
- Dynamic & Dynamic Smooth
- Dissolve & Dissolve Rnd
- Juggles
- Game of Life
- Colorful
- Fireworks & Rain
2023-01-18 22:56:49 +01:00
Blaz Kristan
901ce23cd2 Bugfix.
- incorrect ro_pins in settings
2023-01-18 22:23:34 +01:00
Blaz Kristan
1b52d8065e Ecternal MOSFET for parasite DS18B20 2023-01-18 17:36:04 +01:00
Blaz Kristan
c6db901051 Added gradient to drawCharacter()
Ability to select gradient text on Scrolling Text FX.
2023-01-17 19:54:44 +01:00
Blaž Kristan
39edb1ad37 Merge pull request #2891 from mxklb/pr_fxsegs
Refactored DMX effect mode + new segment controls
2023-01-16 22:38:02 +01:00
Blaz Kristan
a397aa188c Whitespace/indentation cleanup. 2023-01-16 22:12:02 +01:00
Blaz Kristan
dd08751f3f Hide 2D if not compiled. 2023-01-16 22:09:43 +01:00
Blaz Kristan
ef6a9184ba A few more flash bytes saved. 2023-01-16 21:55:12 +01:00
Blaž Kristan
575fb6fc60 Merge pull request #3022 from Aircoookie/disable-more
Disable MQTT more.
2023-01-16 21:44:00 +01:00
Blaz Kristan
4147d6c67e FX: GameOfLife
- better glider detection
- correct behaviour during transition
- optimisations
2023-01-16 18:53:52 +01:00
mxklb
115c17ab90 Corrected wrong comments 2023-01-16 17:30:55 +01:00
mx
d892c7290c Merge branch 'Aircoookie:main' into pr_fxsegs 2023-01-16 17:28:44 +01:00
Blaz Kristan
63d8a902d5 Loading defaults on "fxdef". 2023-01-15 15:21:39 +01:00
Blaz Kristan
43152fcf19 Bugfix.
- d.max_gpio in usermod settings.
2023-01-15 15:19:48 +01:00
Blaz Kristan
1f135f1fa5 "i" start index bugfix #3024 2023-01-14 16:01:46 +01:00
Blaz Kristan
c71d378eab New FX Distortion Waves
Updated FX Lissajous
2023-01-12 21:58:54 +01:00
Maximilian Mewes
bb82bf762f Update Readme, my_config type config options with examples 2023-01-12 21:50:46 +01:00
Blaz Kristan
6fa5689aaf Bugfix.
- segment off
2023-01-12 20:36:50 +01:00
Blaz Kristan
d78bef72ea Disable MQTT more.
Disable Alexa more.
2023-01-12 20:35:34 +01:00
Blaz Kristan
e410de9552 Bugfix.
- fadePixelColorXY()
- clearing 2D segment on mirror or reverse change
- FX update (DNA Spiral, Colored bursts)
2023-01-12 19:13:07 +01:00
Blaz Kristan
8dc262b415 Bugfixes.
- faster random palette blends
- remove UI ledmap selection for 2D
- FX updates (DNA Spiral, Colored bursts, Metaballs)
2023-01-11 23:08:08 +01:00
Abhi Gulati
7fa494815f Fix a typo (#3014) 2023-01-11 11:21:45 +01:00
Blaž Kristan
929bb70e5a Merge pull request #3012 from spdustin/fix-tooltip-pointer-events
Fixes tooltip interfering with pointer events
2023-01-10 06:11:53 +01:00
Dustin Miller
36fb262fa0 Fixes tooltip interfering with pointer events 2023-01-09 18:38:00 -06:00
Frank
b8cc783583 pio: minor update for -C3
adding optional platform version that seems to help in some special cases.
2023-01-09 13:20:02 +01:00
Blaž Kristan
67b3d383e4 Minor fix for (obsolete) Solid Glitter 2023-01-09 13:17:08 +01:00
Frank
9144ccac6b Merge pull request #3006 from Aircoookie/fx-update
FX updates, 2nd try.
2023-01-08 23:44:42 +01:00
Blaz Kristan
04020d5ae2 Universal glitter. 2023-01-08 21:58:55 +01:00
Blaž Kristan
de4f1d09af Merge pull request #3005 from Aircoookie/whitespace 2023-01-07 08:13:17 +01:00
Maximilian Mewes
d16f9efeec Added forgotten file 😥 2023-01-06 19:09:12 +01:00
Maximilian Mewes
8ba5dfe447 Another Bugfx 🧑‍🔧 2023-01-06 19:07:39 +01:00
Blaz Kristan
27d7f5f190 Fixes.
Prevent flickering if segment off.
2023-01-06 18:11:52 +01:00
Blaz Kristan
c43c4c42c8 Renamed No Bg to Overlay 2023-01-06 17:23:24 +01:00
Maximilian Mewes
3759071449 Fix previous bug again 🐛, Add Type Dropdown to config page 2023-01-06 17:00:29 +01:00
Blaž Kristan
613283f656 typo fix 2023-01-06 09:44:26 +01:00
Blaž Kristan
506b6b51ce whitespace cleanup 2023-01-06 09:24:29 +01:00
Blaž Kristan
c7eccfb714 FX updates:
- Ripple (2D & no Bg)
- Glitter (no Bg)
- Sparkle (no Bg)
- Scan (no Bg)
- Two dots (no Bg)
- ICU (no Bg)
- Lightning (no Bg)
- Halloween eyes (no Bg)
- Spots (no Bg)
- Bouncing Balls (no BG)
- Popcorn (no Bg)
- Starburst (no Bg)
- Drip (no Bg)
- Whitespace cleanup
- draw_circle()

"no Bg" will allow overlapping segments if checked.
2023-01-06 09:10:39 +01:00
Maximilian Mewes
85d59945a0 runtime exception fix 🐛 2023-01-06 00:19:16 +01:00
Blaz Kristan
98be19b29f Fix switching off for PIR usermod. 2023-01-05 22:46:30 +01:00
Maximilian Mewes
4c8b490c89 minor changes 2023-01-05 20:38:55 +01:00
Maximilian Mewes
8dd1745149 Add base battery 🔋 class, Add Lipo, Lion class 2023-01-05 19:48:53 +01:00
dekay
66406d86c1 Update comment for 44-key remote (#2999)
Defs for this remote appear to be complete and are not "to be done later".
2023-01-05 16:49:53 +01:00
Frank
35832b07b9 UM Battery: basic support for LiPo cells
* Lipo cells (1S) should not be discharged below 3V
* LiPo cells have a different voltage/discharge rate curve
2023-01-04 19:57:33 +01:00
Frank
357683cbb9 UM Battery: more bugfixing, and improvements for esp32
- improved support for esp32 (read calibrated voltage)
- corrected config saving (measurement pin, and battery min/max were lost)
2023-01-04 17:30:08 +01:00
Frank
15bc6159f9 UM Battery: fix for deprecated function call
wled00/../usermods/Battery/usermod_v2_Battery.h:446:48: warning: 'void PinManagerClass::deallocatePin(byte)' is deprecated: Replaced by two-parameter deallocatePin(gpio, ownerTag)
2023-01-04 12:54:02 +01:00
Frank
7cdafa76a5 UM Battery - improvements for esp32
* added missing pinMode(.., INPUT) on esp32
* do not try reading from pin = -1 (ESP32-S2 shows very allergic reactions to this)
* Info page - show "n/a" when pin = -1
* readme: esp32 default pin = 35
2023-01-04 12:32:31 +01:00
cschwinne
e84b0c91f8 Update year 2023-01-03 17:36:24 +01:00
cschwinne
cecffee3d3 Merge branch 'main' of https://github.com/Aircoookie/WLED 2023-01-03 17:16:14 +01:00
cschwinne
d039a40d7c Invert pull up config value, fixes #2996
Cronixie usermod format change fix
2023-01-03 17:15:55 +01:00
Blaz Kristan
90463d8613 Battery UM fix for MQTT voltage topic. 2023-01-03 17:14:24 +01:00
Blaz Kristan
90c965a6ba Bugfix editing 2D set-up. 2023-01-03 17:12:35 +01:00
Frank
e961691645 Battery, second try 2023-01-03 15:36:35 +01:00
Frank
6270d2408f UM Battery: fix build error on linux
Fixes build error on linux:
wled00/usermods_list.cpp:15:54: fatal error: ../usermods/battery/usermod_v2_battery.h: No such file or directory
compilation terminated.
2023-01-03 15:29:15 +01:00
Frank
7ef1842237 comments updated
see discussion in faf616cbea
2023-01-03 15:16:45 +01:00
Frank
faf616cbea fixing a potential stack corruption
.. overlooked this one when reviewing the PR.
@blazoncek, @ctjet : three questions on the new code remain, because its not clear to me if its correct. Please check.
2023-01-03 14:17:42 +01:00
Frank
4a09e18d9a UM Battery: fix compilation error + bad snprintf 2023-01-02 22:52:37 +01:00
Blaz Kristan
983aca515d Compile fix for disabled 2D. 2023-01-02 21:24:02 +01:00
Frank
eb184d3c68 build number, npm run build 2023-01-02 21:01:39 +01:00
Caleb Marting
187ecf511f 2d Mapping with Matrix Gaps (#2892)
* New 2d mapping
* panel matrix generator
* add todos, fix vert/horz swap
* Fix 2d mapping to matrix in settings 2D
* add correct index mapping to pixels per panel
* fix panel bug in led layout
* formatting and change max panels
* add per panel width and height
* fix using length instead of custom mapping size
* fix: panel dimensions location

* panel[] implemented as a vector.
Removed matrixWidth & matrixHeight.
Panel structure update.
* Fixes.

Co-authored-by: Blaz Kristan <blaz@kristan-sp.si>
2023-01-02 20:56:00 +01:00
lost-hope
0ab35a3ca3 added klipper usermod 2023-01-01 15:13:57 +01:00
Blaž Kristan
8e208bc76d Merge pull request #2993 from spdustin/fix-analog-clock-hours
fixes typo in Analog_Clock.h
2023-01-01 00:35:14 +01:00
Dustin Miller
1b4d92007e updates strings to use F() 2022-12-31 15:24:35 -06:00
Dustin Miller
4101d7664d fixes typo in Analog_Clock.h
Retrieving the config in `readFromConfig()` results in defaults being set to both `hourMarksEnabled` (`false`) and `hourMarkColor` (`#0000FF`) due to differences in capitalization compared to how they're saved in `addToConfig()`
2022-12-31 13:47:48 -06:00
Blaz Kristan
e128c3094a Typo fix. 2022-12-31 18:58:52 +01:00
Blaz Kristan
95869eeb70 Allow more virtual buses. 2022-12-31 17:06:18 +01:00
Blaž Kristan
d977bbd61c Merge pull request #2990 from relax81/main
added #DDMM & #HHMM to scrolling text
2022-12-31 14:10:51 +01:00
Leif
a16a6211e2 added #MMDD view to the scrolling text effect 2022-12-31 03:30:26 +01:00
Leif
a75013e43e Merge remote-tracking branch 'upstream/main' into main 2022-12-31 03:25:21 +01:00
Mark Breen
1e157e95b6 minor spelling fix (#2991) 2022-12-30 12:29:02 +01:00
Leif
04dbfcd0e6 added #DDMM & #HHMM to scrolling text 2022-12-30 00:04:22 +01:00
Maximilian Mewes
73440e2287 Update Usermod Battery (#2975)
* auto-off feature and usermod rename
* low-power-indicator, voltage fine tuning, clean-up

* corrected small mistakes
* Bugfixes, added usermod logo, update readme
* minor changes, implemented change requests, optimizationz
2022-12-28 22:40:13 +01:00
Blaž Kristan
ee4459691f Merge pull request #2982 from itCarl/task-fixing-comments-in-pin_manager-header
Fix Hex values in comments in pin_manager.h
2022-12-28 22:36:55 +01:00
Maximilian Mewes
379c6045b9 Merge branch 'Aircoookie:main' into task-fixing-comments-in-pin_manager-header 2022-12-28 01:53:12 +01:00
Maximilian Mewes
00d0ddb4b5 fixed pinowner comments (hex is not correct and the order is wrong) 2022-12-28 01:50:04 +01:00
Blaz Kristan
be08c01be6 Fix for #2979 2022-12-28 01:01:31 +01:00
Blaž Kristan
fb6abe34df Merge pull request #2966 from Aircoookie/hex-palette
Hex custom palettes and smooth random palette change
2022-12-28 00:53:01 +01:00
Blaz Kristan
b0d107f916 Merge branch 'main' into hex-palette 2022-12-26 10:26:01 +01:00
Blaz Kristan
6d1ff7c3f3 Railway FX
- slower minimum speed
- allow color 1 & 2 in UI
2022-12-26 10:25:26 +01:00
Blaz Kristan
6f67132f4b PROGMEM string optimisation. 2022-12-26 10:20:45 +01:00
Blaž Kristan
859d21162c Merge pull request #2963 from ezcGman/um-sht
SHT Usermod: Fixed MQTT discovery using correct unit; Added getters and isEnabled() check
2022-12-25 22:49:24 +01:00
Blaz Kristan
c739a7ea2f Erroneous ) 2022-12-25 11:05:25 +01:00
Blaz Kristan
7e48875fd4 Minor optimisation. 2022-12-25 11:02:50 +01:00
Blaz Kristan
474e86306f Bugfix: incorrect maxWidth after switching from 2D 2022-12-24 22:00:35 +01:00
Blaz Kristan
b436a660f1 Merge branch 'main' into hex-palette 2022-12-23 21:35:52 +01:00
Blaz Kristan
d36460e30b Minor optimisation.
Fix for #2969
2022-12-23 16:37:13 +01:00
Blaz Kristan
22b2503839 Bugfix & code optimisation. 2022-12-22 18:13:32 +01:00
Blaz Kristan
4322d195d3 Smooth random palette changes
Bugfix loading string palettes
JS optimization.
2022-12-21 21:00:28 +01:00
ezcGman
4ecad65926 UM SHT: Codestyle 2022-12-21 00:34:22 +01:00
ezcGman
f12025b86e UM SHT: Added getters and isEnabled check 2022-12-21 00:05:26 +01:00
ezcGman
5cfea54b06 UM SHT: Apply PR feedback 2022-12-20 23:58:11 +01:00
mxklb
c24b75953a Merge branch 'main' into pr_fxsegs 2022-12-20 01:06:46 +01:00
ezcGman
f3d52f4932 UM SHT: MQTT re-publish values on unit change 2022-12-19 22:30:11 +01:00
ezcGman
ea6d339b9c UM SHT: Fixed MQTT discovery using correct unit 2022-12-19 22:15:39 +01:00
Blaz Kristan
0a0ced3e8e Hex string custom palette option 2022-12-18 21:02:19 +01:00
mxklb
c51dbae8b6 Removed bad code comments 2022-12-14 22:55:42 +01:00
mxklb
f38747aa28 Fixed bug: Last segment in universe skipped 2022-12-09 02:11:16 +01:00
mx
bd721c1310 Merge branch 'Aircoookie:main' into pr_fxsegs 2022-11-29 00:54:15 +01:00
mxklb
507e198b70 Minor cleanups 2022-11-26 17:22:03 +01:00
mx
5c721ee435 Merge branch 'Aircoookie:main' into pr_fxsegs 2022-11-26 17:15:55 +01:00
mxklb
8c5f9b4501 Added missing DMX effect options and 3rd color 2022-11-26 14:41:59 +01:00
mxklb
87fa14b281 Use up-to-date fashion for segment dmx control 2022-11-23 23:19:53 +01:00
mxklb
043947fdcb Added missing brightness to preset DMX mode 2022-11-23 00:38:42 +01:00
mx
ae7eedf523 Merge branch 'Aircoookie:main' into pr_fxsegs 2022-11-20 23:48:06 +01:00
mxklb
84628bd9fc Refactored DMX effect mode + new segement controls (#2325) 2022-11-19 14:10:40 +01:00
pjhatch
56a74bc54c Update FX.cpp
Added the improvements suggested by Gregor Hartmann
2020-08-15 12:34:13 -05:00
pjhatch
a20358b61b Adding 2 ball track modes
With and without collisions
2020-07-12 08:33:48 -05:00
pjhatch
341d9d1697 Update FX.cpp
Still 1 bug to fix - this was a test.
2020-07-05 14:55:14 -05:00
pjhatch
9cee424383 Update FX.cpp 2020-07-05 14:53:14 -05:00
pjhatch
37cb51cfd6 Adding Collision
A couple of bugs still need sorting
2020-07-02 14:16:25 -05:00
pjhatch
84b7bfb989 update for lost balls
Added some protection - so that when intensity is lowered and raised some time later balls that have moved way off the track are recovered.
2020-06-28 19:59:46 -05:00
pjhatch
04d17e4839 Added Ball Track V1
In this version the balls bounce of the edges and do not interact with one another.
2020-06-28 19:43:56 -05:00
324 changed files with 40174 additions and 34023 deletions

View File

@@ -12,6 +12,21 @@
}
},
// To give the container access to a device serial port, you can uncomment one of the following lines.
// Note: If running on Windows, you will have to do some additional steps:
// https://stackoverflow.com/questions/68527888/how-can-i-use-a-usb-com-port-inside-of-a-vscode-development-container
//
// You can explicitly just forward the port you want to connect to. Replace `/dev/ttyACM0` with the serial port for
// your device. This will only work if the device is plugged in from the start without reconnecting. Adding the
// `dialout` group is needed if read/write permisions for the port are limitted to the dialout user.
// "runArgs": ["--device=/dev/ttyACM0", "--group-add", "dialout"],
//
// Alternatively, you can give more comprehensive access to the host system. This will expose all the host devices to
// the container. Adding the `dialout` group is needed if read/write permisions for the port are limitted to the
// dialout user. This could allow the container to modify unrelated serial devices, which would be a similar level of
// risk to running the build directly on the host.
// "runArgs": ["--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "--group-add", "dialout"],
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",

20
.github/stale.yml vendored
View File

@@ -1,20 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 120
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- keep
- enhancement
- confirmed
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
Hey! This issue has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for using WLED!
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

30
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '0 12 * * *'
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-stale: 120
days-before-close: 7
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'pinned,keep,enhancement,confirmed'
exempt-pr-labels: 'pinned,keep,enhancement,confirmed'
exempt-all-milestones: true
operations-per-run: 1000
stale-issue-message: >
Hey! This issue has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for using WLED! ✨
stale-pr-message: >
Hey! This pull request has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for contributing to WLED! ❤️

View File

@@ -1,4 +1,4 @@
name: PlatformIO CI
name: WLED CI
on: [push, pull_request]
@@ -8,21 +8,17 @@ jobs:
name: Gather Environments
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache pip
uses: actions/cache@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- uses: actions/setup-python@v2
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Get default environments
id: envs
run: |
echo "::set-output name=environments::$(pio project config --json-output | jq -cr '.[0][1][0][1]')"
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
outputs:
environments: ${{ steps.envs.outputs.environments }}
@@ -32,55 +28,67 @@ jobs:
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@v2
- name: Cache pip
uses: actions/cache@v2
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
cache: 'npm'
- run: npm ci
- name: Cache PlatformIO
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
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@v2
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install PlatformIO
run: pip install -r requirements.txt
- name: Build firmware
env:
WLED_RELEASE: True
run: pio run -e ${{ matrix.environment }}
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: firmware-${{ matrix.environment }}
path: |
build_output/firmware/*.bin
build_output/firmware/*.gz
- uses: actions/upload-artifact@v2
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: build_output/release/*.bin
build_output/release/*.bin
build_output/release/*_ESP02*.bin.gz
release:
name: Create Release
runs-on: ubuntu-latest
needs: [get_default_envs, build]
needs: build
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v4
with:
name: firmware-release
merge-multiple: true
- name: Create draft release
uses: softprops/action-gh-release@v1
with:
draft: True
files: |
*.bin
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
*.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

32
.gitignore vendored
View File

@@ -1,20 +1,24 @@
.pio
.cache
.clang-format
.direnv
.DS_Store
.idea
.pio
.pioenvs
.piolibdeps
.vscode
/wled00/Release
/wled00/extLibs
/platformio_override.ini
/wled00/my_config.h
/build_output
.DS_Store
.gitignore
.clang-format
node_modules
.idea
.direnv
wled-update.sh
esp01-update.sh
platformio_override.ini
replace_fs.py
wled-update.sh
/build_output/
/node_modules/
/wled00/extLibs
/wled00/LittleFS
replace_fs.py
/wled00/my_config.h
/wled00/Release
/wled00/wled00.ino.cpp
/wled00/html_*.h

6
.vscode/tasks.json vendored
View File

@@ -9,8 +9,8 @@
],
"dependsOrder": "sequence",
"problemMatcher": [
"$platformio",
],
"$platformio"
]
},
{
"type": "PlatformIO",
@@ -18,7 +18,7 @@
"task": "Build",
"group": {
"kind": "build",
"isDefault": true,
"isDefault": true
},
"problemMatcher": [
"$platformio"

View File

@@ -1,11 +1,555 @@
## WLED changelog
#### Build 2409140
- Configure different kinds of busses at compile (#4107 by @PaoloTK)
- BREAKING: removes LEDPIN and DEFAULT_LED_TYPE compile overrides
- Fetch LED types from Bus classes (dynamic UI) (#4129 by @netmindz, @blazoncek, @dedehai)
#### Build 2409100
- WLED 0.15.0-b5 release
- Audioreactive usermod included by default in all compatible builds (including ESP8266)
- Demystified some byte definitions of WiZmote ESP-NOW message (#4114 by @ChuckMash)
- Update usermod "Battery" improved MQTT support (#4110 by @itCarl)
- Added a usermod for interacting with BLE Pixels Dice (#4093 by @axlan)
- Allow lower values for touch threshold (#4081 by @RobinMeis)
- Added POV image effect usermod (#3539 by @Liliputech)
- Remove repeating code to fetch audio data (#4103 by @netmindz)
- Loxone JSON parser doesn't handle lx=0 correctly (#4104 by @FreakyJ, fixes #3809)
- Rename wled00.ino to wled_main.cpp (#4090 by @willmmiles)
- SM16825 chip support including WW & CW channel swap (#4092)
- Add stress testing scripts (#4088 by @willmmiles)
- Improve jsonBufferLock management (#4089 by @willmmiles)
- Fix incorrect PWM bit depth on Esp32 with XTAL clock (#4082 by @PaoloTK)
- Devcontainer args (#4073 by @axlan)
- Effect: Fire2012 optional blur amount (#4078 by @apanteleev)
- Effect: GEQ fix bands (#4077 by @adrianschroeter)
- Boot delay option (#4060 by @DedeHai)
- ESP8266 Audioreactive sync (#3962 by @gaaat98, @netmindz, @softhack007)
- ESP8266 PWM crash fix (#4035 by @willmmiles)
- Usermod: Battery fix (#4051 by @Nickbert7)
- Usermod: Mpu6050 usermod crash fix (#4048 by @willmmiles)
- Usermod: Internal Temperature V2 (#4033 by @adamsthws)
- Various fixes and improvements (including build environments to emulate 0.14.0 for ESP8266)
#### Build 2407070
- Various fixes and improvements (mainly LED settings fix)
#### Build 2406290
- WLED 0.15.0-b4 release
- LED settings bus management update (WARNING: only allows available outputs)
- Add ETH support for LILYGO-POE-Pro (#4030 by @rorosaurus)
- Update usermod_sn_photoresistor (#4017 by @xkvmoto)
- Several internal fixes and optimisations
- move LED_BUILTIN handling to BusManager class
- reduce max panels (web server limitation)
- edit WiFi TX power (ESP32)
- keep current ledmap ID in UI
- limit outputs in UI based on length
- wifi.ap addition to JSON Info (JSON API)
- relay pin init bugfix
- file editor button in UI
- ESP8266: update was restarting device on some occasions
- a bit of throttling in UI (for ESP8266)
#### Build 2406120
- Update NeoPixelBus to v2.8.0
- Increased LED outputs one ESP32 using parallel I2S (up to 17)
- use single/mono I2S + 4x RMT for 5 outputs or less
- use parallel x8 I2S + 8x RMT for >5 outputs (limit of 300 LEDs per output)
- Fixed code of Smartnest and updated documentation (#4001 by @DevilPro1)
- ESP32-S3 WiFi fix (#4010 by @cstruck)
- TetrisAI usermod fix (#3897 by @muebau)
- ESP-NOW usermod hook
- Update wled.h regarding OTA Password (#3993 by @gsieben)
- Usermod BME68X Sensor Implementation (#3994 by @gsieben)
- Add a usermod for AHT10, AHT15 and AHT20 temperature/humidity sensors (#3977 by @LordMike)
- Update Battery usermod documentation (#3968 by @adamsthws)
- Add INA226 usermod for reading current and power over i2c (#3986 by @LordMike)
- Bugfixes: #3991
- Several internal fixes and optimisations (WARNING: some effects may be broken that rely on overflow/narrow width)
- replace uint8_t and uint16_t with unsigned
- replace in8_t and int16_t with int
- reduces code by 1kB
#### Build 2405180
- WLED 0.14.4 release
- Fix for #3978
- Official 0.15.0-b3 release
- Merge 0.14.3 fixes into 0_15
- Added Pinwheel Expand 1D->2D effect mapping mode (#3961 by @Brandon502)
- Add changeable i2c address to BME280 usermod (#3966 by @LordMike)
- Effect: Firenoise - add palette selection
- Experimental parallel I2S support for ESP32 (compile time option)
- increased outputs to 17
- increased max possible color order overrides
- use WLED_USE_PARALLEL_I2S during compile
WARNING: Do not set up more than 256 LEDs per output when using parallel I2S with NeoPixelBus less than 2.9.0
- Update Usermod: Battery (#3964 by @adamsthws)
- Update Usermod: BME280 (#3965 by @LordMike)
- TM1914 chip support (#3913)
- Ignore brightness in Peek
- Antialiased line & circle drawing functions
- Enabled some audioreactive effects for single pixel strips/segments (#3942 by @gaaat98)
- Usermod Battery: Added Support for different battery types, Optimized file structure (#3003 by @itCarl)
- Skip playlist entry API (#3946 by @freakintoddles2)
- various optimisations and bugfixes (#3987, #3978)
#### Build 2405030
- Using brightness in analog clock overlay (#3944 by @paspiz85)
- Add Webpage shortcuts (#3945 by @w00000dy)
- ArtNet Poll reply (#3892 by @askask)
- Improved brightness change via long button presses (#3933 by @gaaat98)
- Relay open drain output (#3920 by @Suxsem)
- NEW JSON API: release info (update page, `info.release`)
- update esp32 platform to arduino-esp32 v2.0.9 (#3902)
- various optimisations and bugfixes (#3952, #3922, #3878, #3926, #3919, #3904 @DedeHai)
#### Build 2404120
- v0.15.0-b3
- fix for #3896 & WS2815 current saving
- conditional compile for AA setPixelColor()
#### Build 2404100
- Internals: #3859, #3862, #3873, #3875
- Prefer I2S1 over RMT on ESP32
- usermod for Adafruit MAX17048 (#3667 by @ccruz09)
- Runtime detection of ESP32 PICO, general PSRAM support
- Extend JSON API "info" object
- add "clock" - CPU clock in MHz
- add "flash" - flash size in MB
- Fix for #3879
- Analog PWM fix for ESP8266 (#3887 by @gaaat98)
- Fix for #3870 (#3880 by @DedeHai)
- ESP32 S3/S2 touch fix (#3798 by @DedeHai)
- PIO env. PSRAM fix for S3 & S3 with 4M flash
- audioreactive always included for S3 & S2
- Fix for #3889
- BREAKING: Effect: modified KITT (Scanner) (#3763)
#### Build 2404040
- WLED 0.14.3 release
- Fix for transition 0 (#3854, #3832, #3720)
- Fix for #3855 via #3873 (by @willmmiles)
#### Build 2403280
- Individual color channel control for JSON API (fixes #3860)
- "col":[int|string|object|array, int|string|object|array, int|string|object|array]
int = Kelvin temperature or 0 for black
string = hex representation of [WW]RRGGBB
object = individual channel control {"r":0,"g":127,"b":255,"w":255}, each being optional (valid to send {})
array = direct channel values [r,g,b,w] (w element being optional)
- runtime selection for CCT IC (Athom 15W bulb)
- #3850 (by @w00000dy)
- Rotary encoder palette count bugfix
- bugfixes and optimisations
#### Build 2403240
- v0.15.0-b2
- WS2805 support (RGB + WW + CW, 600kbps)
- Unified PSRAM use
- NeoPixelBus v2.7.9
- Ubiquitous PSRAM mode for all variants of ESP32
- SSD1309_64 I2C Support for FLD Usermod (#3836 by @THATDONFC)
- Palette cycling fix (add support for `{"seg":[{"pal":"X~Y~"}]}` or `{"seg":[{"pal":"X~Yr"}]}`)
- FW1906 Support (#3810 by @deece and @Robert-github-com)
- ESPAsyncWebServer 2.2.0 (#3828 by @willmmiles)
- Bugfixes: #3843, #3844
#### Build 2403190
- limit max PWM frequency (fix incorrect PWM resolution)
- Segment UI bugfix
- Updated AsyncWebServer (by @wlillmmiles)
- Simpler boot preset (fix for #3806)
- Effect: Fix for 2D Drift animation (#3816 by @BaptisteHudyma)
- Effect: Add twin option to 2D Drift
- MQTT cleanup
- DDP: Support sources that don't push (#3833 by @willmmiles)
- Usermod: Tetris AI usermod (#3711 by @muebau)
#### Build 2403171
- merge 0.14.2 changes into 0.15
#### Build 2403070
- Add additional segment options when controlling over e1.31 (#3616 by @demophoon)
- LockedJsonResponse: Release early if possible (#3760 by @willmmiles)
- Update setup-node and cache usermods in wled-ci.yml (#3737 by @WoodyLetsCode)
- Fix preset sorting (#3790 by @WoodyLetsCode)
- compile time button configuration #3792
- remove IR config if not compiled
- additional string optimisations
- Better low brightness level PWM handling (fixes #2767, #2868)
#### Build 2402290
- Multiple analog button fix for #3549
- Preset caching on chips with PSRAM (credit @akaricchi)
- Fixing stairway usermod and adding buildflags (by @lost-hope)
- ESP-NOW packet modification
- JSON buffer lock error messages / Reduce wait time for lock to 100ms
- Reduce string RAM usage for ESP8266
- Fixing a potential array bounds violation in ESPDMX
- Move timezone table to PROGMEM (#3766 by @willmmiles)
- Reposition upload warning message. (fixes #3778)
- ABL display fix & optimisation
- Add virtual Art-Net RGBW option (#3783 by @shammy642)
#### Build 2402090
- Added new Ethernet controller RGB2Go Tetra (duplicate of ESP3DEUXQuattro)
- Usermod: httpPullLightControl (#3560 by @roelbroersma)
- DMX: S2 & C3 support via modified ESPDMX
- Bugfix: prevent cleaning of JSON buffer after a failed lock attempt (BufferGuard)
- Product/Brand override (API & AP SSID) (#3750 by @moustachauve)
#### Build 2402060
- WLED version 0.15.0-b1
- Harmonic Random Cycle palette (#3729 by @dedehai)
- Multi PIR sensor usermod (added support for attaching multiple PIR sensors)
- Removed obsolete (and nonfunctional) usermods
#### Build 2309120 till build 2402010
- WLED version 0.15.0-a0
- Multi-WiFi support. Add up to 3 (or more via cusom compile) WiFis to connect to (with help from @JPZV)
- Temporary AP. Use your WLED in public with temporary AP.
- Github CI build system enhancements (#3718 by @WoodyLetsCode)
- Accessibility: Node list ( #3715 by @WoodyLetsCode)
- Analog clock overlay enhancement (#3489 by @WoodyLetsCode)
- ESP32-POE-WROVER from Olimex ethernet support (#3625 by @m-wachter)
- APA106 support (#3580 by @itstefanjanos)
- BREAKING: Effect: updated Palette effect to support 2D (#3683 by @TripleWhy)
- "SuperSync" from WLED MM (by @MoonModules)
- Effect: DNA Spiral Effect Speed Fix (#3723 by @Derek4aty1)
- Fix for #3693
- Orange flash fix (#3196) for transitions
- Add own background image upload (#3596 by @WoodyLetsCode)
- WLED time overrides (`WLED_NTP_ENABLED`, `WLED_TIMEZONE`, `WLED_UTC_OFFSET`, `WLED_LAT` and `WLED_LON`)
- Better sorting and naming of static palettes (by @WoodyLetsCode)
- ANIMartRIX usermod and effects (#3673 by @netmindz)
- Use canvas instead of CSS gradient for liveview (#3621 by @zanhecht)
- Fix for #3672
- ColoOrderMap W channel swap (color order overrides now have W swap)
- En-/disable LED maps when receiving realtime data (#3554 by @ezcGman)
- Added PWM frequency selection to UI (Settings)
- Automatically build UI before compiling (#3598, #3666 by @WoodyLetsCode)
- Internal: Added *suspend* API to `strip` (`WS2812FX class`)
- Possible fix for #3589 & partial fix for #3605
- MPU6050 upgrade (#3654 by @willmmiles)
- UI internals (#3656 by @WoodyLetsCode)
- ColorPicker fix (#3658 by @WoodyLetsCode)
- Global JSON buffer guarding (#3648 by @willmmiles, resolves #3641, #3312, #3367, #3637, #3646, #3447)
- Effect: Fireworks 1D (fix for matrix trailing strip)
- BREAKING: Reduced number of segments (12) on ESP8266 due to less available RAM
- Increased available effect data buffer (increases more if board has PSRAM)
- Custom palette editor mobile UI enhancement (by @imeszaros)
- Per port Auto Brightness Limiter (ABL)
- Use PSRAM for JSON buffer (double size, larger ledmaps, up to 2k)
- Reduced heap fragmentation by allocating ledmap array only once and not deallocating effect buffer
- HTTP retries on failed UI load
- UI Search: scroll to top (#3587 by @WoodyLetsCode)
- Return to inline iro.js and rangetouch.js (#3597 by @WoodyLetsCode)
- Better caching (#3591 by @WoodyLetsCode)
- Do not send 404 for missing `skin.css` (#3590 by @WoodyLetsCode)
- Simplified UI rework (#3511 by @WoodyLetsCode)
- Domoticz device ID for PIR and Temperature usermods
- Bugfix for UCS8904 `hasWhite()`
- Better search in UI (#3540 by @WoodyLetsCode)
- Seeding FastLED PRNG (#3552 by @TripleWhy)
- WIZ Smart Button support (#3547 by @micw)
- New button type (button switch, fix for #3537)
- Pixel Magic Tool update (#3483 by @ajotanc)
- Effect: 2D Matrix fix for gaps
- Bugfix #3526, #3533, #3561
- Spookier Halloween Eyes (#3501)
- Compile time options for Multi Relay usermod (#3498)
- Effect: Fix for Dissolve (#3502)
- Better reverse proxy support (nested paths)
- Implement global JSON API boolean toggle (i.e. instead of "var":true or "var":false -> "var":"t").
- Sort presets by ID
- Fix for #3641, #3312, #3367, #3637, #3646, #3447, #3632, #3496, #2922, #3593, #3514, #3522, #3578 (partial), #3606 (@WoodyLetsCode)
- Improved random bg image and added random bg image options (@WoodyLetsCode, #3481)
- Audio palettes (Audioreactive usermod, credit @netmindz)
- Better UI tooltips (@ajotnac, #3464)
- Better effect filters (filter dropdown)
- UDP sync fix (for #3487)
- Power button override (solves #3431)
- Additional HTTP request throttling (ESP8266)
- Additional UI/UX improvements
- Segment class optimisations (internal)
- ESP-NOW sync
- ESP-NOW Wiz remote JSON overrides (similar to IR JSON) & bugfixes
- Gamma correction for custom palettes (#3399).
- Restore presets from browser local storage
- Optional effect blending
- Restructured UDP Sync (internal)
- Remove sync receive
- Sync clarification
- Disallow 2D effects on non-2D segments
- Return of 2 audio simulations
- Bugfix in sync #3344 (internal)
- remove excessive segments
- ignore inactive segments if not syncing bounds
- send UDP/WS on segment change
- pop_back() when removing last segment
#### Build 2403170
- WLED 0.14.2 release
#### Build 2403110
- Beta WLED 0.14.2-b2
- New AsyncWebServer (improved performance and reduced memory use)
- New builds for ESP8266 with 160MHz CPU clock
- Fixing stairway usermod and adding buildflags (#3758 by @lost-hope)
- Fixing a potential array bounds violation in ESPDMX
- Reduced RAM usage (moved strings and TZ data (by @willmmiles) to PROGMEM)
- LockedJsonResponse: Release early if possible (by @willmmiles)
#### Build 2402120
- Beta WLED 0.14.2-b1
- Possible fix for #3589 & partial fix for #3605
- Prevent JSON buffer clear after failed lock attempt
- Multiple analog button fix for #3549
- UM Audioreactive: add two compiler options (#3732 by @wled-install)
- Fix for #3693
#### Build 2401141
- Official release of WLED 0.14.1
- Fix for #3566, #3665, #3672
- Sorting of palettes in custom palette editor (#3674 by @WoodyLetsCode)
#### Build 2401060
- Version bump: 0.14.1-b3
- Global JSON buffer guarding (#3648 by @willmmiles, resolves #3641, #3312, #3367, #3637, #3646, #3447)
- Fix for #3632
- Custom palette editor mobile UI enhancement (#3617 by @imeszaros)
- changelog update
#### Build 2312290
- Fix for #3622, #3613, #3609
- Various tweaks and fixes
- changelog update
#### Build 2312230
- Version bump: 0.14.1-b2
- Fix for Pixel Magic button
- Fix for #2922 (option to force WiFi PHY mode to G on ESP8266)
- Fix for #3601, #3400 (incorrect sunrise/sunset, #3612 by @softhack007)
#### Build 2312180
- Bugfixes (#3593, #3490, #3573, #3517, #3561, #3555, #3541, #3536, #3515, #3522, #3533, #3508)
- Various other internal cleanups and optimisations
#### Build 2311160
- Version bump: 0.14.1-b1
- Bugfixes (#3526, #3502, #3496, #3484, #3487, #3445, #3466, #3296, #3382, #3312)
- New feature: Sort presets by ID
- New usermod: LDR sensor (#3490 by @JeffWDH)
- Effect: Twinklefox & Tinklecat metadata fix
- Effect: separate #HH and #MM for Scrolling Text (#3480)
- SSDR usermod enhancements (#3368)
- PWM fan usermod enhancements (#3414)
#### Build 2310010, build 2310130
- Release of WLED version 0.14.0 "Hoshi"
- Bugfixes for #3400, #3403, #3405
- minor HTML optimizations
- audioreactive: bugfix for UDP sound sync (partly initialized packets)
#### Build 2309240
- Release of WLED beta version 0.14.0-b6 "Hoshi"
- Effect bugfixes and improvements (Meteor, Meteor Smooth, Scrolling Text)
- audioreactive: bugfixes for ES8388 and ES7243 init; minor improvements for analog inputs
#### Build 2309100
- Release of WLED beta version 0.14.0-b5 "Hoshi"
- New standard esp32 build with audioreactive
- Effect blending bugfixes, and minor optimizations
#### Build 2309050
- Effect blending (#3311) (finally effect transitions!)
*WARNING*: May not work well with ESP8266, with plenty of segments or usermods (low RAM condition)!!!
- Added receive and send sync groups to JSON API (#3317) (you can change sync groups using preset)
- Internal temperature usermod (#3246)
- MQTT server and topic length overrides (#3354) (new build flags)
- Animated Staircase usermod enhancement (#3348) (on/off toggle/relay control)
- Added local time info to Info page (#3351)
- New effect: Rolling Balls (a.k.a. linear bounce) (#1039)
- Various bug fixes and enhancements.
#### Build 2308110
- Release of WLED beta version 0.14.0-b4 "Hoshi"
- Reset effect data immediately upon mode change
#### Build 2308030
- Improved random palette handling and blending
- Soap bugfix
- Fix ESP-NOW crash with AP mode Always
#### Build 2307180
- Bus-level global buffering (#3280)
- Removed per-segment LED buffer (SEGMENT.leds)
- various fixes and improvements (ESP variants platform 5.3.0, effect optimizations, /json/cfg pin allocation)
#### Build 2307130
- larger `oappend()` stack buffer (3.5k) for ESP32
- Preset cycle bugfix (#3262)
- Rotary encoder ALT fix for large LED count (#3276)
- effect updates (2D Plasmaball), `blur()` speedup
- On/Off toggle from nodes view (may show unknown device type on older versions) (#3291)
- various fixes and improvements (ABL, crashes when changing presets with different segments)
#### Build 2306270
- ESP-NOW remote support (#3237)
- Pixel Magic tool (display pixel art) (#3249)
- Websocket (peek) fallback when connection cannot be established, WS retries (#3267)
- Add WiFi network scan RPC command to Improv Serial (#3271)
- Longer (custom option available) segment name for ESP32
- various fixes and improvements
#### Build 2306210
- 0.14.0-b3 release
- respect global I2C in all usermods (no local initialization of I2C bus)
- Multi relay usermod compile-time enabled option (-D MULTI_RELAY_ENABLED=true|false)
#### Build 2306180
- Added client-side option for applying effect defaults from metadata
- Improved ESP8266 stability by reducing WebSocket response resends
- Updated ESP8266 core to 3.1.2
#### Build 2306141
- Lissajous improvements
- Scrolling Text improvements (leading 0)
#### Build 2306140
- Add settings PIN (un)locking to JSON post API
#### Build 2306130
- Bumped version to 0.14-b3 (beta 3)
- added pin dropdowns in LED preferences (not for LED pins) and usermods
- introduced (unused ATM) NeoGammaWLEDMethod class
- Reverse proxy support
- PCF8754 support for Rotary encoder (requires wiring INT pin to ESP GPIO)
- Rely on global I2C pins for usermods (breaking change)
- various fixes and enhancements
#### Build 2306020
- Support for segment sets (PR #3171)
- Reduce sound simulation modes to 2 to facilitate segment sets
- Trigger button immediately on press if all configured presets are the same (PR #3226)
- Changes for allowing Alexa to change light color to White when auto-calculating from RGB (PR #3211)
#### Build 2305280
- DDP protocol update (#3193)
- added PCF8574 I2C port expander support for Multi relay usermod
- MQTT multipacket (fragmented) message fix
- added option to retain MQTT brightness and color messages
- new ethernet board: @srg74 Ethernet Shield
- new 2D effects: Soap (#3184) & Octopus & Waving cell (credit @St3P40 https://github.com/80Stepko08)
- various fixes and enhancements
#### Build 2305090
- new ethernet board: @Wladi ABC! WLED Eth
- Battery usermod voltage calculation (#3116)
- custom palette editor (#3164)
- improvements in Dancing Shadows and Tartan effects
- UCS389x support
- switched to NeoPixelBus 2.7.5 (replaced NeoPixelBrightnessBus with NeoPixelBusLg)
- SPI bus clock selection (for LEDs) (#3173)
- DMX mode preset fix (#3134)
- iOS fix for scroll (#3182)
- Wordclock "Norddeutsch" fix (#3161)
- various fixes and enhancements
#### Build 2304090
- updated Arduino ESP8266 core to 4.1.0 (newer compiler)
- updated NeoPixelBus to 2.7.3 (with support for UCS890x chipset)
- better support for ESP32-C3, ESP32-S2 and ESP32-S3 (Arduino ESP32 core 5.2.0)
- iPad/tablet with 1024 pixels width in landscape orientation PC mode support (#3153)
- fix for Pixel Art Converter (#3155)
#### Build 2303240
- Peek scaling of large 2D matrices
- Added 0D (1 pixel) metadata for effects & enhance 0D (analog strip) UI handling
- Added ability to disable ADAlight (-D WLED_DISABLE_ADALIGHT)
- Fixed APA102 output on Ethernet enabled controllers
- Added ArtNet virtual/network output (#3121)
- Klipper usermod (#3106)
- Remove DST from CST timezone
- various fixes and enhancements
#### Build 2302180
- Removed Blynk support (servers shut down on 31st Dec 2022)
- Added `ledgap.json` to complement ledmaps for 2D matrices
- Added support for white addressable strips (#3073)
- Ability to use SHT temperature usermod with PWM fan usermod
- Added `onStateChange()` callback to usermods (#3081)
- Refactored `bus_manager` [internal]
- Dual 1D & 2D mode (add 1D strip after the matrix)
- Removed 1D -> 2D mapping for individual pixel control
- effect tweak: Fireworks 1D
- various bugfixes
#### Build 2301240
- Version bump to v0.14.0-b2 "Hoshi"
- PixelArt converter (convert any image to pixel art and display it on a matrix) (PR #3042)
- various effect updates and optimisations
- added Overlay option to some effects (allows overlapping segments)
- added gradient text on Scrolling Text
- added #DDMM, #MMDD & #HHMM date and time options for Scrolling Text effect (PR #2990)
- deprecated: Dynamic Smooth, Dissolve Rnd, Solid Glitter
- optimised & enhanced loading of default values
- new effect: Distortion Waves (2D)
- 2D support for Ripple effect
- slower minimum speed for Railway effect
- DMX effect mode & segment controls (PR #2891)
- Optimisations for conditional compiles (further reduction of code size)
- better UX with effect sliders (PR #3012)
- enhanced support for ESP32 variants: C3, S2 & S3
- usermod enhancements (PIR, Temperature, Battery (PR #2975), Analog Clock (PR #2993))
- new usermod SHT (PR #2963)
- 2D matrix set up with gaps or irregular panels (breaking change!) (PR #2892)
- palette blending/transitions
- random palette smooth changes
- hex color notations in custom palettes
- allow more virtual buses
- plethora of bugfixes
### WLED release 0.14.0-b1
#### Build 2212222
- Version bump to v0.14.0-b1 "Hoshi"
- Full changelog TBD
- 2D matrix support (including mapping 1D effects to 2D and 2D peek)
- [internal] completely rewritten Segment & WS2812FX handling code
- [internal] ability to add custom effects via usermods
- [internal] set of 2D drawing functions
- transitions on every segment (including ESP8266)
- enhanced old and new 2D effects (metadata: default values)
- custom palettes (up to 10; upload palette0.json, palette1.json, ...)
- custom effect sliders and options, quick filters
- global I2C and SPI GPIO allocation (for usermods)
- usermod settings page enhancements (dropdown & info)
- asynchronous preset loading (and added "pd" JSON API call for direct preset apply)
- new usermod Boblight (PR #2917)
- new usermod PWM Outputs (PR #2912)
- new usermod Audioreactive
- new usermod Word Clock Matrix (PR #2743)
- new usermod Ping Pong Clock (PR #2746)
- new usermod ADS1115 (PR #2752)
- new usermod Analog Clock (PR #2736)
- various usermod enhancements and updates
- allow disabling pull-up resistors on buttons
- SD card support (PR #2877)
- enhanced HTTP API to support custom effect sliders & options (X1, X2, X3, M1, M2, M3)
- multiple UDP sync message retries (PR #2830)
- network debug printer (PR #2870)
- automatic UI PC mode on large displays
- removed support for upgrading from pre-0.10 (EEPROM)
- support for setting GPIO level when LEDs are off (RMT idle level, ESP32 only) (PR #2478)
- Pakistan time-zone (PKT)
- ArtPoll support
- TM1829 LED support
- experimental support for ESP32 S2, S3 and C3
- general improvements and bugfixes
### WLED release 0.13.3
@@ -224,7 +768,7 @@
- Added application level pong websockets reply (#2139)
- Use AsyncTCP 1.0.3 as it mitigates the flickering issue from 0.13.0-b2
- Fixed transition manually updated in preset overriden by field value
- Fixed transition manually updated in preset overridden by field value
#### Build 2108050
@@ -753,7 +1297,7 @@
#### Build 2011040
- Inversed Rain direction (fixes #1147)
- Inverted Rain direction (fixes #1147)
#### Build 2011010
@@ -964,7 +1508,7 @@
- Added module info page to web UI
- Added realtime override functionality to web UI
- Added individial segment power and brightness to web UI
- Added individual segment power and brightness to web UI
- Added feature to one-click select single segment only by tapping segment name
- Removed palette jumping to default if color is changed

View File

@@ -2,6 +2,34 @@
Here are a few suggestions to make it easier for you to contribute!
### Describe your PR
Please add a description of your proposed code changes. It does not need to be an exhaustive essay, however a PR with no description or just a few words might not get accepted, simply because very basic information is missing.
A good description helps us to review and understand your proposed changes. For example, you could say a few words about
* what you try to achieve (new feature, fixing a bug, refactoring, security enhancements, etc.)
* how your code works (short technical summary - focus on important aspects that might not be obvious when reading the code)
* testing you performed, known limitations, open ends you possibly could not solve.
* any areas where you like to get help from an experienced maintainer (yes WLED has become big 😉)
### Target branch for pull requests
Please make all PRs against the `0_15` branch.
### Updating your code
While the PR is open - and under review by maintainers - you may be asked to modify your PR source code.
You can simply update your own branch, and push changes in response to reviewer recommendations.
Github will pick up the changes so your PR stays up-to-date.
> [!CAUTION]
> Do not use "force-push" while your PR is open!
> It has many subtle and unexpected consequences on our github reposistory.
> For example, we regularly lost review comments when the PR author force-pushes code changes. So, pretty please, do not force-push.
You can find a collection of very useful tips and tricks here: https://github.com/Aircoookie/WLED/wiki/How-to-properly-submit-a-PR
### Code style
When in doubt, it is easiest to replicate the code style you find in the files you want to edit :)
@@ -14,7 +42,7 @@ You are all set if you have enabled `Editor: Detect Indentation` in VS Code.
#### Blocks
Whether the opening bracket of e.g. an `if` block is in the same line as the condition or in a separate line is up to your discretion. If there is only one statement, leaving out block braches is acceptable.
Whether the opening bracket of e.g. an `if` block is in the same line as the condition or in a separate line is up to your discretion. If there is only one statement, leaving out block brackets is acceptable.
Good:
```cpp
@@ -23,6 +51,11 @@ if (a == b) {
}
```
```cpp
if (a == b) doStuff(a);
```
Acceptable - however the first variant is usually easier to read:
```cpp
if (a == b)
{
@@ -30,12 +63,9 @@ if (a == b)
}
```
```cpp
if (a == b) doStuff(a);
```
There should always be a space between a keyword and its condition and between the condition and brace.
Within the condition, no space should be between the paranthesis and variables.
Within the condition, no space should be between the parenthesis and variables.
Spaces between variables and operators are up to the authors discretion.
There should be no space between function names and their argument parenthesis.
@@ -73,6 +103,6 @@ Good:
<!-- This is an HTML comment -->
```
There is no set character limit for a comment within a line,
though as a rule of thumb you should wrap your comment if it exceeds the width of your editor window.
There is no hard character limit for a comment within a line,
though as a rule of thumb consider wrapping after 120 characters.
Inline comments are OK if they describe that line only and are not exceedingly wide.

View File

@@ -0,0 +1,717 @@
/* esp8266_waveform imported from platform source code
Modified for WLED to work around a fault in the NMI handling,
which can result in the system locking up and hard WDT crashes.
Imported from https://github.com/esp8266/Arduino/blob/7e0d20e2b9034994f573a236364e0aef17fd66de/cores/esp8266/core_esp8266_waveform_pwm.cpp
*/
/*
esp8266_waveform - General purpose waveform generation and control,
supporting outputs on all pins in parallel.
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
The core idea is to have a programmable waveform generator with a unique
high and low period (defined in microseconds or CPU clock cycles). TIMER1
is set to 1-shot mode and is always loaded with the time until the next
edge of any live waveforms.
Up to one waveform generator per pin supported.
Each waveform generator is synchronized to the ESP clock cycle counter, not
the timer. This allows for removing interrupt jitter and delay as the
counter always increments once per 80MHz clock. Changes to a waveform are
contiguous and only take effect on the next waveform transition,
allowing for smooth transitions.
This replaces older tone(), analogWrite(), and the Servo classes.
Everywhere in the code where "cycles" is used, it means ESP.getCycleCount()
clock cycle count, or an interval measured in CPU clock cycles, but not
TIMER1 cycles (which may be 2 CPU clock cycles @ 160MHz).
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <coredecls.h>
#include "ets_sys.h"
#include "core_esp8266_waveform.h"
#include "user_interface.h"
extern "C" {
// Linker magic
void usePWMFixedNMI() {};
// Maximum delay between IRQs
#define MAXIRQUS (10000)
// Waveform generator can create tones, PWM, and servos
typedef struct {
uint32_t nextServiceCycle; // ESP cycle timer when a transition required
uint32_t expiryCycle; // For time-limited waveform, the cycle when this waveform must stop
uint32_t timeHighCycles; // Actual running waveform period (adjusted using desiredCycles)
uint32_t timeLowCycles; //
uint32_t desiredHighCycles; // Ideal waveform period to drive the error signal
uint32_t desiredLowCycles; //
uint32_t lastEdge; // Cycle when this generator last changed
} Waveform;
class WVFState {
public:
Waveform waveform[17]; // State of all possible pins
uint32_t waveformState = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code
uint32_t waveformEnabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code
// Enable lock-free by only allowing updates to waveformState and waveformEnabled from IRQ service routine
uint32_t waveformToEnable = 0; // Message to the NMI handler to start a waveform on a inactive pin
uint32_t waveformToDisable = 0; // Message to the NMI handler to disable a pin from waveform generation
uint32_t waveformToChange = 0; // Mask of pin to change. One bit set in main app, cleared when effected in the NMI
uint32_t waveformNewHigh = 0;
uint32_t waveformNewLow = 0;
uint32_t (*timer1CB)() = NULL;
// Optimize the NMI inner loop by keeping track of the min and max GPIO that we
// are generating. In the common case (1 PWM) these may be the same pin and
// we can avoid looking at the other pins.
uint16_t startPin = 0;
uint16_t endPin = 0;
};
static WVFState wvfState;
// Ensure everything is read/written to RAM
#define MEMBARRIER() { __asm__ volatile("" ::: "memory"); }
// Non-speed critical bits
#pragma GCC optimize ("Os")
// Interrupt on/off control
static IRAM_ATTR void timer1Interrupt();
static bool timerRunning = false;
static __attribute__((noinline)) void initTimer() {
if (!timerRunning) {
timer1_disable();
ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL);
ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt);
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE);
timerRunning = true;
timer1_write(microsecondsToClockCycles(10));
}
}
static IRAM_ATTR void forceTimerInterrupt() {
if (T1L > microsecondsToClockCycles(10)) {
T1L = microsecondsToClockCycles(10);
}
}
// PWM implementation using special purpose state machine
//
// Keep an ordered list of pins with the delta in cycles between each
// element, with a terminal entry making up the remainder of the PWM
// period. With this method sum(all deltas) == PWM period clock cycles.
//
// At t=0 set all pins high and set the timeout for the 1st edge.
// On interrupt, if we're at the last element reset to t=0 state
// Otherwise, clear that pin down and set delay for next element
// and so forth.
constexpr int maxPWMs = 8;
// PWM machine state
typedef struct PWMState {
uint32_t mask; // Bitmask of active pins
uint32_t cnt; // How many entries
uint32_t idx; // Where the state machine is along the list
uint8_t pin[maxPWMs + 1];
uint32_t delta[maxPWMs + 1];
uint32_t nextServiceCycle; // Clock cycle for next step
struct PWMState *pwmUpdate; // Set by main code, cleared by ISR
} PWMState;
static PWMState pwmState;
static uint32_t _pwmFreq = 1000;
static uint32_t _pwmPeriod = microsecondsToClockCycles(1000000UL) / _pwmFreq;
// If there are no more scheduled activities, shut down Timer 1.
// Otherwise, do nothing.
static IRAM_ATTR void disableIdleTimer() {
if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) {
ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
timer1_disable();
timer1_isr_init();
timerRunning = false;
}
}
// Notify the NMI that a new PWM state is available through the mailbox.
// Wait for mailbox to be emptied (either busy or delay() as needed)
static IRAM_ATTR void _notifyPWM(PWMState *p, bool idle) {
p->pwmUpdate = nullptr;
pwmState.pwmUpdate = p;
MEMBARRIER();
forceTimerInterrupt();
while (pwmState.pwmUpdate) {
if (idle) {
esp_yield();
}
MEMBARRIER();
}
}
static void _addPWMtoList(PWMState &p, int pin, uint32_t val, uint32_t range);
// Called when analogWriteFreq() changed to update the PWM total period
//extern void _setPWMFreq_weak(uint32_t freq) __attribute__((weak));
void _setPWMFreq_weak(uint32_t freq) {
_pwmFreq = freq;
// Convert frequency into clock cycles
uint32_t cc = microsecondsToClockCycles(1000000UL) / freq;
// Simple static adjustment to bring period closer to requested due to overhead
// Empirically determined as a constant PWM delay and a function of the number of PWMs
#if F_CPU == 80000000
cc -= ((microsecondsToClockCycles(pwmState.cnt) * 13) >> 4) + 110;
#else
cc -= ((microsecondsToClockCycles(pwmState.cnt) * 10) >> 4) + 75;
#endif
if (cc == _pwmPeriod) {
return; // No change
}
_pwmPeriod = cc;
if (pwmState.cnt) {
PWMState p; // The working copy since we can't edit the one in use
p.mask = 0;
p.cnt = 0;
for (uint32_t i = 0; i < pwmState.cnt; i++) {
auto pin = pwmState.pin[i];
_addPWMtoList(p, pin, wvfState.waveform[pin].desiredHighCycles, wvfState.waveform[pin].desiredLowCycles);
}
// Update and wait for mailbox to be emptied
initTimer();
_notifyPWM(&p, true);
disableIdleTimer();
}
}
/*
static void _setPWMFreq_bound(uint32_t freq) __attribute__((weakref("_setPWMFreq_weak")));
void _setPWMFreq(uint32_t freq) {
_setPWMFreq_bound(freq);
}
*/
// Helper routine to remove an entry from the state machine
// and clean up any marked-off entries
static void _cleanAndRemovePWM(PWMState *p, int pin) {
uint32_t leftover = 0;
uint32_t in, out;
for (in = 0, out = 0; in < p->cnt; in++) {
if ((p->pin[in] != pin) && (p->mask & (1<<p->pin[in]))) {
p->pin[out] = p->pin[in];
p->delta[out] = p->delta[in] + leftover;
leftover = 0;
out++;
} else {
leftover += p->delta[in];
p->mask &= ~(1<<p->pin[in]);
}
}
p->cnt = out;
// Final pin is never used: p->pin[out] = 0xff;
p->delta[out] = p->delta[in] + leftover;
}
// Disable PWM on a specific pin (i.e. when a digitalWrite or analogWrite(0%/100%))
//extern bool _stopPWM_weak(uint8_t pin) __attribute__((weak));
IRAM_ATTR bool _stopPWM_weak(uint8_t pin) {
if (!((1<<pin) & pwmState.mask)) {
return false; // Pin not actually active
}
PWMState p; // The working copy since we can't edit the one in use
p = pwmState;
// In _stopPWM we just clear the mask but keep everything else
// untouched to save IRAM. The main startPWM will handle cleanup.
p.mask &= ~(1<<pin);
if (!p.mask) {
// If all have been stopped, then turn PWM off completely
p.cnt = 0;
}
// Update and wait for mailbox to be emptied, no delay (could be in ISR)
_notifyPWM(&p, false);
// Possibly shut down the timer completely if we're done
disableIdleTimer();
return true;
}
/*
static bool _stopPWM_bound(uint8_t pin) __attribute__((weakref("_stopPWM_weak")));
IRAM_ATTR bool _stopPWM(uint8_t pin) {
return _stopPWM_bound(pin);
}
*/
static void _addPWMtoList(PWMState &p, int pin, uint32_t val, uint32_t range) {
// Stash the val and range so we can re-evaluate the fraction
// should the user change PWM frequency. This allows us to
// give as great a precision as possible. We know by construction
// that the waveform for this pin will be inactive so we can borrow
// memory from that structure.
wvfState.waveform[pin].desiredHighCycles = val; // Numerator == high
wvfState.waveform[pin].desiredLowCycles = range; // Denominator == low
uint32_t cc = (_pwmPeriod * val) / range;
// Clip to sane values in the case we go from OK to not-OK when adjusting frequencies
if (cc == 0) {
cc = 1;
} else if (cc >= _pwmPeriod) {
cc = _pwmPeriod - 1;
}
if (p.cnt == 0) {
// Starting up from scratch, special case 1st element and PWM period
p.pin[0] = pin;
p.delta[0] = cc;
// Final pin is never used: p.pin[1] = 0xff;
p.delta[1] = _pwmPeriod - cc;
} else {
uint32_t ttl = 0;
uint32_t i;
// Skip along until we're at the spot to insert
for (i=0; (i <= p.cnt) && (ttl + p.delta[i] < cc); i++) {
ttl += p.delta[i];
}
// Shift everything out by one to make space for new edge
for (int32_t j = p.cnt; j >= (int)i; j--) {
p.pin[j + 1] = p.pin[j];
p.delta[j + 1] = p.delta[j];
}
int off = cc - ttl; // The delta from the last edge to the one we're inserting
p.pin[i] = pin;
p.delta[i] = off; // Add the delta to this new pin
p.delta[i + 1] -= off; // And subtract it from the follower to keep sum(deltas) constant
}
p.cnt++;
p.mask |= 1<<pin;
}
// Called by analogWrite(1...99%) to set the PWM duty in clock cycles
//extern bool _setPWM_weak(int pin, uint32_t val, uint32_t range) __attribute__((weak));
bool _setPWM_weak(int pin, uint32_t val, uint32_t range) {
stopWaveform(pin);
PWMState p; // Working copy
p = pwmState;
// Get rid of any entries for this pin
_cleanAndRemovePWM(&p, pin);
// And add it to the list, in order
if (p.cnt >= maxPWMs) {
return false; // No space left
}
// Sanity check for all-on/off
uint32_t cc = (_pwmPeriod * val) / range;
if ((cc == 0) || (cc >= _pwmPeriod)) {
digitalWrite(pin, cc ? HIGH : LOW);
return true;
}
_addPWMtoList(p, pin, val, range);
// Set mailbox and wait for ISR to copy it over
initTimer();
_notifyPWM(&p, true);
disableIdleTimer();
// Potentially recalculate the PWM period if we've added another pin
_setPWMFreq(_pwmFreq);
return true;
}
/*
static bool _setPWM_bound(int pin, uint32_t val, uint32_t range) __attribute__((weakref("_setPWM_weak")));
bool _setPWM(int pin, uint32_t val, uint32_t range) {
return _setPWM_bound(pin, val, range);
}
*/
// Start up a waveform on a pin, or change the current one. Will change to the new
// waveform smoothly on next low->high transition. For immediate change, stopWaveform()
// first, then it will immediately begin.
//extern int startWaveformClockCycles_weak(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles, int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) __attribute__((weak));
int startWaveformClockCycles_weak(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles,
int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) {
(void) alignPhase;
(void) phaseOffsetUS;
(void) autoPwm;
if ((pin > 16) || isFlashInterfacePin(pin) || (timeHighCycles == 0)) {
return false;
}
Waveform *wave = &wvfState.waveform[pin];
wave->expiryCycle = runTimeCycles ? ESP.getCycleCount() + runTimeCycles : 0;
if (runTimeCycles && !wave->expiryCycle) {
wave->expiryCycle = 1; // expiryCycle==0 means no timeout, so avoid setting it
}
_stopPWM(pin); // Make sure there's no PWM live here
uint32_t mask = 1<<pin;
MEMBARRIER();
if (wvfState.waveformEnabled & mask) {
// Make sure no waveform changes are waiting to be applied
while (wvfState.waveformToChange) {
esp_yield(); // Wait for waveform to update
MEMBARRIER();
}
wvfState.waveformNewHigh = timeHighCycles;
wvfState.waveformNewLow = timeLowCycles;
MEMBARRIER();
wvfState.waveformToChange = mask;
// The waveform will be updated some time in the future on the next period for the signal
} else { // if (!(wvfState.waveformEnabled & mask)) {
wave->timeHighCycles = timeHighCycles;
wave->desiredHighCycles = timeHighCycles;
wave->timeLowCycles = timeLowCycles;
wave->desiredLowCycles = timeLowCycles;
wave->lastEdge = 0;
wave->nextServiceCycle = ESP.getCycleCount() + microsecondsToClockCycles(1);
wvfState.waveformToEnable |= mask;
MEMBARRIER();
initTimer();
forceTimerInterrupt();
while (wvfState.waveformToEnable) {
esp_yield(); // Wait for waveform to update
MEMBARRIER();
}
}
return true;
}
/*
static int startWaveformClockCycles_bound(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles, int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) __attribute__((weakref("startWaveformClockCycles_weak")));
int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles, int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) {
return startWaveformClockCycles_bound(pin, timeHighCycles, timeLowCycles, runTimeCycles, alignPhase, phaseOffsetUS, autoPwm);
}
// This version falls-thru to the proper startWaveformClockCycles call and is invariant across waveform generators
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS,
int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) {
return startWaveformClockCycles_bound(pin,
microsecondsToClockCycles(timeHighUS), microsecondsToClockCycles(timeLowUS),
microsecondsToClockCycles(runTimeUS), alignPhase, microsecondsToClockCycles(phaseOffsetUS), autoPwm);
}
*/
// Set a callback. Pass in NULL to stop it
//extern void setTimer1Callback_weak(uint32_t (*fn)()) __attribute__((weak));
void setTimer1Callback_weak(uint32_t (*fn)()) {
wvfState.timer1CB = fn;
if (fn) {
initTimer();
forceTimerInterrupt();
}
disableIdleTimer();
}
/*
static void setTimer1Callback_bound(uint32_t (*fn)()) __attribute__((weakref("setTimer1Callback_weak")));
void setTimer1Callback(uint32_t (*fn)()) {
setTimer1Callback_bound(fn);
}
*/
// Stops a waveform on a pin
//extern int stopWaveform_weak(uint8_t pin) __attribute__((weak));
IRAM_ATTR int stopWaveform_weak(uint8_t pin) {
// Can't possibly need to stop anything if there is no timer active
if (!timerRunning) {
return false;
}
// If user sends in a pin >16 but <32, this will always point to a 0 bit
// If they send >=32, then the shift will result in 0 and it will also return false
uint32_t mask = 1<<pin;
if (wvfState.waveformEnabled & mask) {
wvfState.waveformToDisable = mask;
// Cancel any pending updates for this waveform, too.
if (wvfState.waveformToChange & mask) {
wvfState.waveformToChange = 0;
}
forceTimerInterrupt();
while (wvfState.waveformToDisable) {
MEMBARRIER(); // If it wasn't written yet, it has to be by now
/* no-op */ // Can't delay() since stopWaveform may be called from an IRQ
}
}
disableIdleTimer();
return true;
}
/*
static int stopWaveform_bound(uint8_t pin) __attribute__((weakref("stopWaveform_weak")));
IRAM_ATTR int stopWaveform(uint8_t pin) {
return stopWaveform_bound(pin);
}
*/
// Speed critical bits
#pragma GCC optimize ("O2")
// Normally would not want two copies like this, but due to different
// optimization levels the inline attribute gets lost if we try the
// other version.
static inline IRAM_ATTR uint32_t GetCycleCountIRQ() {
uint32_t ccount;
__asm__ __volatile__("rsr %0,ccount":"=a"(ccount));
return ccount;
}
// Find the earliest cycle as compared to right now
static inline IRAM_ATTR uint32_t earliest(uint32_t a, uint32_t b) {
uint32_t now = GetCycleCountIRQ();
int32_t da = a - now;
int32_t db = b - now;
return (da < db) ? a : b;
}
// ----- @willmmiles begin patch -----
// NMI crash workaround
// Sometimes the NMI fails to return, stalling the CPU. When this happens,
// the next NMI gets a return address /inside the NMI handler function/.
// We work around this by caching the last NMI return address, and restoring
// the epc3 and eps3 registers to the previous values if the observed epc3
// happens to be pointing to the _NMILevelVector function.
extern void _NMILevelVector();
extern void _UserExceptionVector_1(); // the next function after _NMILevelVector
static inline IRAM_ATTR void nmiCrashWorkaround() {
static uintptr_t epc3_backup, eps3_backup;
uintptr_t epc3, eps3;
__asm__ __volatile__("rsr %0,epc3; rsr %1,eps3":"=a"(epc3),"=a" (eps3));
if ((epc3 < (uintptr_t) &_NMILevelVector) || (epc3 >= (uintptr_t) &_UserExceptionVector_1)) {
// Address is good; save backup
epc3_backup = epc3;
eps3_backup = eps3;
} else {
// Address is inside the NMI handler -- restore from backup
__asm__ __volatile__("wsr %0,epc3; wsr %1,eps3"::"a"(epc3_backup),"a"(eps3_backup));
}
}
// ----- @willmmiles end patch -----
// The SDK and hardware take some time to actually get to our NMI code, so
// decrement the next IRQ's timer value by a bit so we can actually catch the
// real CPU cycle counter we want for the waveforms.
// The SDK also sometimes is running at a different speed the the Arduino core
// so the ESP cycle counter is actually running at a variable speed.
// adjust(x) takes care of adjusting a delta clock cycle amount accordingly.
#if F_CPU == 80000000
#define DELTAIRQ (microsecondsToClockCycles(9)/4)
#define adjust(x) ((x) << (turbo ? 1 : 0))
#else
#define DELTAIRQ (microsecondsToClockCycles(9)/8)
#define adjust(x) ((x) >> 0)
#endif
// When the time to the next edge is greater than this, RTI and set another IRQ to minimize CPU usage
#define MINIRQTIME microsecondsToClockCycles(6)
static IRAM_ATTR void timer1Interrupt() {
// ----- @willmmiles begin patch -----
nmiCrashWorkaround();
// ----- @willmmiles end patch -----
// Flag if the core is at 160 MHz, for use by adjust()
bool turbo = (*(uint32_t*)0x3FF00014) & 1 ? true : false;
uint32_t nextEventCycle = GetCycleCountIRQ() + microsecondsToClockCycles(MAXIRQUS);
uint32_t timeoutCycle = GetCycleCountIRQ() + microsecondsToClockCycles(14);
if (wvfState.waveformToEnable || wvfState.waveformToDisable) {
// Handle enable/disable requests from main app
wvfState.waveformEnabled = (wvfState.waveformEnabled & ~wvfState.waveformToDisable) | wvfState.waveformToEnable; // Set the requested waveforms on/off
wvfState.waveformState &= ~wvfState.waveformToEnable; // And clear the state of any just started
wvfState.waveformToEnable = 0;
wvfState.waveformToDisable = 0;
// No mem barrier. Globals must be written to RAM on ISR exit.
// Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t)
wvfState.startPin = __builtin_ffs(wvfState.waveformEnabled) - 1;
// Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one)
wvfState.endPin = 32 - __builtin_clz(wvfState.waveformEnabled);
} else if (!pwmState.cnt && pwmState.pwmUpdate) {
// Start up the PWM generator by copying from the mailbox
pwmState.cnt = 1;
pwmState.idx = 1; // Ensure copy this cycle, cause it to start at t=0
pwmState.nextServiceCycle = GetCycleCountIRQ(); // Do it this loop!
// No need for mem barrier here. Global must be written by IRQ exit
}
bool done = false;
if (wvfState.waveformEnabled || pwmState.cnt) {
do {
nextEventCycle = GetCycleCountIRQ() + microsecondsToClockCycles(MAXIRQUS);
// PWM state machine implementation
if (pwmState.cnt) {
int32_t cyclesToGo;
do {
cyclesToGo = pwmState.nextServiceCycle - GetCycleCountIRQ();
if (cyclesToGo < 0) {
if (pwmState.idx == pwmState.cnt) { // Start of pulses, possibly copy new
if (pwmState.pwmUpdate) {
// Do the memory copy from temp to global and clear mailbox
pwmState = *(PWMState*)pwmState.pwmUpdate;
}
GPOS = pwmState.mask; // Set all active pins high
if (pwmState.mask & (1<<16)) {
GP16O = 1;
}
pwmState.idx = 0;
} else {
do {
// Drop the pin at this edge
if (pwmState.mask & (1<<pwmState.pin[pwmState.idx])) {
GPOC = 1<<pwmState.pin[pwmState.idx];
if (pwmState.pin[pwmState.idx] == 16) {
GP16O = 0;
}
}
pwmState.idx++;
// Any other pins at this same PWM value will have delta==0, drop them too.
} while (pwmState.delta[pwmState.idx] == 0);
}
// Preserve duty cycle over PWM period by using now+xxx instead of += delta
cyclesToGo = adjust(pwmState.delta[pwmState.idx]);
pwmState.nextServiceCycle = GetCycleCountIRQ() + cyclesToGo;
}
nextEventCycle = earliest(nextEventCycle, pwmState.nextServiceCycle);
} while (pwmState.cnt && (cyclesToGo < 100));
}
for (auto i = wvfState.startPin; i <= wvfState.endPin; i++) {
uint32_t mask = 1<<i;
// If it's not on, ignore!
if (!(wvfState.waveformEnabled & mask)) {
continue;
}
Waveform *wave = &wvfState.waveform[i];
uint32_t now = GetCycleCountIRQ();
// Disable any waveforms that are done
if (wave->expiryCycle) {
int32_t expiryToGo = wave->expiryCycle - now;
if (expiryToGo < 0) {
// Done, remove!
if (i == 16) {
GP16O = 0;
}
GPOC = mask;
wvfState.waveformEnabled &= ~mask;
continue;
}
}
// Check for toggles
int32_t cyclesToGo = wave->nextServiceCycle - now;
if (cyclesToGo < 0) {
uint32_t nextEdgeCycles;
uint32_t desired = 0;
uint32_t *timeToUpdate;
wvfState.waveformState ^= mask;
if (wvfState.waveformState & mask) {
if (i == 16) {
GP16O = 1;
}
GPOS = mask;
if (wvfState.waveformToChange & mask) {
// Copy over next full-cycle timings
wave->timeHighCycles = wvfState.waveformNewHigh;
wave->desiredHighCycles = wvfState.waveformNewHigh;
wave->timeLowCycles = wvfState.waveformNewLow;
wave->desiredLowCycles = wvfState.waveformNewLow;
wave->lastEdge = 0;
wvfState.waveformToChange = 0;
}
if (wave->lastEdge) {
desired = wave->desiredLowCycles;
timeToUpdate = &wave->timeLowCycles;
}
nextEdgeCycles = wave->timeHighCycles;
} else {
if (i == 16) {
GP16O = 0;
}
GPOC = mask;
desired = wave->desiredHighCycles;
timeToUpdate = &wave->timeHighCycles;
nextEdgeCycles = wave->timeLowCycles;
}
if (desired) {
desired = adjust(desired);
int32_t err = desired - (now - wave->lastEdge);
if (abs(err) < desired) { // If we've lost > the entire phase, ignore this error signal
err /= 2;
*timeToUpdate += err;
}
}
nextEdgeCycles = adjust(nextEdgeCycles);
wave->nextServiceCycle = now + nextEdgeCycles;
wave->lastEdge = now;
}
nextEventCycle = earliest(nextEventCycle, wave->nextServiceCycle);
}
// Exit the loop if we've hit the fixed runtime limit or the next event is known to be after that timeout would occur
uint32_t now = GetCycleCountIRQ();
int32_t cycleDeltaNextEvent = nextEventCycle - now;
int32_t cyclesLeftTimeout = timeoutCycle - now;
done = (cycleDeltaNextEvent > MINIRQTIME) || (cyclesLeftTimeout < 0);
} while (!done);
} // if (wvfState.waveformEnabled)
if (wvfState.timer1CB) {
nextEventCycle = earliest(nextEventCycle, GetCycleCountIRQ() + wvfState.timer1CB());
}
int32_t nextEventCycles = nextEventCycle - GetCycleCountIRQ();
if (nextEventCycles < MINIRQTIME) {
nextEventCycles = MINIRQTIME;
}
nextEventCycles -= DELTAIRQ;
// Do it here instead of global function to save time and because we know it's edge-IRQ
T1L = nextEventCycles >> (turbo ? 1 : 0);
}
};

2925
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "wled",
"version": "0.14.0-b1",
"version": "0.15.0-b5",
"description": "Tools for WLED project",
"main": "tools/cdata.js",
"directories": {
@@ -9,6 +9,7 @@
},
"scripts": {
"build": "node tools/cdata.js",
"test": "node --test",
"dev": "nodemon -e js,html,htm,css,png,jpg,gif,ico,js -w tools/ -w wled00/data/ -x node tools/cdata.js"
},
"repository": {
@@ -22,10 +23,9 @@
},
"homepage": "https://github.com/Aircoookie/WLED#readme",
"dependencies": {
"clean-css": "^4.2.3",
"html-minifier-terser": "^5.1.1",
"clean-css": "^5.3.3",
"html-minifier-terser": "^7.2.0",
"inliner": "^1.13.1",
"nodemon": "^2.0.4",
"zlib": "^1.0.5"
"nodemon": "^3.0.2"
}
}

3
pio-scripts/build_ui.py Normal file
View File

@@ -0,0 +1,3 @@
Import('env')
env.Execute("npm run build")

View File

@@ -1,9 +1,24 @@
# Little convenience script to get an object dump
# You may add "-S" to the objdump commandline (i.e. replace "-D -C " with "-d -S -C ")
# to get source code intermixed with disassembly (SLOW !)
Import('env')
def obj_dump_after_elf(source, target, env):
platform = env.PioPlatform()
board = env.BoardConfig()
mcu = board.get("build.mcu", "esp32")
print("Create firmware.asm")
env.Execute("xtensa-lx106-elf-objdump "+ "-D " + str(target[0]) + " > "+ "${PROGNAME}.asm")
if mcu == "esp8266":
env.Execute("xtensa-lx106-elf-objdump "+ "-D -C " + str(target[0]) + " > "+ "$BUILD_DIR/${PROGNAME}.asm")
if mcu == "esp32":
env.Execute("xtensa-esp32-elf-objdump "+ "-D -C " + str(target[0]) + " > "+ "$BUILD_DIR/${PROGNAME}.asm")
if mcu == "esp32s2":
env.Execute("xtensa-esp32s2-elf-objdump "+ "-D -C " + str(target[0]) + " > "+ "$BUILD_DIR/${PROGNAME}.asm")
if mcu == "esp32s3":
env.Execute("xtensa-esp32s3-elf-objdump "+ "-D -C " + str(target[0]) + " > "+ "$BUILD_DIR/${PROGNAME}.asm")
if mcu == "esp32c3":
env.Execute("riscv32-esp-elf-objdump "+ "-D -C " + str(target[0]) + " > "+ "$BUILD_DIR/${PROGNAME}.asm")
env.AddPostAction("$BUILD_DIR/${PROGNAME}.elf", [obj_dump_after_elf])

View File

@@ -4,6 +4,7 @@ import shutil
import gzip
OUTPUT_DIR = "build_output{}".format(os.path.sep)
#OUTPUT_DIR = os.path.join("build_output")
def _get_cpp_define_value(env, define):
define_list = [item[-1] for item in env["CPPDEFINES"] if item[0] == define]
@@ -13,57 +14,52 @@ def _get_cpp_define_value(env, define):
return None
def _create_dirs(dirs=["firmware", "map"]):
# check if output directories exist and create if necessary
if not os.path.isdir(OUTPUT_DIR):
os.mkdir(OUTPUT_DIR)
def _create_dirs(dirs=["map", "release", "firmware"]):
for d in dirs:
if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)):
os.mkdir("{}{}".format(OUTPUT_DIR, d))
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:
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"
print(f"Copying {source} to {release_file}")
shutil.copy(source, release_file)
bin_gzip(release_file, release_gz_file)
else:
variant = env["PIOENV"]
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
print(f"Copying {source} to {bin_file}")
shutil.copy(source, bin_file)
def bin_rename_copy(source, target, env):
_create_dirs()
variant = env["PIOENV"]
builddir = os.path.join(env["PROJECT_BUILD_DIR"], variant)
source_map = os.path.join(builddir, env["PROGNAME"] + ".map")
# create string with location and file names based on variant
map_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant)
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
if release_name:
_create_dirs(["release"])
version = _get_cpp_define_value(env, "WLED_VERSION")
release_file = "{}release{}WLED_{}_{}.bin".format(OUTPUT_DIR, os.path.sep, version, release_name)
shutil.copy(str(target[0]), release_file)
# check if new target files exist and remove if necessary
for f in [map_file, bin_file]:
if os.path.isfile(f):
os.remove(f)
# copy firmware.bin to firmware/<variant>.bin
shutil.copy(str(target[0]), bin_file)
create_release(str(target[0]))
# copy firmware.map to map/<variant>.map
if os.path.isfile("firmware.map"):
shutil.move("firmware.map", map_file)
print("Found linker mapfile firmware.map")
shutil.copy("firmware.map", map_file)
if os.path.isfile(source_map):
print(f"Found linker mapfile {source_map}")
shutil.copy(source_map, map_file)
def bin_gzip(source, target, env):
_create_dirs()
variant = env["PIOENV"]
# create string with location and file names based on variant
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
gzip_file = "{}firmware{}{}.bin.gz".format(OUTPUT_DIR, os.path.sep, variant)
# check if new target files exist and remove if necessary
if os.path.isfile(gzip_file): os.remove(gzip_file)
# write gzip firmware file
with open(bin_file,"rb") as fp:
with gzip.open(gzip_file, "wb", compresslevel = 9) as f:
def bin_gzip(source, target):
# only create gzip for esp8266
if not env["PIOPLATFORM"] == "espressif8266":
return
print(f"Creating gzip file {target} from {source}")
with open(source,"rb") as fp:
with gzip.open(target, "wb", compresslevel = 9) as f:
shutil.copyfileobj(fp, f)
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_rename_copy, bin_gzip])
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", bin_rename_copy)

View File

@@ -9,33 +9,8 @@
# (use `platformio_override.ini` when building for your own board; see `platformio_override.ini.sample` for an example)
# ------------------------------------------------------------------------------
# Release / CI binaries
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola, esp32c3, esp32s3dev_8MB
# Build everything
; default_envs = esp32dev, esp8285_4CH_MagicHome, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
# Single binaries (uncomment your board)
; default_envs = elekstube_ips
; default_envs = nodemcuv2
; default_envs = esp8266_2m
; default_envs = esp01_1m_full
; default_envs = esp07
; default_envs = d1_mini
; default_envs = heltec_wifi_kit_8
; default_envs = h803wf
; default_envs = d1_mini_debug
; default_envs = d1_mini_ota
; default_envs = esp32dev
; default_envs = esp8285_4CH_MagicHome
; default_envs = esp8285_H801
; default_envs = d1_mini_5CH_Shojo_PCB
; default_envs = wemos_shield_esp32
; default_envs = m5atom
; default_envs = esp32_eth
; default_envs = esp32dev_qio80
; default_envs = esp32_eth_ota1mapp
; default_envs = esp32s2_saola
# CI/release binaries
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover
src_dir = ./wled00
data_dir = ./wled00/data
@@ -54,27 +29,39 @@ extra_configs =
arduino_core_2_6_3 = espressif8266@2.3.3
arduino_core_2_7_4 = espressif8266@2.6.2
arduino_core_3_0_0 = espressif8266@3.0.0
arduino_core_3_2_0 = espressif8266@3.2.0
arduino_core_3_0_2 = espressif8266@3.2.0
arduino_core_3_1_0 = espressif8266@4.1.0
arduino_core_3_1_2 = espressif8266@4.2.1
# Development platforms
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
# Platform to use for ESP8266
platform_wled_default = ${common.arduino_core_3_2_0}
platform_wled_default = ${common.arduino_core_3_1_2}
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
platformio/toolchain-xtensa @ ~2.40802.200502
platformio/tool-esptool @ ~1.413.0
platformio/tool-esptoolpy @ ~1.30000.0
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
platform_packages = platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platformio/tool-esptool #@ ~1.413.0
platformio/tool-esptoolpy #@ ~1.30000.0
## previous platform for 8266, in case of problems with the new one
## you'll need makuna/NeoPixelBus@ 2.6.9 for arduino_core_3_0_2, which does not support Ucs890x
;; platform_wled_default = ${common.arduino_core_3_0_2}
;; platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
;; platformio/toolchain-xtensa @ ~2.40802.200502
;; platformio/tool-esptool @ ~1.413.0
;; platformio/tool-esptoolpy @ ~1.30000.0
# ------------------------------------------------------------------------------
# FLAGS: DEBUG
#
# esp8266 : see https://docs.platformio.org/en/latest/platforms/espressif8266.html#debug-level
# esp32 : see https://docs.platformio.org/en/latest/platforms/espressif32.html#debug-level
# ------------------------------------------------------------------------------
debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM
#if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h"
#-DDEBUG_ESP_CORE is not working right now
debug_flags = -D DEBUG=1 -D WLED_DEBUG_ALL ;; or -D WLED_DEBUG -DWLED_DEBUG_FS -DWLED_DEBUG_FX -DWLED_DEBUG_BUS -DWLED_DEBUG_PINMANAGER -DWLED_DEBUG_USERMODS -DWLED_DEBUG_MATH
-DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM ;; for esp8266
# if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h"
# -DDEBUG_ESP_CORE is not working right now
# ------------------------------------------------------------------------------
# FLAGS: ldscript (available ldscripts at https://github.com/esp8266/Arduino/tree/master/tools/sdk/ld)
@@ -104,6 +91,7 @@ build_flags =
-DBEARSSL_SSL_BASIC
-D CORE_DEBUG_LEVEL=0
-D NDEBUG
-Wno-attributes ;; silence warnings about unknown attribute 'maybe_unused' in NeoPixelBus
#build_flags for the IRremoteESP8266 library (enabled decoders have to appear here)
-D _IR_ENABLE_DEFAULT_=false
-D DECODE_HASH=true
@@ -111,17 +99,10 @@ build_flags =
-D DECODE_SONY=true
-D DECODE_SAMSUNG=true
-D DECODE_LG=true
; -Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library
-DWLED_USE_MY_CONFIG
; -D USERMOD_SENSORSTOMQTT
#For ADS1115 sensor uncomment following
; -D USERMOD_ADS1115
build_unflags =
build_flags_esp8266 = ${common.build_flags} ${esp8266.build_flags}
build_flags_esp32 = ${common.build_flags} ${esp32.build_flags}
ldscript_1m128k = eagle.flash.1m128.ld
ldscript_2m512k = eagle.flash.2m512.ld
ldscript_2m1m = eagle.flash.2m1m.ld
@@ -133,6 +114,8 @@ extra_scripts =
post:pio-scripts/output_bins.py
post:pio-scripts/strip-floats.py
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/build_ui.py
; post:pio-scripts/obj-dump.py ;; convenience script to create a disassembly dump of the firmware (hardcore debugging)
# ------------------------------------------------------------------------------
# COMMON SETTINGS:
@@ -141,39 +124,54 @@ extra_scripts =
framework = arduino
board_build.flash_mode = dout
monitor_speed = 115200
# slow upload speed (comment this out with a ';' when building for development use)
# slow upload speed but most compatible (use platformio_override.ini to use faster speed)
upload_speed = 115200
# fast upload speed (remove ';' when building for development use)
; upload_speed = 921600
# ------------------------------------------------------------------------------
# LIBRARIES: required dependencies
# Please note that we don't always use the latest version of a library.
#
# The following libraries have been included (and some of them changd) in the source:
# ArduinoJson@5.13.5, Blynk@0.5.4(changed), E131@1.0.0(changed), Time@1.5, Timezone@1.2.1
# The following libraries have been included (and some of them changed) in the source:
# ArduinoJson@5.13.5, E131@1.0.0(changed), Time@1.5, Timezone@1.2.1
# ------------------------------------------------------------------------------
lib_compat_mode = strict
lib_deps =
fastled/FastLED @ 3.5.0
fastled/FastLED @ 3.6.0
IRremoteESP8266 @ 2.8.2
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7
makuna/NeoPixelBus @ 2.8.0
#https://github.com/makuna/NeoPixelBus.git#CoreShaderBeta
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.2.1
# for I2C interface
;Wire
# ESP-NOW library
;gmag11/QuickESPNow @ ~0.7.0
https://github.com/blazoncek/QuickESPNow.git#optional-debug
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
#TFT_eSPI
#For use SSD1306 OLED display uncomment following
#U8g2@~2.28.8
#U8g2@~2.32.10
#For Dallas sensor uncomment following 2 lines
#OneWire@~2.3.5
#milesburton/DallasTemperature@^3.9.0
#For compatible OLED display uncomment following
#olikraus/U8g2 #@ ~2.33.15
#For Dallas sensor uncomment following
#paulstoffregen/OneWire @ ~2.3.8
#For BME280 sensor uncomment following
#BME280@~3.0.0
; adafruit/Adafruit BMP280 Library @ 2.1.0
; adafruit/Adafruit CCS811 Library @ 1.0.4
; adafruit/Adafruit Si7021 Library @ 1.4.0
#BME280 @ ~3.0.0
;adafruit/Adafruit BMP280 Library @ 2.1.0
;adafruit/Adafruit CCS811 Library @ 1.0.4
;adafruit/Adafruit Si7021 Library @ 1.4.0
#For ADS1115 sensor uncomment following
; adafruit/Adafruit BusIO @ 1.13.2
; adafruit/Adafruit ADS1X15 @ 2.4.0
;adafruit/Adafruit BusIO @ 1.13.2
;adafruit/Adafruit ADS1X15 @ 2.4.0
#For MAX1704x Lipo Monitor / Fuel Gauge uncomment following
; https://github.com/adafruit/Adafruit_BusIO @ 1.14.5
; https://github.com/adafruit/Adafruit_MAX1704X @ 1.0.2
#For MPU6050 IMU uncomment follwoing
;electroniccats/MPU6050 @1.0.1
# For -D USERMOD_ANIMARTRIX
# CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms!
;https://github.com/netmindz/animartrix.git#18bf17389e57c69f11bc8d04ebe1d215422c7fb7
# SHT85
;robtillaart/SHT85@~0.3.3
# Audioreactive usermod
;kosme/arduinoFFT @ 2.0.1
extra_scripts = ${scripts_defaults.extra_scripts}
@@ -182,97 +180,157 @@ build_flags =
-DESP8266
-DFP_IN_IROM
;-Wno-deprecated-declarations
;-Wno-register
;-Wno-misleading-indentation
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
;-Wno-register ;; leaves some warnings when compiling C files: command-line option '-Wno-register' is valid for C++/ObjC++ but not for C
;-Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library ;; warning: this can be dangerous
-Wno-misleading-indentation
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
; lwIP 2 - Higher Bandwidth no Features
; -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
; lwIP 1.4 - Higher Bandwidth (Aircoookie has)
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
; VTABLES in Flash
; lwIP 2 - Higher Bandwidth no Features
; -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
; lwIP 1.4 - Higher Bandwidth (Aircoookie has)
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
; VTABLES in Flash
-DVTABLES_IN_FLASH
; restrict to minimal mime-types
; restrict to minimal mime-types
-DMIMETYPE_MINIMAL
; other special-purpose framework flags (see https://docs.platformio.org/en/latest/platforms/espressif8266.html)
; decrease code cache size and increase IRAM to fit all pixel functions
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown
lib_deps =
${env.lib_deps}
lib_deps =
#https://github.com/lorol/LITTLEFS.git
ESPAsyncTCP @ 1.2.2
ESPAsyncUDP
makuna/NeoPixelBus @ 2.6.9
ESP8266PWM
${env.lib_deps}
;; compatibilty flags - same as 0.14.0 which seems to work better on some 8266 boards. Not using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48
build_flags_compat =
-DESP8266
-DFP_IN_IROM
;;-Wno-deprecated-declarations
-Wno-misleading-indentation
;;-Wno-attributes ;; silence warnings about unknown attribute 'maybe_unused' in NeoPixelBus
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
-DVTABLES_IN_FLASH
-DMIMETYPE_MINIMAL
-DWLED_SAVE_IRAM ;; needed to prevent linker error
;; this platform version was used for WLED 0.14.0
platform_compat = espressif8266@4.2.0
platform_packages_compat =
platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platformio/tool-esptool #@ ~1.413.0
platformio/tool-esptoolpy #@ ~1.30000.0
;; experimental - for using older NeoPixelBus 2.7.9
lib_deps_compat =
ESPAsyncTCP @ 1.2.2
ESPAsyncUDP
ESP8266PWM
fastled/FastLED @ 3.6.0
IRremoteESP8266 @ 2.8.2
makuna/NeoPixelBus @ 2.7.9
https://github.com/blazoncek/QuickESPNow.git#optional-debug
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.2.1
[esp32]
#platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip
platform = espressif32@3.5.0
platform_packages = framework-arduinoespressif32 @ https://github.com/Aircoookie/arduino-esp32.git#1.0.6.4
build_flags = -g
-DARDUINO_ARCH_ESP32
#-DCONFIG_LITTLEFS_FOR_IDF_3_2
-D CONFIG_ASYNC_TCP_USE_WDT=0
#use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x
#use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x
-D LOROL_LITTLEFS
; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when builing with arduino-esp32 >=2.0.3
; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
extended_partitions = tools/WLED_ESP32_4MB_700k_FS.csv
big_partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; 1.8MB firmware, 256KB filesystem, coredump support
large_partitions = tools/WLED_ESP32_8MB.csv
extreme_partitions = tools/WLED_ESP32_16MB_9MB_FS.csv
lib_deps =
${env.lib_deps}
https://github.com/lorol/LITTLEFS.git
makuna/NeoPixelBus @ 2.6.9
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
# additional build flags for audioreactive
AR_build_flags = -D USERMOD_AUDIOREACTIVE
AR_lib_deps = kosme/arduinoFFT @ 2.0.1
[esp32_idf_V4]
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
;; very similar to the normal ESP32 flags, but omitting Lorol LittleFS, as littlefs is included in the new framework already.
;;
;; please note that you can NOT update existing ESP32 installs with a "V4" build. Also updating by OTA will not work properly.
;; You need to completely erase your device (esptool erase_flash) first, then install the "V4" build from VSCode+platformio.
platform = espressif32@ ~6.3.2
platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)
build_flags = -g
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
-DARDUINO_ARCH_ESP32 -DESP32
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps =
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
[esp32s2]
;; generic definitions for all ESP32-S2 boards
platform = espressif32@ ~6.3.2
platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32S2
-DCONFIG_IDF_TARGET_ESP32S2
-DCONFIG_IDF_TARGET_ESP32S2=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0
-DCO
-DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 !
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT, ARDUINO_USB_MSC_ON_BOOT, ARDUINO_USB_DFU_ON_BOOT
;; ARDUINO_USB_CDC_ON_BOOT
lib_deps =
${env.lib_deps}
makuna/NeoPixelBus @ 2.6.9
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
[esp32c3]
;; generic definitions for all ESP32-C3 boards
platform = espressif32@ ~6.3.2
platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)
build_flags = -g
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32C3
-DCONFIG_IDF_TARGET_ESP32C3
-DCONFIG_IDF_TARGET_ESP32C3=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DCO
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
lib_deps =
${env.lib_deps}
makuna/NeoPixelBus @ 2.6.9
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
[esp32s3]
;; generic definitions for all ESP32-S3 boards
platform = espressif32@ ~6.3.2
platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)
build_flags = -g
-DESP32
-DARDUINO_ARCH_ESP32
-DARDUINO_ARCH_ESP32S3
-DCONFIG_IDF_TARGET_ESP32S3
-DCONFIG_IDF_TARGET_ESP32S3=1
-D CONFIG_ASYNC_TCP_USE_WDT=0
-DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_DFU_ON_BOOT=0
-DCO
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT, ARDUINO_USB_MSC_ON_BOOT, ARDUINO_USB_DFU_ON_BOOT
;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT
lib_deps =
${env.lib_deps}
;; NeoPixelBus 2.7.1 is the first that has official support for ESP32-S3
makuna/NeoPixelBus @ ~2.7.1
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
${env.lib_deps}
# ------------------------------------------------------------------------------
@@ -285,87 +343,108 @@ 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} -D WLED_RELEASE_NAME=ESP8266 -D WLED_DISABLE_BLYNK #-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
[env:nodemcuv2_compat]
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
;; 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
-D USERMOD_AUDIOREACTIVE
[env:esp8266_2m]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02 -D WLED_DISABLE_BLYNK
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02
lib_deps = ${esp8266.lib_deps}
[env:esp8266_2m_compat]
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
[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
-D USERMOD_AUDIOREACTIVE
[env:esp01_1m_full]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA -D WLED_DISABLE_BLYNK
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}
[env:esp07]
board = esp07
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}
lib_deps = ${esp8266.lib_deps}
[env:esp01_1m_full_compat]
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
[env:d1_mini]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
upload_speed = 921600
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
[env:heltec_wifi_kit_8]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps}
[env:h803wf]
board = d1_mini
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} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[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
-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
[env:esp32dev]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 -D WLED_DISABLE_BLYNK #-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}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
[env:esp32dev_qio80]
[env:esp32dev_8M]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_qio80 -D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32.lib_deps}
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}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.partitions = ${esp32.large_partitions}
; board_build.f_flash = 80000000L
;[env:esp32dev_audioreactive]
;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_audioreactive #-D WLED_DISABLE_BROWNOUT_DET
; ${esp32.AR_build_flags}
;lib_deps = ${esp32.lib_deps}
; ${esp32.AR_lib_deps}
;monitor_filters = esp32_exception_decoder
;board_build.partitions = ${esp32.default_partitions}
;; board_build.f_flash = 80000000L
;; board_build.flash_mode = dio
[env:esp32_eth]
board = esp32-poe
@@ -373,281 +452,130 @@ platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 -D WLED_DISABLE_BLYNK
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}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.default_partitions}
[env:esp32s2_saola]
board = esp32-s2-saola-1
platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.2/platform-tasmota-espressif32-2.0.2.zip
platform_packages =
framework = arduino
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
[env:esp32_wrover]
extends = esp32_idf_V4
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
board = ttgo-t7-v14-mini32
board_build.f_flash = 80000000L
board_build.flash_mode = qio
upload_speed = 460800
board_build.partitions = ${esp32.extended_partitions}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags} #-D WLED_RELEASE_NAME=S2_saola
lib_deps = ${esp32s2.lib_deps}
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}
lib_deps = ${esp32_idf_V4.lib_deps}
${esp32.AR_lib_deps}
[env:esp32c3]
platform = espressif32@5.1.1
[env:esp32c3dev]
extends = esp32c3
platform = ${esp32c3.platform}
platform_packages = ${esp32c3.platform_packages}
framework = arduino
board = esp32-c3-devkitm-1
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
build_flags = ${common.build_flags} ${esp32c3.build_flags} #-D WLED_RELEASE_NAME=ESP32-C3
board_build.partitions = ${esp32.default_partitions}
build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=ESP32-C3
-D WLED_WATCHDOG_TIMEOUT=0
; -DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual USB
-DLOLIN_WIFI_FIX ; seems to work much better with this
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
;-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
upload_speed = 460800
build_unflags = ${common.build_unflags}
lib_deps = ${esp32c3.lib_deps}
[env:esp32s3dev_8MB]
;; ESP32-S3-DevKitC-1 development board, with 8MB FLASH, no PSRAM (flash_mode: qio)
board = esp32-s3-devkitc-1
platform = espressif32@5.1.1
platform_packages =
upload_speed = 921600 ; or 460800
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags}
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
-D ARDUINO_USB_CDC_ON_BOOT=0 -D ARDUINO_USB_MSC_ON_BOOT=0 -D ARDUINO_DFU_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_MSC_ON_BOOT=0 -D ARDUINO_DFU_ON_BOOT=0 ; -D ARDUINO_USB_MODE=0 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
;-D WLED_DEBUG
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = tools/WLED_ESP32_8MB.csv
board_build.f_flash = 80000000L
board_build.flash_mode = qio
; board_build.flash_mode = dio ;; try this if you have problems at startup
monitor_filters = esp32_exception_decoder
[env:esp32s3dev_8MB_PSRAM]
;; ESP32-TinyS3 development board, with 8MB FLASH and 8MB PSRAM (memory_type: qio_opi, qio_qspi, or opi_opi)
;board = um_tinys3 ; -> needs workaround from https://github.com/Aircoookie/WLED/pull/2905#issuecomment-1328049860
;board = esp32s3box ; -> error: 'esp32_adc2gpio' was not declared in this scope
board = esp32-s3-devkitc-1 ; -> compiles, but does not support PSRAM
platform = espressif32 @ ~5.2.0
platform_packages =
[env:esp32s3dev_16MB_opi]
;; ESP32-S3 development board, with 16MB FLASH and >= 8MB PSRAM (memory_type: qio_opi)
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s3.build_flags}
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_MODE=1 -D ARDUINO_USB_MSC_ON_BOOT=0 ; -D ARDUINO_USB_CDC_ON_BOOT=0
; -D WLED_RELEASE_NAME=ESP32-S3_PSRAM
-D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
board_build.partitions = tools/WLED_ESP32_8MB.csv
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.extreme_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
[env:esp32s3dev_8MB_opi]
;; ESP32-S3 development board, with 8MB FLASH and >= 8MB PSRAM (memory_type: qio_opi)
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
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")
-DBOARD_HAS_PSRAM
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.large_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:esp8285_H801]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
[env:esp32s3_4M_qspi]
;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi)
board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM
platform = ${esp32s3.platform}
platform_packages = ${esp32s3.platform_packages}
upload_speed = 921600
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_5CH_Shojo_PCB]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_USE_SHOJO_PCB
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
# DEVELOPMENT BOARDS
# ------------------------------------------------------------------------------
[env:d1_mini_debug]
board = d1_mini
build_type = debug
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} ${common.debug_flags}
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_ota]
board = d1_mini
upload_protocol = espota
# exchange for your WLED IP
upload_port = "10.10.1.27"
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps}
[env:anavi_miracle_controller]
board = d1_mini
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} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2
lib_deps = ${esp8266.lib_deps}
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_4M_qspi
-DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
-DBOARD_HAS_PSRAM
-DLOLIN_WIFI_FIX ; seems to work much better with this
-D WLED_WATCHDOG_TIMEOUT=0
${esp32.AR_build_flags}
lib_deps = ${esp32s3.lib_deps}
${esp32.AR_lib_deps}
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
monitor_filters = esp32_exception_decoder
[env:lolin_s2_mini]
platform = espressif32@5.1.1
platform = ${esp32s2.platform}
platform_packages = ${esp32s2.platform_packages}
board = lolin_s2_mini
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
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=LolinS2
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
-DBOARD_HAS_PSRAM
-D ARDUINO_USB_CDC_ON_BOOT
-D WLED_USE_PSRAM
-DLOLIN_WIFI_FIX ; seems to work much better with this
-D WLED_WATCHDOG_TIMEOUT=0
-D CONFIG_ASYNC_TCP_USE_WDT=0
-D LEDPIN=16
-D BTNPIN=18
-D RLYPIN=9
-D IRPIN=7
-D DATA_PINS=16
-D HW_PIN_SCL=35
-D HW_PIN_SDA=33
-D HW_PIN_CLOCKSPI=7
-D HW_PIN_DATASPI=11
-D HW_PIN_MISOSPI=9
; -D STATUSLED=15
${esp32.AR_build_flags}
lib_deps = ${esp32s2.lib_deps}
# ------------------------------------------------------------------------------
# custom board configurations
# ------------------------------------------------------------------------------
[env:wemos_shield_esp32]
board = esp32dev
platform = espressif32@3.2
upload_speed = 460800
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32}
-D LEDPIN=16
-D RLYPIN=19
-D BTNPIN=17
-D IRPIN=18
-D UWLED_USE_MY_CONFIG
-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
olikraus/U8g2 @ ^2.28.8
https://github.com/blazoncek/arduinoFFT.git
board_build.partitions = ${esp32.default_partitions}
[env:m5atom]
board = esp32dev
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
lib_deps = ${esp32.lib_deps}
platform = espressif32@3.2
board_build.partitions = ${esp32.default_partitions}
[env:sp501e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=1
lib_deps = ${esp8266.lib_deps}
[env:sp511e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3
lib_deps = ${esp8266.lib_deps}
[env:athom7w]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags_esp8266} -D WLED_MAX_CCT_BLEND=0 -D BTNPIN=-1 -D IRPIN=-1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:athom15w]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags_esp8266} -D WLED_USE_IC_CCT -D BTNPIN=-1 -D IRPIN=-1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:MY9291]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA -D USERMOD_MY9291
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
# codm pixel controller board configurations
# codm-controller-0.6 can also be used for the TYWE3S controller
# ------------------------------------------------------------------------------
[env:codm-controller-0.6]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps}
[env:codm-controller-0.6-rev2]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
# EleksTube-IPS
# ------------------------------------------------------------------------------
[env:elekstube_ips]
board = esp32dev
platform = espressif32@3.2
upload_speed = 921600
build_flags = ${common.build_flags_esp32} -D WLED_DISABLE_BROWNOUT_DET -D WLED_DISABLE_INFRARED
-D USERMOD_RTC
-D USERMOD_ELEKSTUBE_IPS
-D LEDPIN=12
-D RLYPIN=27
-D BTNPIN=34
-D WLED_DISABLE_BLYNK
-D DEFAULT_LED_COUNT=6
# Display config
-D ST7789_DRIVER
-D TFT_WIDTH=135
-D TFT_HEIGHT=240
-D CGRAM_OFFSET
-D TFT_SDA_READ
-D TFT_MOSI=23
-D TFT_SCLK=18
-D TFT_DC=25
-D TFT_RST=26
-D SPI_FREQUENCY=40000000
-D USER_SETUP_LOADED
monitor_filters = esp32_exception_decoder
lib_deps =
${esp32.lib_deps}
TFT_eSPI @ ^2.3.70
board_build.partitions = ${esp32.default_partitions}
${esp32.AR_lib_deps}

View File

@@ -1,66 +0,0 @@
# Example PlatformIO Project Configuration Override
# ------------------------------------------------------------------------------
# Copy to platformio_override.ini to activate overrides
# ------------------------------------------------------------------------------
# Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = WLED_tasmota_1M
[env:WLED_tasmota_1M]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
lib_deps = ${esp8266.lib_deps}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
; *********************************************************************
; *** Use custom settings from file my_config.h
-DWLED_USE_MY_CONFIG
; *********************************************************************
;
;
; *** To use the below defines/overrides, copy and paste each onto it's own line just below build_flags in the section above.
;
; disable specific features
; -D WLED_DISABLE_OTA
; -D WLED_DISABLE_ALEXA
; -D WLED_DISABLE_BLYNK
; -D WLED_DISABLE_HUESYNC
; -D WLED_DISABLE_INFRARED
; -D WLED_DISABLE_WEBSOCKETS
; PIN defines - uncomment and change, if needed:
; -D LEDPIN=2
; -D BTNPIN=0
; -D TOUCHPIN=T0
; -D IRPIN=4
; -D RLYPIN=12
; -D RLYMDE=1
; digital LED strip types - uncomment only one ! - this will disable WS281x / SK681x support
; -D USE_APA102
; -D USE_WS2801
; -D USE_LPD8806
; PIN defines for 2 wire LEDs
-D CLKPIN=0
-D DATAPIN=2
; to drive analog LED strips (aka 5050) hardware configuration is no longer necessary
; configure the settings in the UI as follows (hard):
; for the Magic Home LED Controller use PWM pins 5,12,13,15
; for the H801 controller use PINs 15,13,12,14 (W2 = 04)
; for the BW-LT11 controller use PINs 12,4,14,5
;
; set the name of the module - make sure there is a quote-backslash-quote before the name and a backslash-quote-quote after the name
; -D SERVERNAME="\"WLED\""
;
; set the number of LEDs
; -D DEFAULT_LED_COUNT=30
;
; set milliampere limit when using ESP pin to power leds
; -D ABL_MILLIAMPS_DEFAULT=850
;
; enable IR by setting remote type
; -D IRTYPE=0 ;0 Remote disabled | 1 24-key RGB | 2 24-key with CT | 3 40-key blue | 4 40-key RGB | 5 21-key RGB | 6 6-key black | 7 9-key red | 8 JSON remote
;
; set default color order of your led strip
; -D DEFAULT_LED_COLOR_ORDER=COL_ORDER_GRB

View File

@@ -0,0 +1,526 @@
# Example PlatformIO Project Configuration Override
# ------------------------------------------------------------------------------
# Copy to platformio_override.ini to activate overrides
# ------------------------------------------------------------------------------
# Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = WLED_tasmota_1M # define as many as you need
#----------
# SAMPLE
#----------
[env:WLED_generic8266_1M]
extends = env:esp01_1m_full # when you want to extend the existing environment (define only updated options)
; board = esp01_1m # uncomment when ou need different board
; platform = ${common.platform_wled_default} # uncomment and change when you want particular platform
; platform_packages = ${common.platform_packages}
; board_build.ldscript = ${common.ldscript_1m128k}
; upload_speed = 921600 # fast upload speed (remove ';' if your board supports fast upload speed)
# Sample libraries used for various usermods. Uncomment when using particular usermod.
lib_deps = ${esp8266.lib_deps}
; olikraus/U8g2 # @~2.33.15
; paulstoffregen/OneWire@~2.3.8
; adafruit/Adafruit Unified Sensor@^1.1.4
; adafruit/DHT sensor library@^1.4.1
; adafruit/Adafruit BME280 Library@^2.2.2
; Wire
; robtillaart/SHT85@~0.3.3
; ;gmag11/QuickESPNow @ ~0.7.0 # will also load QuickDebug
; https://github.com/blazoncek/QuickESPNow.git#optional-debug ;; exludes debug library
; ${esp32.AR_lib_deps} ;; used for USERMOD_AUDIOREACTIVE
; bitbank2/PNGdec@^1.0.1 ;; used for POV display uncomment following
build_unflags = ${common.build_unflags}
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
;
; disable specific features
; -D WLED_DISABLE_OTA
; -D WLED_DISABLE_ALEXA
; -D WLED_DISABLE_HUESYNC
; -D WLED_DISABLE_LOXONE
; -D WLED_DISABLE_INFRARED
; -D WLED_DISABLE_WEBSOCKETS
; -D WLED_DISABLE_MQTT
; -D WLED_DISABLE_ADALIGHT
; -D WLED_DISABLE_2D
; -D WLED_DISABLE_PXMAGIC
; -D WLED_DISABLE_ESPNOW
; -D WLED_DISABLE_BROWNOUT_DET
;
; enable optional built-in features
; -D WLED_ENABLE_PIXART
; -D WLED_ENABLE_USERMOD_PAGE # if created
; -D WLED_ENABLE_DMX
;
; PIN defines - uncomment and change, if needed:
; -D DATA_PINS=2
; or use this for multiple outputs
; -D DATA_PINS=1,3
; -D BTNPIN=0
; -D IRPIN=4
; -D RLYPIN=12
; -D RLYMDE=1
; -D RLYODRAIN=0
; -D LED_BUILTIN=2 # GPIO of built-in LED
;
; Limit max buses
; -D WLED_MAX_BUSSES=2
; -D WLED_MAX_ANALOG_CHANNELS=3 # only 3 PWM HW pins available
; -D WLED_MAX_DIGITAL_CHANNELS=2 # only 2 HW accelerated pins available
;
; Configure default WiFi
; -D CLIENT_SSID='"MyNetwork"'
; -D CLIENT_PASS='"Netw0rkPassw0rd"'
;
; Configure and use Ethernet
; -D WLED_USE_ETHERNET
; -D WLED_ETH_DEFAULT=5
; do not use pins 5, (16,) 17, 18, 19, 21, 22, 23, 25, 26, 27 for anything but ethernet
; -D PHY_ADDR=0 -D ETH_PHY_POWER=5 -D ETH_PHY_MDC=23 -D ETH_PHY_MDIO=18
; -D ETH_CLK_MODE=ETH_CLOCK_GPIO17_OUT
;
; NTP time configuration
; -D WLED_NTP_ENABLED=true
; -D WLED_TIMEZONE=2
; -D WLED_LAT=48.86
; -D WLED_LON=2.33
;
; Use Watchdog timer with 10s guard
; -D WLED_WATCHDOG_TIMEOUT=10
;
; Create debug build (with remote debug)
; -D WLED_DEBUG_ALL ;; or
; -D WLED_DEBUG
; -D WLED_DEBUG_FS
; -D WLED_DEBUG_FX
; -D WLED_DEBUG_BUS
; -D WLED_DEBUG_PINMANAGER
; -D WLED_DEBUG_USERMODS
; -D WLED_DEBUG_MATH
; -D WLED_DEBUG_HOST='"192.168.0.100"'
; -D WLED_DEBUG_PORT=7868
;
; Use Autosave usermod and set it to do save after 90s
; -D USERMOD_AUTO_SAVE
; -D AUTOSAVE_AFTER_SEC=90
;
; Use AHT10/AHT15/AHT20 usermod
; -D USERMOD_AHT10
;
; Use INA226 usermod
; -D USERMOD_INA226
;
; 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
; -D FLD_PIN_DATASPI=13
; -D FLD_PIN_DC=26
; -D FLD_PIN_CS=15
; -D FLD_PIN_RESET=27
;
; Use Rotary encoder usermod (in conjunction with 4LD)
; -D USERMOD_ROTARY_ENCODER_UI
; -D ENCODER_DT_PIN=5
; -D ENCODER_CLK_PIN=18
; -D ENCODER_SW_PIN=19
;
; Use Dallas DS18B20 temperature sensor usermod and configure it to use GPIO13
; -D USERMOD_DALLASTEMPERATURE
; -D TEMPERATURE_PIN=13
;
; Use Multi Relay usermod and configure it to use 6 relays and appropriate GPIO
; -D USERMOD_MULTI_RELAY
; -D MULTI_RELAY_MAX_RELAYS=6
; -D MULTI_RELAY_PINS=12,23,22,21,24,25
;
; Use PIR sensor usermod and configure it to use GPIO4 and timer of 60s
; -D USERMOD_PIRSWITCH
; -D PIR_SENSOR_PIN=4 # use -1 to disable usermod
; -D PIR_SENSOR_OFF_SEC=60
; -D PIR_SENSOR_MAX_SENSORS=2 # max allowable sensors (uses OR logic for triggering)
;
; Use Audioreactive usermod and configure I2S microphone
; -D USERMOD_AUDIOREACTIVE
; -D AUDIOPIN=-1
; -D DMTYPE=1 # 0-analog/disabled, 1-I2S generic, 2-ES7243, 3-SPH0645, 4-I2S+mclk, 5-I2S PDM
; -D I2S_SDPIN=36
; -D I2S_WSPIN=23
; -D I2S_CKPIN=19
;
; Use PWM fan usermod
; -D USERMOD_PWM_FAN
; -D TACHO_PIN=33
; -D PWM_PIN=32
;
; Use POV Display usermod
; -D USERMOD_POV_DISPLAY
; Use built-in or custom LED as a status indicator (assumes LED is connected to GPIO16)
; -D STATUSLED=16
;
; set the name of the module - make sure there is a quote-backslash-quote before the name and a backslash-quote-quote after the name
; -D SERVERNAME="\"WLED\""
;
; set the number of LEDs
; -D DEFAULT_LED_COUNT=30
; or this for multiple outputs
; -D PIXEL_COUNTS=30,30
;
; set the default LED type
; -D DEFAULT_LED_TYPE=22 # see const.h (TYPE_xxxx)
;
; set milliampere limit when using ESP power pin (or inadequate PSU) to power LEDs
; -D ABL_MILLIAMPS_DEFAULT=850
; -D LED_MILLIAMPS_DEFAULT=55
;
; enable IR by setting remote type
; -D IRTYPE=0 # 0 Remote disabled | 1 24-key RGB | 2 24-key with CT | 3 40-key blue | 4 40-key RGB | 5 21-key RGB | 6 6-key black | 7 9-key red | 8 JSON remote
;
; set default color order of your led strip
; -D DEFAULT_LED_COLOR_ORDER=COL_ORDER_GRB
;
; use PSRAM on classic ESP32 rev.1 (rev.3 or above has no issues)
; -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue # needed only for classic ESP32 rev.1
;
; configure I2C and SPI interface (for various hardware)
; -D I2CSDAPIN=33 # initialise interface
; -D I2CSCLPIN=35 # initialise interface
; -D HW_PIN_SCL=35
; -D HW_PIN_SDA=33
; -D HW_PIN_CLOCKSPI=7
; -D HW_PIN_DATASPI=11
; -D HW_PIN_MISOSPI=9
# ------------------------------------------------------------------------------
# PRE-CONFIGURED DEVELOPMENT BOARDS AND CONTROLLERS
# ------------------------------------------------------------------------------
[env:esp07]
board = esp07
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}
lib_deps = ${esp8266.lib_deps}
[env:d1_mini]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
upload_speed = 921600
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
[env:heltec_wifi_kit_8]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:h803wf]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:esp32dev_qio80]
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_DISABLE_BROWNOUT_DET
lib_deps = ${esp32.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = qio
[env:esp32dev_V4_dio80]
;; experimental ESP32 env using ESP-IDF V4.4.x
;; Warning: this build environment is not stable!!
;; please erase your device before installing.
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_DISABLE_BROWNOUT_DET
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32_idf_V4.default_partitions}
board_build.f_flash = 80000000L
board_build.flash_mode = dio
[env:esp32s2_saola]
board = esp32-s2-saola-1
platform = ${esp32s2.platform}
platform_packages = ${esp32s2.platform_packages}
framework = arduino
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
board_build.flash_mode = qio
upload_speed = 460800
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32s2.build_flags}
;-DLOLIN_WIFI_FIX ;; try this in case Wifi does not work
-DARDUINO_USB_CDC_ON_BOOT=1
lib_deps = ${esp32s2.lib_deps}
[env:esp32s3dev_8MB_PSRAM_qspi]
;; ESP32-TinyS3 development board, with 8MB FLASH and PSRAM (memory_type: qio_qspi)
extends = env:esp32s3dev_8MB_PSRAM_opi
;board = um_tinys3 ; -> needs workaround from https://github.com/Aircoookie/WLED/pull/2905#issuecomment-1328049860
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
board_build.arduino.memory_type = qio_qspi ;; use with PSRAM: 2MB or 4MB
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
[env:esp8285_H801]
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_5CH_Shojo_PCB]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_USE_SHOJO_PCB
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_debug]
board = d1_mini
build_type = debug
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} ${common.debug_flags}
lib_deps = ${esp8266.lib_deps}
[env:d1_mini_ota]
board = d1_mini
upload_protocol = espota
# exchange for your WLED IP
upload_port = "10.10.1.27"
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:anavi_miracle_controller]
board = d1_mini
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=12 -D IRPIN=-1 -D RLYPIN=2
lib_deps = ${esp8266.lib_deps}
[env:esp32c3dev_2MB]
;; for ESP32-C3 boards with 2MB flash (instead of 4MB).
;; this board need a specific partition file. OTA not possible.
extends = esp32c3
platform = ${esp32c3.platform}
platform_packages = ${esp32c3.platform_packages}
board = esp32-c3-devkitm-1
build_flags = ${common.build_flags} ${esp32c3.build_flags}
-D WLED_WATCHDOG_TIMEOUT=0
-D WLED_DISABLE_OTA
; -DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
build_unflags = ${common.build_unflags}
upload_speed = 115200
lib_deps = ${esp32c3.lib_deps}
board_build.partitions = tools/WLED_ESP32_2MB_noOTA.csv
board_build.flash_mode = dio
[env:wemos_shield_esp32]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
upload_speed = 460800
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags}
-D DATA_PINS=16
-D RLYPIN=19
-D BTNPIN=17
-D IRPIN=18
-D UWLED_USE_MY_CONFIG
-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
olikraus/U8g2 @ ^2.28.8
https://github.com/blazoncek/arduinoFFT.git
board_build.partitions = ${esp32.default_partitions}
[env:m5atom]
board = esp32dev
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D DATA_PINS=27 -D BTNPIN=39
lib_deps = ${esp32.lib_deps}
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
board_build.partitions = ${esp32.default_partitions}
[env:sp501e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=3 -D BTNPIN=1
lib_deps = ${esp8266.lib_deps}
[env:sp511e]
board = esp_wroom_02
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_2m512k}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D DATA_PINS=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3
lib_deps = ${esp8266.lib_deps}
[env:Athom_RGBCW] ;7w and 5w(GU10) bulbs
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,13,5
-D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0
lib_deps = ${esp8266.lib_deps}
[env:Athom_15w_RGBCW] ;15w bulb
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,5,13
-D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 -D WLED_USE_IC_CCT
lib_deps = ${esp8266.lib_deps}
[env:Athom_3Pin_Controller] ;small controller with only data
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:Athom_4Pin_Controller] ; With clock and data interface
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=12 -D DATA_PINS=1 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:Athom_5Pin_Controller] ;Analog light strip controller
board = esp8285
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 DATA_PINS=4,12,14,13 -D WLED_DISABLE_INFRARED
lib_deps = ${esp8266.lib_deps}
[env:MY9291]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA -D USERMOD_MY9291
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
# codm pixel controller board configurations
# codm-controller-0_6 can also be used for the TYWE3S controller
# ------------------------------------------------------------------------------
[env:codm-controller-0_6]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_2m512k}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
[env:codm-controller-0_6-rev2]
board = esp_wroom_02
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_4m1m}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------
# EleksTube-IPS
# ------------------------------------------------------------------------------
[env:elekstube_ips]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
upload_speed = 921600
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_DISABLE_BROWNOUT_DET -D WLED_DISABLE_INFRARED
-D USERMOD_RTC
-D USERMOD_ELEKSTUBE_IPS
-D DATA_PINS=12
-D RLYPIN=27
-D BTNPIN=34
-D DEFAULT_LED_COUNT=6
# Display config
-D ST7789_DRIVER
-D TFT_WIDTH=135
-D TFT_HEIGHT=240
-D CGRAM_OFFSET
-D TFT_SDA_READ
-D TFT_MOSI=23
-D TFT_SCLK=18
-D TFT_DC=25
-D TFT_RST=26
-D SPI_FREQUENCY=40000000
-D USER_SETUP_LOADED
monitor_filters = esp32_exception_decoder
lib_deps =
${esp32.lib_deps}
TFT_eSPI @ ^2.3.70
board_build.partitions = ${esp32.default_partitions}

View File

@@ -3,7 +3,7 @@
<a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a>
<a href="https://raw.githubusercontent.com/Aircoookie/WLED/master/LICENSE"><img src="https://img.shields.io/github/license/Aircoookie/wled?color=blue&style=flat-square"></a>
<a href="https://wled.discourse.group"><img src="https://img.shields.io/discourse/topics?colorB=blue&label=forum&server=https%3A%2F%2Fwled.discourse.group%2F&style=flat-square"></a>
<a href="https://discord.gg/KuqP7NE"><img src="https://img.shields.io/discord/473448917040758787.svg?colorB=blue&label=discord&style=flat-square"></a>
<a href="https://discord.gg/QAh7wJHrRM"><img src="https://img.shields.io/discord/473448917040758787.svg?colorB=blue&label=discord&style=flat-square"></a>
<a href="https://kno.wled.ge"><img src="https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square"></a>
<a href="https://github.com/Aircoookie/WLED-App"><img src="https://img.shields.io/badge/app-wled-blue.svg?style=flat-square"></a>
<a href="https://gitpod.io/#https://github.com/Aircoookie/WLED"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?style=flat-square&logo=gitpod"></a>
@@ -26,7 +26,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
- Up to 250 user presets to save and load colors/effects easily, supports cycling through them.
- Presets can be used to automatically execute API calls
- Nightlight function (gradually dims down)
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
- Full OTA software updateability (HTTP + ArduinoOTA), password protectable
- Configurable analog clock (Cronixie, 7-segment and EleksTube IPS clock support via usermods)
- Configurable Auto Brightness limit for safe operation
- Filesystem-based config for easier backup of presets and settings
@@ -34,8 +34,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
## 💡 Supported light control interfaces
- WLED app for [Android](https://play.google.com/store/apps/details?id=com.aircoookie.WLED) and [iOS](https://apps.apple.com/us/app/wled/id1475695033)
- JSON and HTTP request APIs
- MQTT
- Blynk IoT
- MQTT
- E1.31, Art-Net, DDP and TPM2.net
- [diyHue](https://github.com/diyhue/diyHue) (Wled is supported by diyHue, including Hue Sync Entertainment under udp. Thanks to [Gregory Mallios](https://github.com/gmallios))
- [Hyperion](https://github.com/hyperion-project/hyperion.ng)
@@ -67,7 +66,7 @@ Credits [here](https://kno.wled.ge/about/contributors/)!
Join the Discord server to discuss everything about WLED!
<a href="https://discord.gg/KuqP7NE"><img src="https://discordapp.com/api/guilds/473448917040758787/widget.png?style=banner2" width="25%"></a>
<a href="https://discord.gg/QAh7wJHrRM"><img src="https://discordapp.com/api/guilds/473448917040758787/widget.png?style=banner2" width="25%"></a>
Check out the WLED [Discourse forum](https://wled.discourse.group)!

View File

@@ -1,66 +1,62 @@
#
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile
#
aiofiles==0.8.0
aiofiles==22.1.0
# via platformio
ajsonrpc==1.2.0
# via platformio
anyio==3.6.1
anyio==3.6.2
# via starlette
async-timeout==4.0.2
# via zeroconf
bottle==0.12.23
bottle==0.12.25
# via platformio
certifi==2022.12.7
certifi==2023.7.22
# via requests
charset-normalizer==2.1.1
charset-normalizer==3.1.0
# via requests
click==8.1.3
# via
# platformio
# uvicorn
colorama==0.4.5
# via platformio
h11==0.13.0
colorama==0.4.6
# via
# click
# platformio
h11==0.14.0
# via
# uvicorn
# wsproto
idna==3.3
idna==3.7
# via
# anyio
# requests
ifaddr==0.2.0
# via zeroconf
marshmallow==3.17.0
marshmallow==3.19.0
# via platformio
packaging==21.3
packaging==23.1
# via marshmallow
platformio==6.1.4
platformio==6.1.14
# via -r requirements.in
pyelftools==0.29
# via platformio
pyparsing==3.0.9
# via packaging
pyserial==3.5
# via platformio
requests==2.28.1
requests==2.32.0
# via platformio
semantic-version==2.10.0
# via platformio
sniffio==1.2.0
sniffio==1.3.0
# via anyio
starlette==0.20.4
starlette==0.23.1
# via platformio
tabulate==0.8.10
tabulate==0.9.0
# via platformio
urllib3==1.26.11
typing-extensions==4.11.0
# via starlette
urllib3==1.26.19
# via requests
uvicorn==0.18.2
uvicorn==0.20.0
# via platformio
wsproto==1.1.0
# via platformio
zeroconf==0.39.0
wsproto==1.2.0
# via platformio

View File

@@ -1,6 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x180000,
app1, app, ota_1, 0x190000,0x180000,
spiffs, data, spiffs, 0x310000,0xF0000,
app0, app, ota_0, 0x10000, 0x1A0000,
app1, app, ota_1, 0x1B0000,0x1A0000,
spiffs, data, spiffs, 0x350000,0xB0000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x180000 0x1A0000
5 app1 app ota_1 0x190000 0x1B0000 0x180000 0x1A0000
6 spiffs data spiffs 0x310000 0x350000 0xF0000 0xB0000

View File

@@ -0,0 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x300000,
app1, app, ota_1, 0x310000,0x300000,
spiffs, data, spiffs, 0x610000,0x9E0000,
coredump, data, coredump,,64K
# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
1 # Name, Type, SubType, Offset, Size, Flags
2 nvs, data, nvs, 0x9000, 0x5000,
3 otadata, data, ota, 0xe000, 0x2000,
4 app0, app, ota_0, 0x10000, 0x300000,
5 app1, app, ota_1, 0x310000,0x300000,
6 spiffs, data, spiffs, 0x610000,0x9E0000,
7 coredump, data, coredump,,64K
8 # to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage

View File

@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 20K,
otadata, data, ota, 0xe000, 8K,
app0, app, ota_0, 0x10000, 1536K,
spiffs, data, spiffs, 0x190000, 384K,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 20K
3 otadata data ota 0xe000 8K
4 app0 app ota_0 0x10000 1536K
5 spiffs data spiffs 0x190000 384K

View File

@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1D0000,
app1, app, ota_1, 0x1E0000,0x1D0000,
spiffs, data, spiffs, 0x3B0000,0x40000,
coredump, data, coredump,,64K
1 # Name, Type, SubType, Offset, Size, Flags
2 nvs, data, nvs, 0x9000, 0x5000,
3 otadata, data, ota, 0xe000, 0x2000,
4 app0, app, ota_0, 0x10000, 0x1D0000,
5 app1, app, ota_1, 0x1E0000,0x1D0000,
6 spiffs, data, spiffs, 0x3B0000,0x40000,
7 coredump, data, coredump,,64K

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1A0000,
app1, app, ota_1, 0x1B0000,0x1A0000,
spiffs, data, spiffs, 0x350000,0xB0000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x1A0000
5 app1 app ota_1 0x1B0000 0x1A0000
6 spiffs data spiffs 0x350000 0xB0000

View File

@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x200000,
app1, app, ota_1, 0x210000,0x200000,
spiffs, data, spiffs, 0x410000,0x3F0000,
spiffs, data, spiffs, 0x410000,0x3E0000,
coredump, data, coredump,,64K
1 # Name # Name, Type, SubType, Offset, Size, Flags Type SubType Offset Size Flags
3 otadata otadata, data, ota, 0xe000, 0x2000, data ota 0xe000 0x2000
4 app0 app0, app, ota_0, 0x10000, 0x200000, app ota_0 0x10000 0x200000
5 app1 app1, app, ota_1, 0x210000,0x200000, app ota_1 0x210000 0x200000
6 spiffs spiffs, data, spiffs, 0x410000,0x3E0000, data spiffs 0x410000 0x3F0000
7 coredump, data, coredump,,64K

212
tools/cdata-test.js Normal file
View File

@@ -0,0 +1,212 @@
'use strict';
const assert = require('node:assert');
const { describe, it, before, after } = require('node:test');
const fs = require('fs');
const path = require('path');
const child_process = require('child_process');
const util = require('util');
const execPromise = util.promisify(child_process.exec);
process.env.NODE_ENV = 'test'; // Set the environment to testing
const cdata = require('./cdata.js');
describe('Function', () => {
const testFolderPath = path.join(__dirname, 'testFolder');
const oldFilePath = path.join(testFolderPath, 'oldFile.txt');
const newFilePath = path.join(testFolderPath, 'newFile.txt');
// Create a temporary file before the test
before(() => {
// Create test folder
if (!fs.existsSync(testFolderPath)) {
fs.mkdirSync(testFolderPath);
}
// Create an old file
fs.writeFileSync(oldFilePath, 'This is an old file.');
// Modify the 'mtime' to simulate an old file
const oldTime = new Date();
oldTime.setFullYear(oldTime.getFullYear() - 1);
fs.utimesSync(oldFilePath, oldTime, oldTime);
// Create a new file
fs.writeFileSync(newFilePath, 'This is a new file.');
});
// delete the temporary files after the test
after(() => {
fs.rmSync(testFolderPath, { recursive: true });
});
describe('isFileNewerThan', async () => {
it('should return true if the file is newer than the provided time', async () => {
const pastTime = Date.now() - 10000; // 10 seconds ago
assert.strictEqual(cdata.isFileNewerThan(newFilePath, pastTime), true);
});
it('should return false if the file is older than the provided time', async () => {
assert.strictEqual(cdata.isFileNewerThan(oldFilePath, Date.now()), false);
});
it('should throw an exception if the file does not exist', async () => {
assert.throws(() => {
cdata.isFileNewerThan('nonexistent.txt', Date.now());
});
});
});
describe('isAnyFileInFolderNewerThan', async () => {
it('should return true if a file in the folder is newer than the given time', async () => {
const time = fs.statSync(path.join(testFolderPath, 'oldFile.txt')).mtime;
assert.strictEqual(cdata.isAnyFileInFolderNewerThan(testFolderPath, time), true);
});
it('should return false if no files in the folder are newer than the given time', async () => {
assert.strictEqual(cdata.isAnyFileInFolderNewerThan(testFolderPath, new Date()), false);
});
it('should throw an exception if the folder does not exist', async () => {
assert.throws(() => {
cdata.isAnyFileInFolderNewerThan('nonexistent', new Date());
});
});
});
});
describe('Script', () => {
const folderPath = 'wled00';
const dataPath = path.join(folderPath, 'data');
before(() => {
process.env.NODE_ENV = 'production';
// Backup files
fs.cpSync("wled00/data", "wled00Backup", { recursive: true });
fs.cpSync("tools/cdata.js", "cdata.bak.js");
fs.cpSync("package.json", "package.bak.json");
});
after(() => {
// Restore backup
fs.rmSync("wled00/data", { recursive: true });
fs.renameSync("wled00Backup", "wled00/data");
fs.rmSync("tools/cdata.js");
fs.renameSync("cdata.bak.js", "tools/cdata.js");
fs.rmSync("package.json");
fs.renameSync("package.bak.json", "package.json");
});
// delete all html_*.h files
async function deleteBuiltFiles() {
const files = await fs.promises.readdir(folderPath);
await Promise.all(files.map(file => {
if (file.startsWith('html_') && path.extname(file) === '.h') {
return fs.promises.unlink(path.join(folderPath, file));
}
}));
}
// check if html_*.h files were created
async function checkIfBuiltFilesExist() {
const files = await fs.promises.readdir(folderPath);
const htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h');
assert(htmlFiles.length > 0, 'html_*.h files were not created');
}
async function runAndCheckIfBuiltFilesExist() {
await execPromise('node tools/cdata.js');
await checkIfBuiltFilesExist();
}
async function checkIfFileWasNewlyCreated(file) {
const modifiedTime = fs.statSync(file).mtimeMs;
assert(Date.now() - modifiedTime < 500, file + ' was not modified');
}
async function testFileModification(sourceFilePath, resultFile) {
// run cdata.js to ensure html_*.h files are created
await execPromise('node tools/cdata.js');
// modify file
fs.appendFileSync(sourceFilePath, ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
// run script cdata.js again and wait for it to finish
await execPromise('node tools/cdata.js');
await checkIfFileWasNewlyCreated(path.join(folderPath, resultFile));
}
describe('should build if', () => {
it('html_*.h files are missing', async () => {
await deleteBuiltFiles();
await runAndCheckIfBuiltFilesExist();
});
it('only one html_*.h file is missing', async () => {
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// delete a random html_*.h file
let files = await fs.promises.readdir(folderPath);
let htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h');
const randomFile = htmlFiles[Math.floor(Math.random() * htmlFiles.length)];
await fs.promises.unlink(path.join(folderPath, randomFile));
await runAndCheckIfBuiltFilesExist();
});
it('script was executed with -f or --force', async () => {
await execPromise('node tools/cdata.js');
await new Promise(resolve => setTimeout(resolve, 1000));
await execPromise('node tools/cdata.js --force');
await checkIfFileWasNewlyCreated(path.join(folderPath, 'html_ui.h'));
await new Promise(resolve => setTimeout(resolve, 1000));
await execPromise('node tools/cdata.js -f');
await checkIfFileWasNewlyCreated(path.join(folderPath, 'html_ui.h'));
});
it('a file changes', async () => {
await testFileModification(path.join(dataPath, 'index.htm'), 'html_ui.h');
});
it('a inlined file changes', async () => {
await testFileModification(path.join(dataPath, 'index.js'), 'html_ui.h');
});
it('a settings file changes', async () => {
await testFileModification(path.join(dataPath, 'settings_leds.htm'), 'html_ui.h');
});
it('the favicon changes', async () => {
await testFileModification(path.join(dataPath, 'favicon.ico'), 'html_ui.h');
});
it('cdata.js changes', async () => {
await testFileModification('tools/cdata.js', 'html_ui.h');
});
it('package.json changes', async () => {
await testFileModification('package.json', 'html_ui.h');
});
});
describe('should not build if', () => {
it('the files are already built', async () => {
await deleteBuiltFiles();
// run script cdata.js and wait for it to finish
let startTime = Date.now();
await execPromise('node tools/cdata.js');
const firstRunTime = Date.now() - startTime;
// run script cdata.js and wait for it to finish
startTime = Date.now();
await execPromise('node tools/cdata.js');
const secondRunTime = Date.now() - startTime;
// check if second run was faster than the first (must be at least 2x faster)
assert(secondRunTime < firstRunTime / 2, 'html_*.h files were rebuilt');
});
});
});

View File

@@ -2,7 +2,7 @@
* Writes compressed C arrays of data files (web interface)
* How to use it?
*
* 1) Install Node 11+ and npm
* 1) Install Node 20+ and npm
* 2) npm install
* 3) npm run build
*
@@ -15,26 +15,58 @@
* It uses NodeJS packages to inline, minify and GZIP files. See writeHtmlGzipped and writeChunks invocations at the bottom of the page.
*/
const fs = require("fs");
const fs = require("node:fs");
const path = require("path");
const inliner = require("inliner");
const zlib = require("zlib");
const zlib = require("node:zlib");
const CleanCSS = require("clean-css");
const MinifyHTML = require("html-minifier-terser").minify;
const minifyHtml = require("html-minifier-terser").minify;
const packageJson = require("../package.json");
/**
*
// Export functions for testing
module.exports = { isFileNewerThan, isAnyFileInFolderNewerThan };
const output = ["wled00/html_ui.h", "wled00/html_pixart.h", "wled00/html_cpal.h", "wled00/html_pxmagic.h", "wled00/html_settings.h", "wled00/html_other.h"]
// \x1b[34m is blue, \x1b[36m is cyan, \x1b[0m is reset
const wledBanner = `
\t\x1b[34m ## ## ## ###### ######
\t\x1b[34m## ## ## ## ## ## ##
\t\x1b[34m## ## ## ## ###### ## ##
\t\x1b[34m## ## ## ## ## ## ##
\t\x1b[34m ## ## ###### ###### ######
\t\t\x1b[36m build script for web UI
\x1b[0m`;
const singleHeader = `/*
* Binary array for the Web UI.
* gzip is used for smaller size and improved speeds.
*
* Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
* to find out how to easily modify the web UI source!
*/
function hexdump(buffer,isHex=false) {
`;
const multiHeader = `/*
* More web UI HTML source arrays.
* This file is auto generated, please don't make any changes manually.
*
* Instead, see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
* to find out how to easily modify the web UI source!
*/
`;
function hexdump(buffer, isHex = false) {
let lines = [];
for (let i = 0; i < buffer.length; i +=(isHex?32:16)) {
for (let i = 0; i < buffer.length; i += (isHex ? 32 : 16)) {
var block;
let hexArray = [];
if (isHex) {
block = buffer.slice(i, i + 32)
for (let j = 0; j < block.length; j +=2 ) {
hexArray.push("0x" + block.slice(j,j+2))
for (let j = 0; j < block.length; j += 2) {
hexArray.push("0x" + block.slice(j, j + 2))
}
} else {
block = buffer.slice(i, i + 16); // cut buffer into blocks of 16
@@ -51,201 +83,164 @@ function hexdump(buffer,isHex=false) {
return lines.join(",\n");
}
function strReplace(str, search, replacement) {
return str.split(search).join(replacement);
}
function adoptVersionAndRepo(html) {
let repoUrl = packageJson.repository ? packageJson.repository.url : undefined;
if (repoUrl) {
repoUrl = repoUrl.replace(/^git\+/, "");
repoUrl = repoUrl.replace(/\.git$/, "");
// Replace we
html = strReplace(html, "https://github.com/atuline/WLED", repoUrl);
html = strReplace(html, "https://github.com/Aircoookie/WLED", repoUrl);
html = html.replaceAll("https://github.com/atuline/WLED", repoUrl);
html = html.replaceAll("https://github.com/Aircoookie/WLED", repoUrl);
}
let version = packageJson.version;
if (version) {
html = strReplace(html, "##VERSION##", version);
html = html.replaceAll("##VERSION##", version);
}
return html;
}
function filter(str, type) {
str = adoptVersionAndRepo(str);
if (type === undefined) {
async function minify(str, type = "plain") {
const options = {
collapseWhitespace: true,
collapseBooleanAttributes: true,
collapseInlineTagWhitespace: true,
minifyCSS: true,
minifyJS: true,
removeAttributeQuotes: true,
removeComments: true,
sortAttributes: true,
sortClassName: true,
};
if (type == "plain") {
return str;
} else if (type == "css-minify") {
return new CleanCSS({}).minify(str).styles;
} else if (type == "js-minify") {
return MinifyHTML('<script>' + str + '</script>', {
collapseWhitespace: true,
minifyJS: true,
continueOnParseError: false,
removeComments: true,
}).replace(/<[\/]*script>/g,'');
let js = await minifyHtml('<script>' + str + '</script>', options);
return js.replace(/<[\/]*script>/g, '');
} else if (type == "html-minify") {
return MinifyHTML(str, {
collapseWhitespace: true,
maxLineLength: 80,
minifyCSS: true,
minifyJS: true,
continueOnParseError: false,
removeComments: true,
});
} else if (type == "html-minify-ui") {
return MinifyHTML(str, {
collapseWhitespace: true,
conservativeCollapse: true,
maxLineLength: 80,
minifyCSS: true,
minifyJS: true,
continueOnParseError: false,
removeComments: true,
});
} else {
console.warn("Unknown filter: " + type);
return str;
return await minifyHtml(str, options);
}
throw new Error("Unknown filter: " + type);
}
function writeHtmlGzipped(sourceFile, resultFile, page) {
async function writeHtmlGzipped(sourceFile, resultFile, page) {
console.info("Reading " + sourceFile);
new inliner(sourceFile, function (error, html) {
console.info("Inlined " + html.length + " characters");
html = filter(html, "html-minify-ui");
console.info("Minified to " + html.length + " characters");
if (error) {
console.warn(error);
throw error;
}
new inliner(sourceFile, async function (error, html) {
if (error) throw error;
html = adoptVersionAndRepo(html);
zlib.gzip(html, { level: zlib.constants.Z_BEST_COMPRESSION }, function (error, result) {
if (error) {
console.warn(error);
throw error;
}
console.info("Compressed " + result.length + " bytes");
const array = hexdump(result);
const src = `/*
* Binary array for the Web UI.
* gzip is used for smaller size and improved speeds.
*
* Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
* to find out how to easily modify the web UI source!
*/
// Autogenerated from ${sourceFile}, do not edit!!
const uint16_t PAGE_${page}_L = ${result.length};
const uint8_t PAGE_${page}[] PROGMEM = {
${array}
};
`;
console.info("Writing " + resultFile);
fs.writeFileSync(resultFile, src);
});
const originalLength = html.length;
html = await minify(html, "html-minify");
const result = zlib.gzipSync(html, { level: zlib.constants.Z_BEST_COMPRESSION });
console.info("Minified and compressed " + sourceFile + " from " + originalLength + " to " + result.length + " bytes");
const array = hexdump(result);
let src = singleHeader;
src += `const uint16_t PAGE_${page}_L = ${result.length};\n`;
src += `const uint8_t PAGE_${page}[] PROGMEM = {\n${array}\n};\n\n`;
console.info("Writing " + resultFile);
fs.writeFileSync(resultFile, src);
});
}
function specToChunk(srcDir, s) {
if (s.method == "plaintext") {
const buf = fs.readFileSync(srcDir + "/" + s.file);
const str = buf.toString("utf-8");
const chunk = `
// Autogenerated from ${srcDir}/${s.file}, do not edit!!
const char ${s.name}[] PROGMEM = R"${s.prepend || ""}${filter(str, s.filter)}${
s.append || ""
}";
async function specToChunk(srcDir, s) {
const buf = fs.readFileSync(srcDir + "/" + s.file);
let chunk = `\n// Autogenerated from ${srcDir}/${s.file}, do not edit!!\n`
`;
return s.mangle ? s.mangle(chunk) : chunk;
} else if (s.method == "gzip") {
const buf = fs.readFileSync(srcDir + "/" + s.file);
var str = buf.toString('utf-8');
if (s.mangle) str = s.mangle(str);
const zip = zlib.gzipSync(filter(str, s.filter), { level: zlib.constants.Z_BEST_COMPRESSION });
const result = hexdump(zip.toString('hex'), true);
const chunk = `
// Autogenerated from ${srcDir}/${s.file}, do not edit!!
const uint16_t ${s.name}_length = ${zip.length};
const uint8_t ${s.name}[] PROGMEM = {
${result}
};
`;
return chunk;
} else if (s.method == "binary") {
const buf = fs.readFileSync(srcDir + "/" + s.file);
const result = hexdump(buf);
const chunk = `
// Autogenerated from ${srcDir}/${s.file}, do not edit!!
const uint16_t ${s.name}_length = ${result.length};
const uint8_t ${s.name}[] PROGMEM = {
${result}
};
`;
return chunk;
} else {
console.warn("Unknown method: " + s.method);
return undefined;
}
}
function writeChunks(srcDir, specs, resultFile) {
let src = `/*
* More web UI HTML source arrays.
* This file is auto generated, please don't make any changes manually.
* Instead, see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
* to find out how to easily modify the web UI source!
*/
`;
specs.forEach((s) => {
try {
console.info("Reading " + srcDir + "/" + s.file + " as " + s.name);
src += specToChunk(srcDir, s);
} catch (e) {
console.warn(
"Failed " + s.name + " from " + srcDir + "/" + s.file,
e.message.length > 60 ? e.message.substring(0, 60) : e.message
);
if (s.method == "plaintext" || s.method == "gzip") {
let str = buf.toString("utf-8");
str = adoptVersionAndRepo(str);
const originalLength = str.length;
if (s.method == "gzip") {
if (s.mangle) str = s.mangle(str);
const zip = zlib.gzipSync(await minify(str, s.filter), { level: zlib.constants.Z_BEST_COMPRESSION });
console.info("Minified and compressed " + s.file + " from " + originalLength + " to " + zip.length + " bytes");
const result = hexdump(zip);
chunk += `const uint16_t ${s.name}_length = ${zip.length};\n`;
chunk += `const uint8_t ${s.name}[] PROGMEM = {\n${result}\n};\n\n`;
return chunk;
} else {
const minified = await minify(str, s.filter);
console.info("Minified " + s.file + " from " + originalLength + " to " + minified.length + " bytes");
chunk += `const char ${s.name}[] PROGMEM = R"${s.prepend || ""}${minified}${s.append || ""}";\n\n`;
return s.mangle ? s.mangle(chunk) : chunk;
}
});
} else if (s.method == "binary") {
const result = hexdump(buf);
chunk += `const uint16_t ${s.name}_length = ${buf.length};\n`;
chunk += `const uint8_t ${s.name}[] PROGMEM = {\n${result}\n};\n\n`;
return chunk;
}
throw new Error("Unknown method: " + s.method);
}
async function writeChunks(srcDir, specs, resultFile) {
let src = multiHeader;
for (const s of specs) {
console.info("Reading " + srcDir + "/" + s.file + " as " + s.name);
src += await specToChunk(srcDir, s);
}
console.info("Writing " + src.length + " characters into " + resultFile);
fs.writeFileSync(resultFile, src);
}
writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index');
writeHtmlGzipped("wled00/data/simple.htm", "wled00/html_simple.h", 'simple');
/*
writeChunks(
"wled00/data",
[
{
file: "simple.css",
name: "PAGE_simpleCss",
method: "gzip",
filter: "css-minify",
},
{
file: "simple.js",
name: "PAGE_simpleJs",
method: "gzip",
filter: "js-minify",
},
{
file: "simple.htm",
name: "PAGE_simple",
method: "gzip",
filter: "html-minify-ui",
// Check if a file is newer than a given time
function isFileNewerThan(filePath, time) {
const stats = fs.statSync(filePath);
return stats.mtimeMs > time;
}
// Check if any file in a folder (or its subfolders) is newer than a given time
function isAnyFileInFolderNewerThan(folderPath, time) {
const files = fs.readdirSync(folderPath, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(folderPath, file.name);
if (isFileNewerThan(filePath, time)) {
return true;
}
],
"wled00/html_simplex.h"
);
*/
if (file.isDirectory() && isAnyFileInFolderNewerThan(filePath, time)) {
return true;
}
}
return false;
}
// Check if the web UI is already built
function isAlreadyBuilt(webUIPath, packageJsonPath = "package.json") {
let lastBuildTime = Infinity;
for (const file of output) {
try {
lastBuildTime = Math.min(lastBuildTime, fs.statSync(file).mtimeMs);
} catch (e) {
if (e.code !== 'ENOENT') throw e;
console.info("File " + file + " does not exist. Rebuilding...");
return false;
}
}
return !isAnyFileInFolderNewerThan(webUIPath, lastBuildTime) && !isFileNewerThan(packageJsonPath, lastBuildTime) && !isFileNewerThan(__filename, lastBuildTime);
}
// Don't run this script if we're in a test environment
if (process.env.NODE_ENV === 'test') {
return;
}
console.info(wledBanner);
if (isAlreadyBuilt("wled00/data") && process.argv[2] !== '--force' && process.argv[2] !== '-f') {
console.info("Web UI is already built");
return;
}
writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index');
writeHtmlGzipped("wled00/data/pixart/pixart.htm", "wled00/html_pixart.h", 'pixart');
writeHtmlGzipped("wled00/data/cpal/cpal.htm", "wled00/html_cpal.h", 'cpal');
writeHtmlGzipped("wled00/data/pxmagic/pxmagic.htm", "wled00/html_pxmagic.h", 'pxmagic');
writeChunks(
"wled00/data",
[
@@ -256,7 +251,13 @@ writeChunks(
filter: "css-minify",
mangle: (str) =>
str
.replace("%%","%")
.replace("%%", "%")
},
{
file: "common.js",
name: "JS_common",
method: "gzip",
filter: "js-minify",
},
{
file: "settings.htm",
@@ -387,12 +388,6 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
method: "gzip",
filter: "html-minify",
},
{
file: "liveviewws.htm",
name: "PAGE_liveviewws",
method: "gzip",
filter: "html-minify",
},
{
file: "liveviewws2D.htm",
name: "PAGE_liveviewws2D",
@@ -409,16 +404,6 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
file: "favicon.ico",
name: "favicon",
method: "binary",
},
{
file: "iro.js",
name: "iroJs",
method: "gzip"
},
{
file: "rangetouch.js",
name: "rangetouchJs",
method: "gzip"
}
],
"wled00/html_other.h"

37
tools/stress_test.sh Normal file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# Some web server stress tests
#
# Perform a large number of parallel requests, stress testing the web server
# TODO: some kind of performance metrics
# Accepts three command line arguments:
# - first argument - mandatory - IP or hostname of target server
# - second argument - target type (optional)
# - third argument - xfer count (for replicated targets) (optional)
HOST=$1
declare -n TARGET_STR="${2:-JSON_LARGER}_TARGETS"
REPLICATE_COUNT=$(("${3:-10}"))
PARALLEL_MAX=${PARALLEL_MAX:-50}
CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max ${PARALLEL_MAX}"
CURL_PRINT_RESPONSE_ARGS="-w %{http_code}\n"
JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2')
FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi')
# Replicate one target many times
function replicate() {
printf "${1}?%d " $(seq 1 ${REPLICATE_COUNT})
}
read -a JSON_TINY_TARGETS <<< $(replicate "json/nodes")
read -a JSON_SMALL_TARGETS <<< $(replicate "json/info")
read -a JSON_LARGE_TARGETS <<< $(replicate "json/si")
read -a JSON_LARGER_TARGETS <<< $(replicate "json/fxdata")
# Expand target URLS to full arguments for curl
TARGETS=(${TARGET_STR[@]})
#echo "${TARGETS[@]}"
FULL_TGT_OPTIONS=$(printf "http://${HOST}/%s -o /dev/null " "${TARGETS[@]}")
#echo ${FULL_TGT_OPTIONS}
time curl ${CURL_ARGS} ${FULL_TGT_OPTIONS}

46
tools/udp_test.py Normal file
View File

@@ -0,0 +1,46 @@
import numpy as np
import socket
class WledRealtimeClient:
def __init__(self, wled_controller_ip, num_pixels, udp_port=21324, max_pixels_per_packet=126):
self.wled_controller_ip = wled_controller_ip
self.num_pixels = num_pixels
self.udp_port = udp_port
self.max_pixels_per_packet = max_pixels_per_packet
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self._prev_pixels = np.full((3, self.num_pixels), 253, dtype=np.uint8)
self.pixels = np.full((3, self.num_pixels), 1, dtype=np.uint8)
def update(self):
# Truncate values and cast to integer
self.pixels = np.clip(self.pixels, 0, 255).astype(np.uint8)
p = np.copy(self.pixels)
idx = np.where(~np.all(p == self._prev_pixels, axis=0))[0]
num_pixels = len(idx)
n_packets = (num_pixels + self.max_pixels_per_packet - 1) // self.max_pixels_per_packet
idx_split = np.array_split(idx, n_packets)
header = bytes([1, 2]) # WARLS protocol header
for packet_indices in idx_split:
data = bytearray(header)
for i in packet_indices:
data.extend([i, *p[:, i]]) # Index and RGB values
self._sock.sendto(bytes(data), (self.wled_controller_ip, self.udp_port))
self._prev_pixels = np.copy(p)
################################## LED blink test ##################################
if __name__ == "__main__":
WLED_CONTROLLER_IP = "192.168.1.153"
NUM_PIXELS = 255 # Amount of LEDs on your strip
import time
wled = WledRealtimeClient(WLED_CONTROLLER_IP, NUM_PIXELS)
print('Starting LED blink test')
while True:
for i in range(NUM_PIXELS):
wled.pixels[1, i] = 255 if wled.pixels[1, i] == 0 else 0
wled.update()
time.sleep(.01)

View File

@@ -0,0 +1,36 @@
# Usermod AHT10
This Usermod is designed to read a `AHT10`, `AHT15` or `AHT20` sensor and output the following:
- Temperature
- Humidity
Configuration is performed via the Usermod menu. The following settings can be configured in the Usermod Menu:
- I2CAddress: The i2c address in decimal. Set it to either 56 (0x38, the default) or 57 (0x39).
- SensorType, one of:
- 0 - AHT10
- 1 - AHT15
- 2 - AHT20
- CheckInterval: Number of seconds between readings
- Decimals: Number of decimals to put in the output
Dependencies, These must be added under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
- Libraries
- `enjoyneering/AHT10@~1.1.0` (by [enjoyneering](https://registry.platformio.org/libraries/enjoyneering/AHT10))
- `Wire`
## Author
[@LordMike](https://github.com/LordMike)
# Compiling
To enable, compile with `USERMOD_AHT10` defined (e.g. in `platformio_override.ini`)
```ini
[env:aht10_example]
extends = env:esp32dev
build_flags =
${common.build_flags} ${esp32.build_flags}
-D USERMOD_AHT10
; -D USERMOD_AHT10_DEBUG ; -- add a debug status to the info modal
lib_deps =
${esp32.lib_deps}
enjoyneering/AHT10@~1.1.0
```

View File

@@ -0,0 +1,9 @@
[env:aht10_example]
extends = env:esp32dev
build_flags =
${common.build_flags} ${esp32.build_flags}
-D USERMOD_AHT10
; -D USERMOD_AHT10_DEBUG ; -- add a debug status to the info modal
lib_deps =
${esp32.lib_deps}
enjoyneering/AHT10@~1.1.0

View File

@@ -0,0 +1,327 @@
#pragma once
#include "wled.h"
#include <AHT10.h>
#define AHT10_SUCCESS 1
class UsermodAHT10 : public Usermod
{
private:
static const char _name[];
unsigned long _lastLoopCheck = 0;
bool _settingEnabled : 1; // Enable the usermod
bool _mqttPublish : 1; // Publish mqtt values
bool _mqttPublishAlways : 1; // Publish always, regardless if there is a change
bool _mqttHomeAssistant : 1; // Enable Home Assistant docs
bool _initDone : 1; // Initialization is done
// Settings. Some of these are stored in a different format than they're user settings - so we don't have to convert at runtime
uint8_t _i2cAddress = AHT10_ADDRESS_0X38;
ASAIR_I2C_SENSOR _ahtType = AHT10_SENSOR;
uint16_t _checkInterval = 60000; // milliseconds, user settings is in seconds
float _decimalFactor = 100; // a power of 10 factor. 1 would be no change, 10 is one decimal, 100 is two etc. User sees a power of 10 (0, 1, 2, ..)
uint8_t _lastStatus = 0;
float _lastHumidity = 0;
float _lastTemperature = 0;
#ifndef WLED_MQTT_DISABLE
float _lastHumiditySent = 0;
float _lastTemperatureSent = 0;
#endif
AHT10 *_aht = nullptr;
float truncateDecimals(float val)
{
return roundf(val * _decimalFactor) / _decimalFactor;
}
void initializeAht()
{
if (_aht != nullptr)
{
delete _aht;
}
_aht = new AHT10(_i2cAddress, _ahtType);
_lastStatus = 0;
_lastHumidity = 0;
_lastTemperature = 0;
}
~UsermodAHT10()
{
delete _aht;
_aht = nullptr;
}
#ifndef WLED_DISABLE_MQTT
void mqttInitialize()
{
// This is a generic "setup mqtt" function, So we must abort if we're not to do mqtt
if (!WLED_MQTT_CONNECTED || !_mqttPublish || !_mqttHomeAssistant)
return;
char topic[128];
snprintf_P(topic, 127, "%s/temperature", mqttDeviceTopic);
mqttCreateHassSensor(F("Temperature"), topic, F("temperature"), F("°C"));
snprintf_P(topic, 127, "%s/humidity", mqttDeviceTopic);
mqttCreateHassSensor(F("Humidity"), topic, F("humidity"), F("%"));
}
void mqttPublishIfChanged(const __FlashStringHelper *topic, float &lastState, float state, float minChange)
{
// Check if MQTT Connected, otherwise it will crash the 8266
// Only report if the change is larger than the required diff
if (WLED_MQTT_CONNECTED && _mqttPublish && (_mqttPublishAlways || fabsf(lastState - state) > minChange))
{
char subuf[128];
snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, (const char *)topic);
mqtt->publish(subuf, 0, false, String(state).c_str());
lastState = state;
}
}
// Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
void mqttCreateHassSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement)
{
String t = String(F("homeassistant/sensor/")) + mqttClientID + "/" + name + F("/config");
StaticJsonDocument<600> doc;
doc[F("name")] = name;
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
if (unitOfMeasurement != "")
doc[F("unit_of_measurement")] = unitOfMeasurement;
if (deviceClass != "")
doc[F("device_class")] = deviceClass;
doc[F("expire_after")] = 1800;
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F(WLED_BRAND);
device[F("model")] = F(WLED_PRODUCT_NAME);
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
#endif
public:
void setup()
{
initializeAht();
}
void loop()
{
// if usermod is disabled or called during strip updating just exit
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
if (!_settingEnabled || strip.isUpdating())
return;
// do your magic here
unsigned long currentTime = millis();
if (currentTime - _lastLoopCheck < _checkInterval)
return;
_lastLoopCheck = currentTime;
_lastStatus = _aht->readRawData();
if (_lastStatus == AHT10_ERROR)
{
// Perform softReset and retry
DEBUGUM_PRINTLN(F("AHTxx returned error, doing softReset"));
if (!_aht->softReset())
{
DEBUGUM_PRINTLN(F("softReset failed"));
return;
}
_lastStatus = _aht->readRawData();
}
if (_lastStatus == AHT10_SUCCESS)
{
float temperature = truncateDecimals(_aht->readTemperature(AHT10_USE_READ_DATA));
float humidity = truncateDecimals(_aht->readHumidity(AHT10_USE_READ_DATA));
#ifndef WLED_DISABLE_MQTT
// Push to MQTT
// We can avoid reporting if the change is insignificant. The threshold chosen is below the level of accuracy, but way above 0.01 which is the precision of the value provided.
// The AHT10/15/20 has an accuracy of 0.3C in the temperature readings
mqttPublishIfChanged(F("temperature"), _lastTemperatureSent, temperature, 0.1f);
// The AHT10/15/20 has an accuracy in the humidity sensor of 2%
mqttPublishIfChanged(F("humidity"), _lastHumiditySent, humidity, 0.5f);
#endif
// Store
_lastTemperature = temperature;
_lastHumidity = humidity;
}
}
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent)
{
mqttInitialize();
}
#endif
uint16_t getId()
{
return USERMOD_ID_AHT10;
}
void addToJsonInfo(JsonObject &root) override
{
// if "u" object does not exist yet wee need to create it
JsonObject user = root["u"];
if (user.isNull())
user = root.createNestedObject("u");
#ifdef USERMOD_AHT10_DEBUG
JsonArray temp = user.createNestedArray(F("AHT last loop"));
temp.add(_lastLoopCheck);
temp = user.createNestedArray(F("AHT last status"));
temp.add(_lastStatus);
#endif
JsonArray jsonTemp = user.createNestedArray(F("Temperature"));
JsonArray jsonHumidity = user.createNestedArray(F("Humidity"));
if (_lastLoopCheck == 0)
{
// Before first run
jsonTemp.add(F("Not read yet"));
jsonHumidity.add(F("Not read yet"));
return;
}
if (_lastStatus != AHT10_SUCCESS)
{
jsonTemp.add(F("An error occurred"));
jsonHumidity.add(F("An error occurred"));
return;
}
jsonTemp.add(_lastTemperature);
jsonTemp.add(F("°C"));
jsonHumidity.add(_lastHumidity);
jsonHumidity.add(F("%"));
}
void addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[F("Enabled")] = _settingEnabled;
top[F("I2CAddress")] = static_cast<uint8_t>(_i2cAddress);
top[F("SensorType")] = _ahtType;
top[F("CheckInterval")] = _checkInterval / 1000;
top[F("Decimals")] = log10f(_decimalFactor);
#ifndef WLED_DISABLE_MQTT
top[F("MqttPublish")] = _mqttPublish;
top[F("MqttPublishAlways")] = _mqttPublishAlways;
top[F("MqttHomeAssistantDiscovery")] = _mqttHomeAssistant;
#endif
DEBUGUM_PRINTLN(F("AHT10 config saved."));
}
bool readFromConfig(JsonObject &root) override
{
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
if (!configComplete)
return false;
bool tmpBool = false;
configComplete &= getJsonValue(top[F("Enabled")], tmpBool);
if (configComplete)
_settingEnabled = tmpBool;
configComplete &= getJsonValue(top[F("I2CAddress")], _i2cAddress);
configComplete &= getJsonValue(top[F("CheckInterval")], _checkInterval);
if (configComplete)
{
if (1 <= _checkInterval && _checkInterval <= 600)
_checkInterval *= 1000;
else
// Invalid input
_checkInterval = 60000;
}
configComplete &= getJsonValue(top[F("Decimals")], _decimalFactor);
if (configComplete)
{
if (0 <= _decimalFactor && _decimalFactor <= 5)
_decimalFactor = pow10f(_decimalFactor);
else
// Invalid input
_decimalFactor = 100;
}
uint8_t tmpAhtType;
configComplete &= getJsonValue(top[F("SensorType")], tmpAhtType);
if (configComplete)
{
if (0 <= tmpAhtType && tmpAhtType <= 2)
_ahtType = static_cast<ASAIR_I2C_SENSOR>(tmpAhtType);
else
// Invalid input
_ahtType = ASAIR_I2C_SENSOR::AHT10_SENSOR;
}
#ifndef WLED_DISABLE_MQTT
configComplete &= getJsonValue(top[F("MqttPublish")], tmpBool);
if (configComplete)
_mqttPublish = tmpBool;
configComplete &= getJsonValue(top[F("MqttPublishAlways")], tmpBool);
if (configComplete)
_mqttPublishAlways = tmpBool;
configComplete &= getJsonValue(top[F("MqttHomeAssistantDiscovery")], tmpBool);
if (configComplete)
_mqttHomeAssistant = tmpBool;
#endif
if (_initDone)
{
// Reloading config
initializeAht();
#ifndef WLED_DISABLE_MQTT
mqttInitialize();
#endif
}
_initDone = true;
return configComplete;
}
};
const char UsermodAHT10::_name[] PROGMEM = "AHTxx";

View File

@@ -56,7 +56,7 @@ private:
// runtime
bool initDone = false;
uint32_t lastOverlayDraw = 0;
uint32_t lastOverlayDraw = 0;
void validateAndUpdate() {
mainSegment.validateAndUpdate();
@@ -110,9 +110,9 @@ private:
static inline uint32_t qadd32(uint32_t c1, uint32_t c2) {
return RGBW32(
qadd8(R(c1), R(c2)),
qadd8(G(c1), G(c2)),
qadd8(B(c1), B(c2)),
qadd8(R(c1), R(c2)),
qadd8(G(c1), G(c2)),
qadd8(B(c1), B(c2)),
qadd8(W(c1), W(c2))
);
}
@@ -166,7 +166,7 @@ public:
double secondP = second(localTime) / 60.0;
double minuteP = minute(localTime) / 60.0;
double hourP = (hour(localTime) % 12) / 12.0 + minuteP / 12.0;
if (hourMarksEnabled) {
for (int Led = 0; Led <= 55; Led = Led + 5)
{
@@ -174,7 +174,7 @@ public:
setPixelColor(hourmarkled, hourMarkColor);
}
}
if (secondsEnabled) {
int16_t secondLed = adjustToSegment(secondP, secondsSegment);
@@ -203,45 +203,45 @@ public:
void addToConfig(JsonObject& root) override {
validateAndUpdate();
JsonObject top = root.createNestedObject("Analog Clock");
top["Overlay Enabled"] = enabled;
top["First LED (Main Ring)"] = mainSegment.firstLed;
top["Last LED (Main Ring)"] = mainSegment.lastLed;
top["Center/12h LED (Main Ring)"] = mainSegment.centerLed;
top["Hour Marks Enabled"] = hourMarksEnabled;
top["Hour Mark Color (RRGGBB)"] = colorToHexString(hourMarkColor);
top["Hour Color (RRGGBB)"] = colorToHexString(hourColor);
top["Minute Color (RRGGBB)"] = colorToHexString(minuteColor);
top["Show Seconds"] = secondsEnabled;
top["First LED (Seconds Ring)"] = secondsSegment.firstLed;
top["Last LED (Seconds Ring)"] = secondsSegment.lastLed;
top["Center/12h LED (Seconds Ring)"] = secondsSegment.centerLed;
top["Second Color (RRGGBB)"] = colorToHexString(secondColor);
top["Seconds Effect (0-1)"] = secondsEffect;
top["Blend Colors"] = blendColors;
JsonObject top = root.createNestedObject(F("Analog Clock"));
top[F("Overlay Enabled")] = enabled;
top[F("First LED (Main Ring)")] = mainSegment.firstLed;
top[F("Last LED (Main Ring)")] = mainSegment.lastLed;
top[F("Center/12h LED (Main Ring)")] = mainSegment.centerLed;
top[F("Hour Marks Enabled")] = hourMarksEnabled;
top[F("Hour Mark Color (RRGGBB)")] = colorToHexString(hourMarkColor);
top[F("Hour Color (RRGGBB)")] = colorToHexString(hourColor);
top[F("Minute Color (RRGGBB)")] = colorToHexString(minuteColor);
top[F("Show Seconds")] = secondsEnabled;
top[F("First LED (Seconds Ring)")] = secondsSegment.firstLed;
top[F("Last LED (Seconds Ring)")] = secondsSegment.lastLed;
top[F("Center/12h LED (Seconds Ring)")] = secondsSegment.centerLed;
top[F("Second Color (RRGGBB)")] = colorToHexString(secondColor);
top[F("Seconds Effect (0-1)")] = secondsEffect;
top[F("Blend Colors")] = blendColors;
}
bool readFromConfig(JsonObject& root) override {
JsonObject top = root["Analog Clock"];
JsonObject top = root[F("Analog Clock")];
bool configComplete = !top.isNull();
String color;
configComplete &= getJsonValue(top["Overlay Enabled"], enabled, false);
configComplete &= getJsonValue(top["First LED (Main Ring)"], mainSegment.firstLed, 0);
configComplete &= getJsonValue(top["Last LED (Main Ring)"], mainSegment.lastLed, 59);
configComplete &= getJsonValue(top["Center/12h LED (Main Ring)"], mainSegment.centerLed, 0);
configComplete &= getJsonValue(top["Hour marks Enabled"], hourMarksEnabled, false);
configComplete &= getJsonValue(top["Hour mark Color (RRGGBB)"], color, "FF0000") && hexStringToColor(color, hourMarkColor, 0x0000FF);
configComplete &= getJsonValue(top["Hour Color (RRGGBB)"], color, "0000FF") && hexStringToColor(color, hourColor, 0x0000FF);
configComplete &= getJsonValue(top["Minute Color (RRGGBB)"], color, "00FF00") && hexStringToColor(color, minuteColor, 0x00FF00);
configComplete &= getJsonValue(top["Show Seconds"], secondsEnabled, true);
configComplete &= getJsonValue(top["First LED (Seconds Ring)"], secondsSegment.firstLed, 0);
configComplete &= getJsonValue(top["Last LED (Seconds Ring)"], secondsSegment.lastLed, 59);
configComplete &= getJsonValue(top["Center/12h LED (Seconds Ring)"], secondsSegment.centerLed, 0);
configComplete &= getJsonValue(top["Second Color (RRGGBB)"], color, "FF0000") && hexStringToColor(color, secondColor, 0xFF0000);
configComplete &= getJsonValue(top["Seconds Effect (0-1)"], secondsEffect, 0);
configComplete &= getJsonValue(top["Blend Colors"], blendColors, true);
configComplete &= getJsonValue(top[F("Overlay Enabled")], enabled, false);
configComplete &= getJsonValue(top[F("First LED (Main Ring)")], mainSegment.firstLed, 0);
configComplete &= getJsonValue(top[F("Last LED (Main Ring)")], mainSegment.lastLed, 59);
configComplete &= getJsonValue(top[F("Center/12h LED (Main Ring)")], mainSegment.centerLed, 0);
configComplete &= getJsonValue(top[F("Hour Marks Enabled")], hourMarksEnabled, false);
configComplete &= getJsonValue(top[F("Hour Mark Color (RRGGBB)")], color, F("161616")) && hexStringToColor(color, hourMarkColor, 0x161616);
configComplete &= getJsonValue(top[F("Hour Color (RRGGBB)")], color, F("0000FF")) && hexStringToColor(color, hourColor, 0x0000FF);
configComplete &= getJsonValue(top[F("Minute Color (RRGGBB)")], color, F("00FF00")) && hexStringToColor(color, minuteColor, 0x00FF00);
configComplete &= getJsonValue(top[F("Show Seconds")], secondsEnabled, true);
configComplete &= getJsonValue(top[F("First LED (Seconds Ring)")], secondsSegment.firstLed, 0);
configComplete &= getJsonValue(top[F("Last LED (Seconds Ring)")], secondsSegment.lastLed, 59);
configComplete &= getJsonValue(top[F("Center/12h LED (Seconds Ring)")], secondsSegment.centerLed, 0);
configComplete &= getJsonValue(top[F("Second Color (RRGGBB)")], color, F("FF0000")) && hexStringToColor(color, secondColor, 0xFF0000);
configComplete &= getJsonValue(top[F("Seconds Effect (0-1)")], secondsEffect, 0);
configComplete &= getJsonValue(top[F("Blend Colors")], blendColors, true);
if (initDone) {
validateAndUpdate();
@@ -253,4 +253,4 @@ public:
uint16_t getId() override {
return USERMOD_ID_ANALOG_CLOCK;
}
};
};

View File

@@ -25,6 +25,7 @@ class Animated_Staircase : public Usermod {
bool useUSSensorBottom = false; // using PIR or UltraSound sensor?
unsigned int topMaxDist = 50; // default maximum measured distance in cm, top
unsigned int bottomMaxDist = 50; // default maximum measured distance in cm, bottom
bool togglePower = false; // toggle power on/off with staircase on/off
/* runtime variables */
bool initDone = false;
@@ -90,14 +91,17 @@ class Animated_Staircase : public Usermod {
static const char _bottomEcho_pin[];
static const char _topEchoCm[];
static const char _bottomEchoCm[];
static const char _togglePower[];
void publishMqtt(bool bottom, const char* state) {
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED){
char subuf[64];
sprintf_P(subuf, PSTR("%s/motion/%d"), mqttDeviceTopic, (int)bottom);
mqtt->publish(subuf, 0, false, state);
}
#endif
}
void updateSegments() {
@@ -129,7 +133,7 @@ class Animated_Staircase : public Usermod {
* received within this time, an object is detected
* and the function will return true.
*
* The speed of sound is 343 meters per second at 20 degress Celcius.
* The speed of sound is 343 meters per second at 20 degrees Celsius.
* Since the sound has to travel back and forth, the detection
* distance for the sensor in cm is (0.0343 * maxTimeUs) / 2.
*
@@ -174,14 +178,14 @@ class Animated_Staircase : public Usermod {
bottomSensorState = bottomSensorRead; // change previous state
sensorChanged = true;
publishMqtt(true, bottomSensorState ? "on" : "off");
DEBUG_PRINTLN(F("Bottom sensor changed."));
DEBUGUM_PRINTLN(F("Bottom sensor changed."));
}
if (topSensorRead != topSensorState) {
topSensorState = topSensorRead; // change previous state
sensorChanged = true;
publishMqtt(false, topSensorState ? "on" : "off");
DEBUG_PRINTLN(F("Top sensor changed."));
DEBUGUM_PRINTLN(F("Top sensor changed."));
}
// Values read, reset the flags for next API call
@@ -194,11 +198,12 @@ class Animated_Staircase : public Usermod {
if (on) {
lastSensor = topSensorRead;
} else {
if (togglePower && onIndex == offIndex && offMode) toggleOnOff(); // toggle power on if off
// If the bottom sensor triggered, we need to swipe up, ON
swipe = bottomSensorRead;
DEBUG_PRINT(F("ON -> Swipe "));
DEBUG_PRINTLN(swipe ? F("up.") : F("down."));
DEBUGUM_PRINT(F("ON -> Swipe "));
DEBUGUM_PRINTLN(swipe ? F("up.") : F("down."));
if (onIndex == offIndex) {
// Position the indices for a correct on-swipe
@@ -225,8 +230,8 @@ class Animated_Staircase : public Usermod {
swipe = lastSensor;
on = false;
DEBUG_PRINT(F("OFF -> Swipe "));
DEBUG_PRINTLN(swipe ? F("up.") : F("down."));
DEBUGUM_PRINT(F("OFF -> Swipe "));
DEBUGUM_PRINTLN(swipe ? F("up.") : F("down."));
}
}
@@ -247,11 +252,14 @@ class Animated_Staircase : public Usermod {
offIndex = MAX(onIndex, offIndex - 1);
}
}
if (oldOn != onIndex || oldOff != offIndex) updateSegments(); // reduce the number of updates to necessary ones
if (oldOn != onIndex || oldOff != offIndex) {
updateSegments(); // reduce the number of updates to necessary ones
if (togglePower && onIndex == offIndex && !offMode && !on) toggleOnOff(); // toggle power off for all segments off
}
}
}
// send sesnor values to JSON API
// send sensor values to JSON API
void writeSensorsToJson(JsonObject& staircase) {
staircase[F("top-sensor")] = topSensorRead;
staircase[F("bottom-sensor")] = bottomSensorRead;
@@ -265,12 +273,12 @@ class Animated_Staircase : public Usermod {
void enable(bool enable) {
if (enable) {
DEBUG_PRINTLN(F("Animated Staircase enabled."));
DEBUG_PRINT(F("Delay between steps: "));
DEBUG_PRINT(segment_delay_ms);
DEBUG_PRINT(F(" milliseconds.\nStairs switch off after: "));
DEBUG_PRINT(on_time_ms / 1000);
DEBUG_PRINTLN(F(" seconds."));
DEBUGUM_PRINTLN(F("Animated Staircase enabled."));
DEBUGUM_PRINT(F("Delay between steps: "));
DEBUGUM_PRINT(segment_delay_ms);
DEBUGUM_PRINT(F(" milliseconds.\nStairs switch off after: "));
DEBUGUM_PRINT(on_time_ms / 1000);
DEBUGUM_PRINTLN(F(" seconds."));
if (!useUSSensorBottom)
pinMode(bottomPIRorTriggerPin, INPUT_PULLUP);
@@ -289,10 +297,11 @@ class Animated_Staircase : public Usermod {
offIndex = maxSegmentId = strip.getLastActiveSegmentId() + 1;
// shorten the strip transition time to be equal or shorter than segment delay
transitionDelayTemp = transitionDelay = segment_delay_ms;
strip.setTransition(segment_delay_ms/100);
transitionDelay = segment_delay_ms;
strip.setTransition(segment_delay_ms);
strip.trigger();
} else {
if (togglePower && !on && offMode) toggleOnOff(); // toggle power on if off
// Restore segment options
for (int i = 0; i <= strip.getLastActiveSegmentId(); i++) {
Segment &seg = strip.getSegment(i);
@@ -300,9 +309,9 @@ class Animated_Staircase : public Usermod {
seg.setOption(SEG_OPTION_ON, true);
}
strip.trigger(); // force strip update
stateChanged = true; // inform external dvices/UI of change
stateChanged = true; // inform external devices/UI of change
colorUpdated(CALL_MODE_DIRECT_CHANGE);
DEBUG_PRINTLN(F("Animated Staircase disabled."));
DEBUGUM_PRINTLN(F("Animated Staircase disabled."));
}
enabled = enable;
}
@@ -323,7 +332,7 @@ class Animated_Staircase : public Usermod {
};
// NOTE: this *WILL* return TRUE if all the pins are set to -1.
// this is *BY DESIGN*.
if (!pinManager.allocateMultiplePins(pins, 4, PinOwner::UM_AnimatedStaircase)) {
if (!PinManager::allocateMultiplePins(pins, 4, PinOwner::UM_AnimatedStaircase)) {
topPIRorTriggerPin = -1;
topEchoPin = -1;
bottomPIRorTriggerPin = -1;
@@ -345,6 +354,7 @@ class Animated_Staircase : public Usermod {
uint16_t getId() { return USERMOD_ID_ANIMATED_STAIRCASE; }
#ifndef WLED_DISABLE_MQTT
/**
* handling of MQTT message
* topic only contains stripped topic (part after /wled/MAC)
@@ -382,6 +392,7 @@ class Animated_Staircase : public Usermod {
mqtt->subscribe(subuf, 0);
}
}
#endif
void addToJsonState(JsonObject& root) {
JsonObject staircase = root[FPSTR(_name)];
@@ -389,7 +400,7 @@ class Animated_Staircase : public Usermod {
staircase = root.createNestedObject(FPSTR(_name));
}
writeSensorsToJson(staircase);
DEBUG_PRINTLN(F("Staircase sensor state exposed in API."));
DEBUGUM_PRINTLN(F("Staircase sensor state exposed in API."));
}
/*
@@ -409,7 +420,7 @@ class Animated_Staircase : public Usermod {
}
if (en != enabled) enable(en);
readSensorsFromJson(staircase);
DEBUG_PRINTLN(F("Staircase sensor state read from API."));
DEBUGUM_PRINTLN(F("Staircase sensor state read from API."));
}
}
@@ -440,7 +451,8 @@ class Animated_Staircase : public Usermod {
staircase[FPSTR(_bottomEcho_pin)] = useUSSensorBottom ? bottomEchoPin : -1;
staircase[FPSTR(_topEchoCm)] = topMaxDist;
staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist;
DEBUG_PRINTLN(F("Staircase config saved."));
staircase[FPSTR(_togglePower)] = togglePower;
DEBUGUM_PRINTLN(F("Staircase config saved."));
}
/*
@@ -458,8 +470,8 @@ class Animated_Staircase : public Usermod {
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINT(FPSTR(_name));
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
@@ -480,17 +492,19 @@ class Animated_Staircase : public Usermod {
bottomEchoPin = top[FPSTR(_bottomEcho_pin)] | bottomEchoPin;
topMaxDist = top[FPSTR(_topEchoCm)] | topMaxDist;
topMaxDist = min(150,max(30,(int)topMaxDist)); // max distnace ~1.5m (a lag of 9ms may be expected)
topMaxDist = min(150,max(30,(int)topMaxDist)); // max distance ~1.5m (a lag of 9ms may be expected)
bottomMaxDist = top[FPSTR(_bottomEchoCm)] | bottomMaxDist;
bottomMaxDist = min(150,max(30,(int)bottomMaxDist)); // max distance ~1.5m (a lag of 9ms may be expected)
DEBUG_PRINT(FPSTR(_name));
togglePower = top[FPSTR(_togglePower)] | togglePower; // staircase toggles power on/off
DEBUGUM_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
DEBUG_PRINTLN(F(" config loaded."));
DEBUGUM_PRINTLN(F(" config loaded."));
} else {
// changing parameters from settings page
DEBUG_PRINTLN(F(" config (re)loaded."));
DEBUGUM_PRINTLN(F(" config (re)loaded."));
bool changed = false;
if ((oldUseUSSensorTop != useUSSensorTop) ||
(oldUseUSSensorBottom != useUSSensorBottom) ||
@@ -499,15 +513,15 @@ class Animated_Staircase : public Usermod {
(oldBottomAPin != bottomPIRorTriggerPin) ||
(oldBottomBPin != bottomEchoPin)) {
changed = true;
pinManager.deallocatePin(oldTopAPin, PinOwner::UM_AnimatedStaircase);
pinManager.deallocatePin(oldTopBPin, PinOwner::UM_AnimatedStaircase);
pinManager.deallocatePin(oldBottomAPin, PinOwner::UM_AnimatedStaircase);
pinManager.deallocatePin(oldBottomBPin, PinOwner::UM_AnimatedStaircase);
PinManager::deallocatePin(oldTopAPin, PinOwner::UM_AnimatedStaircase);
PinManager::deallocatePin(oldTopBPin, PinOwner::UM_AnimatedStaircase);
PinManager::deallocatePin(oldBottomAPin, PinOwner::UM_AnimatedStaircase);
PinManager::deallocatePin(oldBottomBPin, PinOwner::UM_AnimatedStaircase);
}
if (changed) setup();
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return true;
return !top[FPSTR(_togglePower)].isNull();
}
/*
@@ -547,3 +561,4 @@ const char Animated_Staircase::_bottomPIRorTrigger_pin[] PROGMEM = "bottomPIR
const char Animated_Staircase::_bottomEcho_pin[] PROGMEM = "bottomEcho_pin";
const char Animated_Staircase::_topEchoCm[] PROGMEM = "top-dist-cm";
const char Animated_Staircase::_bottomEchoCm[] PROGMEM = "bottom-dist-cm";
const char Animated_Staircase::_togglePower[] PROGMEM = "toggle-on-off";

View File

@@ -11,14 +11,14 @@ The Animated Staircase can be controlled by the WLED API. Change settings such a
speed, on/off time and distance by sending an HTTP request, see below.
## WLED integration
To include this usermod in your WLED setup, you have to be able to [compile WLED from source](https://github.com/Aircoookie/WLED/wiki/Compiling-WLED).
To include this usermod in your WLED setup, you have to be able to [compile WLED from source](https://kno.wled.ge/advanced/compiling-wled/).
Before compiling, you have to make the following modifications:
Edit `usermods_list.cpp`:
1. Open `wled00/usermods_list.cpp`
2. add `#include "../usermods/Animated_Staircase/Animated_Staircase.h"` to the top of the file
3. add `usermods.add(new Animated_Staircase());` to the end of the `void registerUsermods()` function.
3. add `UsermodManager::add(new Animated_Staircase());` to the end of the `void registerUsermods()` function.
You can configure usermod using the Usermods settings page.
Please enter GPIO pins for PIR or ultrasonic sensors (trigger and echo).
@@ -38,7 +38,7 @@ Maximum distance for ultrasonic sensor can be configured as the time needed for
You _may_ need to use 10k pull-down resistors on the selected PIR pins, depending on the sensor.
## WLED configuration
1. In the WLED UI, confgure a segment for each step. The lowest step of the stairs is the
1. In the WLED UI, configure a segment for each step. The lowest step of the stairs is the
lowest segment id.
2. Save your segments into a preset.
3. Ideally, add the preset in the config > LED setup menu to the "apply
@@ -91,7 +91,7 @@ To enable the usermod again, use `"enabled":true`.
Alternatively you can use _Usermod_ Settings page where you can change other parameters as well.
### Changing animation parameters and detection range of the ultrasonic HC-SR04 sensor
Using _Usermod_ Settings page you can define different usermod parameters, includng sensor pins, delay between segment activation etc.
Using _Usermod_ Settings page you can define different usermod parameters, including sensor pins, delay between segment activation etc.
When an ultrasonic sensor is enabled you can enter maximum detection distance in centimeters separately for top and bottom sensors.

View File

@@ -9,7 +9,7 @@ The luminance is displayed in both the Info section of the web UI, as well as pu
- This must be added under `lib_deps` in your `platformio.ini` (or `platformio_override.ini`).
- Data is published over MQTT - make sure you've enabled the MQTT sync interface.
## Compiliation
## Compilation
To enable, compile with `USERMOD_BH1750` defined (e.g. in `platformio_override.ini`)
```ini

View File

@@ -1,10 +1,13 @@
// force the compiler to show a warning to confirm that this file is included
#warning **** Included USERMOD_BH1750 ****
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#pragma once
#include "wled.h"
#include <Wire.h>
#include <BH1750.h>
// the max frequency to check photoresistor, 10 seconds
@@ -22,7 +25,7 @@
#define USERMOD_BH1750_FIRST_MEASUREMENT_AT 10000
#endif
// only report if differance grater than offset value
// only report if difference grater than offset value
#ifndef USERMOD_BH1750_OFFSET_VALUE
#define USERMOD_BH1750_OFFSET_VALUE 1
#endif
@@ -52,20 +55,11 @@ private:
static const char _offset[];
static const char _HomeAssistantDiscovery[];
// set the default pins based on the architecture, these get overridden by Usermod menu settings
#ifdef ARDUINO_ARCH_ESP32 // ESP32 boards
#define HW_PIN_SCL 22
#define HW_PIN_SDA 21
#else // ESP8266 boards
#define HW_PIN_SCL 5
#define HW_PIN_SDA 4
#endif
int8_t ioPin[2] = {HW_PIN_SCL, HW_PIN_SDA}; // I2C pins: SCL, SDA...defaults to Arch hardware pins but overridden at setup()
bool initDone = false;
bool sensorFound = false;
// Home Assistant and MQTT
String mqttLuminanceTopic = F("");
String mqttLuminanceTopic;
bool mqttInitialized = false;
bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages
@@ -92,7 +86,7 @@ private:
StaticJsonDocument<600> doc;
doc[F("name")] = String(serverDescription) + F(" ") + name;
doc[F("name")] = String(serverDescription) + " " + name;
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
if (unitOfMeasurement != "")
@@ -104,14 +98,14 @@ private:
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F("WLED");
device[F("model")] = F("FOSS");
device[F("manufacturer")] = F(WLED_BRAND);
device[F("model")] = F(WLED_PRODUCT_NAME);
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUG_PRINTLN(t);
DEBUG_PRINTLN(temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
@@ -119,14 +113,7 @@ private:
public:
void setup()
{
bool HW_Pins_Used = (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA); // note whether architecture-based hardware SCL/SDA pins used
PinOwner po = PinOwner::UM_BH1750; // defaults to being pinowner for SCL/SDA pins
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } }; // allocate pins
if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
if (!pinManager.allocateMultiplePins(pins, 2, po)) return;
Wire.begin(ioPin[1], ioPin[0]);
if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; }
sensorFound = lightMeter.begin();
initDone = true;
}
@@ -156,6 +143,7 @@ public:
{
lastLux = lux;
lastSend = millis();
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED)
{
if (!mqttInitialized)
@@ -164,12 +152,13 @@ public:
mqttInitialized = true;
}
mqtt->publish(mqttLuminanceTopic.c_str(), 0, true, String(lux).c_str());
DEBUG_PRINTLN(F("Brightness: ") + String(lux) + F("lx"));
DEBUGUM_PRINTLN(F("Brightness: ") + String(lux) + F("lx"));
}
else
{
DEBUG_PRINTLN(F("Missing MQTT connection. Not publishing data"));
DEBUGUM_PRINTLN(F("Missing MQTT connection. Not publishing data"));
}
#endif
}
}
@@ -184,7 +173,9 @@ public:
user = root.createNestedObject(F("u"));
JsonArray lux_json = user.createNestedArray(F("Luminance"));
if (!sensorFound) {
if (!enabled) {
lux_json.add(F("disabled"));
} else if (!sensorFound) {
// if no sensor
lux_json.add(F("BH1750 "));
lux_json.add(F("Not Found"));
@@ -210,25 +201,20 @@ public:
top[FPSTR(_minReadInterval)] = minReadingInterval;
top[FPSTR(_HomeAssistantDiscovery)] = HomeAssistantDiscovery;
top[FPSTR(_offset)] = offset;
JsonArray io_pin = top.createNestedArray(F("pin"));
for (byte i=0; i<2; i++) io_pin.add(ioPin[i]);
top[F("help4Pins")] = F("SCL,SDA"); // help for Settings page
DEBUG_PRINTLN(F("BH1750 config saved."));
DEBUGUM_PRINTLN(F("BH1750 config saved."));
}
// called before setup() to populate properties from values stored in cfg.json
bool readFromConfig(JsonObject &root)
{
int8_t newPin[2]; for (byte i=0; i<2; i++) newPin[i] = ioPin[i]; // prepare to note changed pins
// we look for JSON object.
JsonObject top = root[FPSTR(_name)];
if (top.isNull())
{
DEBUG_PRINT(FPSTR(_name));
DEBUG_PRINT(F("BH1750"));
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINT(F("BH1750"));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
bool configComplete = !top.isNull();
@@ -238,27 +224,12 @@ public:
configComplete &= getJsonValue(top[FPSTR(_minReadInterval)], minReadingInterval, 500); //ms
configComplete &= getJsonValue(top[FPSTR(_HomeAssistantDiscovery)], HomeAssistantDiscovery, false);
configComplete &= getJsonValue(top[FPSTR(_offset)], offset, 1);
for (byte i=0; i<2; i++) configComplete &= getJsonValue(top[F("pin")][i], newPin[i], ioPin[i]);
DEBUG_PRINT(FPSTR(_name));
DEBUGUM_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
for (byte i=0; i<2; i++) ioPin[i] = newPin[i];
DEBUG_PRINTLN(F(" config loaded."));
DEBUGUM_PRINTLN(F(" config loaded."));
} else {
DEBUG_PRINTLN(F(" config (re)loaded."));
// changing parameters from settings page
bool pinsChanged = false;
for (byte i=0; i<2; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; } // check if any pins changed
if (pinsChanged) { //if pins changed, deallocate old pins and allocate new ones
PinOwner po = PinOwner::UM_BH1750;
if (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
pinManager.deallocateMultiplePins((const uint8_t *)ioPin, 2, po); // deallocate pins
for (byte i=0; i<2; i++) ioPin[i] = newPin[i];
setup();
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[F("pin")].isNull();
DEBUGUM_PRINTLN(F(" config (re)loaded."));
}
return configComplete;

View File

@@ -7,6 +7,7 @@ This Usermod is designed to read a `BME280` or `BMP280` sensor and output the fo
- Dew Point (`BME280` only)
Configuration is performed via the Usermod menu. There are no parameters to set in code! The following settings can be configured in the Usermod Menu:
- The i2c address in decimal. Set it to either 118 (0x76, the default) or 119 (0x77).
- Temperature Decimals (number of decimal places to output)
- Humidity Decimals
- Pressure Decimals

View File

@@ -1,11 +1,14 @@
// force the compiler to show a warning to confirm that this file is included
#warning **** Included USERMOD_BME280 version 2.0 ****
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#pragma once
#include "wled.h"
#include <Arduino.h>
#include <Wire.h>
#include <BME280I2C.h> // BME280 sensor
#include <EnvironmentCalculations.h> // BME280 extended measurements
@@ -21,6 +24,7 @@ private:
uint8_t PressureDecimals = 0; // Number of decimal places in published pressure values
uint16_t TemperatureInterval = 5; // Interval to measure temperature (and humidity, dew point if available) in seconds
uint16_t PressureInterval = 300; // Interval to measure pressure in seconds
BME280I2C::I2CAddr I2CAddress = BME280I2C::I2CAddr_0x76; // i2c address, defaults to 0x76
bool PublishAlways = false; // Publish values even when they have not changed
bool UseCelsius = true; // Use Celsius for Reporting
bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information
@@ -28,25 +32,11 @@ private:
// set the default pins based on the architecture, these get overridden by Usermod menu settings
#ifdef ESP8266
//uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8
//uint8_t RST_PIN = 16; // Un-comment for Heltec WiFi-Kit-8
#endif
int8_t ioPin[2] = {i2c_scl, i2c_sda}; // I2C pins: SCL, SDA...defaults to Arch hardware pins but overridden at setup()
bool initDone = false;
// BME280 sensor settings
BME280I2C::Settings settings{
BME280::OSR_X16, // Temperature oversampling x16
BME280::OSR_X16, // Humidity oversampling x16
BME280::OSR_X16, // Pressure oversampling x16
// Defaults
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. Default 0x76
};
BME280I2C bme{settings};
BME280I2C bme;
uint8_t sensorType;
@@ -76,7 +66,7 @@ private:
static const char _name[];
static const char _enabled[];
// Read the BME280/BMP280 Sensor (which one runs depends on whether Celsius or Farenheit being set in Usermod Menu)
// Read the BME280/BMP280 Sensor (which one runs depends on whether Celsius or Fahrenheit being set in Usermod Menu)
void UpdateBME280Data(int SensorType)
{
float _temperature, _humidity, _pressure;
@@ -158,14 +148,14 @@ private:
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F("WLED");
device[F("model")] = F("FOSS");
device[F("manufacturer")] = F(WLED_BRAND);
device[F("model")] = F(WLED_PRODUCT_NAME);
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUG_PRINTLN(t);
DEBUG_PRINTLN(temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
@@ -179,40 +169,52 @@ private:
}
}
void initializeBmeComms()
{
BME280I2C::Settings settings{
BME280::OSR_X16, // Temperature oversampling x16
BME280::OSR_X16, // Humidity oversampling x16
BME280::OSR_X16, // Pressure oversampling x16
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
I2CAddress
};
bme.setSettings(settings);
if (!bme.begin())
{
sensorType = 0;
DEBUGUM_PRINTLN(F("Could not find BME280 I2C sensor!"));
}
else
{
switch (bme.chipModel())
{
case BME280::ChipModel_BME280:
sensorType = 1;
DEBUGUM_PRINTLN(F("Found BME280 sensor! Success."));
break;
case BME280::ChipModel_BMP280:
sensorType = 2;
DEBUGUM_PRINTLN(F("Found BMP280 sensor! No Humidity available."));
break;
default:
sensorType = 0;
DEBUGUM_PRINTLN(F("Found UNKNOWN sensor! Error!"));
}
}
}
public:
void setup()
{
bool HW_Pins_Used = (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda); // note whether architecture-based hardware SCL/SDA pins used
PinOwner po = PinOwner::UM_BME280; // defaults to being pinowner for SCL/SDA pins
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } }; // allocate pins
if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
if (!pinManager.allocateMultiplePins(pins, 2, po)) { sensorType=0; return; }
if (i2c_scl<0 || i2c_sda<0) { enabled = false; sensorType = 0; return; }
Wire.begin(ioPin[1], ioPin[0]);
if (!bme.begin())
{
sensorType = 0;
DEBUG_PRINTLN(F("Could not find BME280 I2C sensor!"));
}
else
{
switch (bme.chipModel())
{
case BME280::ChipModel_BME280:
sensorType = 1;
DEBUG_PRINTLN(F("Found BME280 sensor! Success."));
break;
case BME280::ChipModel_BMP280:
sensorType = 2;
DEBUG_PRINTLN(F("Found BMP280 sensor! No Humidity available."));
break;
default:
sensorType = 0;
DEBUG_PRINTLN(F("Found UNKNOWN sensor! Error!"));
}
}
initDone=true;
initializeBmeComms();
initDone = true;
}
void loop()
@@ -369,12 +371,11 @@ public:
}
else if (sensorType==2) //BMP280
{
JsonArray temperature_json = user.createNestedArray(F("Temperature"));
JsonArray pressure_json = user.createNestedArray(F("Pressure"));
temperature_json.add(roundf(sensorTemperature * powf(10, TemperatureDecimals)));
temperature_json.add(roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals));
temperature_json.add(tempScale);
pressure_json.add(roundf(sensorPressure * powf(10, PressureDecimals)));
pressure_json.add(roundf(sensorPressure * powf(10, PressureDecimals)) / powf(10, PressureDecimals));
pressure_json.add(F("hPa"));
}
else if (sensorType==1) //BME280
@@ -386,9 +387,9 @@ public:
JsonArray dewpoint_json = user.createNestedArray(F("Dew Point"));
temperature_json.add(roundf(sensorTemperature * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals));
temperature_json.add(tempScale);
humidity_json.add(roundf(sensorHumidity * powf(10, HumidityDecimals)));
humidity_json.add(roundf(sensorHumidity * powf(10, HumidityDecimals)) / powf(10, HumidityDecimals));
humidity_json.add(F("%"));
pressure_json.add(roundf(sensorPressure * powf(10, PressureDecimals)));
pressure_json.add(roundf(sensorPressure * powf(10, PressureDecimals)) / powf(10, PressureDecimals));
pressure_json.add(F("hPa"));
heatindex_json.add(roundf(sensorHeatIndex * powf(10, TemperatureDecimals)) / powf(10, TemperatureDecimals));
heatindex_json.add(tempScale);
@@ -403,6 +404,7 @@ public:
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
top[F("I2CAddress")] = static_cast<uint8_t>(I2CAddress);
top[F("TemperatureDecimals")] = TemperatureDecimals;
top[F("HumidityDecimals")] = HumidityDecimals;
top[F("PressureDecimals")] = PressureDecimals;
@@ -411,10 +413,7 @@ public:
top[F("PublishAlways")] = PublishAlways;
top[F("UseCelsius")] = UseCelsius;
top[F("HomeAssistantDiscovery")] = HomeAssistantDiscovery;
JsonArray io_pin = top.createNestedArray(F("pin"));
for (byte i=0; i<2; i++) io_pin.add(ioPin[i]);
top[F("help4Pins")] = F("SCL,SDA"); // help for Settings page
DEBUG_PRINTLN(F("BME280 config saved."));
DEBUGUM_PRINTLN(F("BME280 config saved."));
}
// Read Usermod Config Settings
@@ -423,18 +422,20 @@ public:
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
int8_t newPin[2]; for (byte i=0; i<2; i++) newPin[i] = ioPin[i]; // prepare to note changed pins
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINT(F(_name));
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINT(F(_name));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
bool configComplete = !top.isNull();
configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
// A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing
uint8_t tmpI2cAddress;
configComplete &= getJsonValue(top[F("I2CAddress")], tmpI2cAddress, 0x76);
I2CAddress = static_cast<BME280I2C::I2CAddr>(tmpI2cAddress);
configComplete &= getJsonValue(top[F("TemperatureDecimals")], TemperatureDecimals, 1);
configComplete &= getJsonValue(top[F("HumidityDecimals")], HumidityDecimals, 0);
configComplete &= getJsonValue(top[F("PressureDecimals")], PressureDecimals, 0);
@@ -443,27 +444,29 @@ public:
configComplete &= getJsonValue(top[F("PublishAlways")], PublishAlways, false);
configComplete &= getJsonValue(top[F("UseCelsius")], UseCelsius, true);
configComplete &= getJsonValue(top[F("HomeAssistantDiscovery")], HomeAssistantDiscovery, false);
for (byte i=0; i<2; i++) configComplete &= getJsonValue(top[F("pin")][i], newPin[i], ioPin[i]);
DEBUG_PRINT(FPSTR(_name));
DEBUGUM_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
for (byte i=0; i<2; i++) ioPin[i] = newPin[i];
DEBUG_PRINTLN(F(" config loaded."));
DEBUGUM_PRINTLN(F(" config loaded."));
} else {
DEBUG_PRINTLN(F(" config (re)loaded."));
// changing parameters from settings page
bool pinsChanged = false;
for (byte i=0; i<2; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; } // check if any pins changed
if (pinsChanged) { //if pins changed, deallocate old pins and allocate new ones
PinOwner po = PinOwner::UM_BME280;
if (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
pinManager.deallocateMultiplePins((const uint8_t *)ioPin, 2, po); // deallocate pins
for (byte i=0; i<2; i++) ioPin[i] = newPin[i];
setup();
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[F("pin")].isNull();
DEBUGUM_PRINTLN(F(" config (re)loaded."));
// Reset all known values
sensorType = 0;
sensorTemperature = 0;
sensorHumidity = 0;
sensorHeatIndex = 0;
sensorDewPoint = 0;
sensorPressure = 0;
lastTemperature = 0;
lastHumidity = 0;
lastHeatIndex = 0;
lastDewPoint = 0;
lastPressure = 0;
initializeBmeComms();
}
return configComplete;

Binary file not shown.

View File

@@ -0,0 +1,152 @@
# Usermod BME68X
This usermod was developed for a BME680/BME68X sensor. The BME68X is not compatible with the BME280/BMP280 chip. It has its own library. The original 'BSEC Software Library' from Bosch was used to develop the code. The measured values are displayed on the WLED info page.
<p align="center"><img src="pics/pic1.png" style="width:60%;"></p>
In addition, the values are published on MQTT if this is active. The topic used for this is: 'wled/[MQTT Client ID]'. The Client ID is set in the WLED MQTT settings.
<p align="center"><img src="pics/pic2.png"></p>
If you use HomeAssistance discovery, the device tree for HomeAssistance is created. This is published under the topic 'homeassistant/sensor/[MQTT Client ID]' via MQTT.
<p align="center"><img src="pics/pic3.png"></p>
A device with the following sensors appears in HomeAssistant. Please note that MQTT must be activated in HomeAssistant.
<p align="center"><img src="pics/pic4.png" style="width:60%;"></p>
## Features
Raw sensor types
Sensor Accuracy Scale Range
--------------------------------------------------------------------------------------------------
Temperature +/- 1.0 °C/°F -40 to 85 °C
Humidity +/- 3 % 0 to 100 %
Pressure +/- 1 hPa 300 to 1100 hPa
Gas Resistance Ohm
The BSEC Library calculates the following values via the gas resistance
Sensor Accuracy Scale Range
--------------------------------------------------------------------------------------------------
IAQ value between 0 and 500
Static IAQ same as IAQ but for permanently installed devices
CO2 PPM
VOC PPM
Gas-Percentage %
In addition the usermod calculates
Sensor Accuracy Scale Range
--------------------------------------------------------------------------------------------------
Absolute humidity g/m³
Dew point °C/°F
### IAQ (Indoor Air Quality)
The IAQ is divided into the following value groups.
<p align="center"><img src="pics/pic5.png"></p>
For more detailed information, please consult the enclosed Bosch product description (BME680.pdf).
## Calibration of the device
The gas sensor of the BME68X must be calibrated. This differs from the BME280, which does not require any calibration.
There is a range of additional information for this, which the driver also provides. These values can be found in HomeAssistant under Diagnostics.
- **STABILIZATION_STATUS**: Gas sensor stabilization status [boolean] Indicates initial stabilization status of the gas sensor element: stabilization is ongoing (0) or stabilization is finished (1).
- **RUN_IN_STATUS**: Gas sensor run-in status [boolean] Indicates power-on stabilization status of the gas sensor element: stabilization is ongoing (0) or stabilization is finished (1)
Furthermore, all GAS based values have their own accuracy value. These have the following meaning:
- **Accuracy = 0** means the sensor is being stabilized (this can take a while on the first run)
- **Accuracy = 1** means that the previous measured values show too few differences and cannot be used for calibration. If the sensor is at accuracy 1 for too long, you must ensure that the ambient air is chaning. Opening the windows is fine. Or sometimes it is sufficient to breathe on the sensor for approx. 5 minutes.
- **Accuracy = 2** means the sensor is currently calibrating.
- **Accuracy = 3** means that the sensor has been successfully calibrated. Once accuracy 3 is reached, the calibration data is automatically written to the file system. This calibration data will be used again at the next start and will speed up the calibration.
The IAQ index is therefore only meaningful if IAQ Accuracy = 3. In addition to the value for IAQ, BSEC also provides us with CO2 and VOC equivalent values. When using the sensor, the calibration value should also always be read out and displayed or transmitted.
Reasonably reliable values are therefore only achieved when accuracy displays the value 3.
## Settings
The settings of the usermods are set in the usermod section of wled.
<p align="center"><img src="pics/pic6.png"></p>
The possible settings are
- **Enable:** Enables / disables the usermod
- **I2C address:** I2C address of the sensor. You can choose between 0X77 & 0X76. The default is 0x77.
- **Interval:** Specifies the interval of seconds at which the usermod should be executed. The default is every second.
- **Pub Chages Only:** If this item is active, the values are only published if they have changed since the last publication.
- **Pub Accuracy:** The Accuracy values associated with the gas values are also published.
- **Pub Calib State:** If this item is active, STABILIZATION_STATUS& RUN_IN_STATUS are also published.
- **Temp Scale:** Here you can choose between °C and °F.
- **Temp Offset:** The temperature offset is always set in °C. It must be converted for Fahrenheit.
- **HA Discovery:** If this item is active, the HomeAssistant sensor tree is created.
- **Pause While WLED Active:** If WLED has many LEDs to calculate, the computing power may no longer be sufficient to calculate the LEDs and read the sensor data. The LEDs then hang for a few microseconds, which can be seen. If this point is active, no sensor data is fetched as long as WLED is running.
- **Del Calibration Hist:** If a check mark is set here, the calibration file saved in the file system is deleted when the settings are saved.
### Sensors
Applies to all sensors. The number of decimal places is set here. If the sensor is set to -1, it will no longer be published. In addition, the IAQ values can be activated here in verbal form.
It is recommended to use the Static IAQ for the IAQ values. This is recommended by Bosch for statically placed devices.
## Output
Data is published over MQTT - make sure you've enabled the MQTT sync interface.
In addition to outputting via MQTT, you can read the values from the Info Screen on the dashboard page of the device's web interface.
Methods also exist to read the read/calculated values from other WLED modules through code.
- getTemperature(); The scale °C/°F is depended to the settings
- getHumidity();
- getPressure();
- getGasResistance();
- getAbsoluteHumidity();
- getDewPoint(); The scale °C/°F is depended to the settings
- getIaq();
- getStaticIaq();
- getCo2();
- getVoc();
- getGasPerc();
- getIaqAccuracy();
- getStaticIaqAccuracy();
- getCo2Accuracy();
- getVocAccuracy();
- getGasPercAccuracy();
- getStabStatus();
- getRunInStatus();
## Compiling
To enable, compile with `USERMOD_BME68X` defined (e.g. in `platformio_override.ini`) and add the `BSEC Software Library` to the lib_deps.
```
[env:esp32-BME680]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
lib_deps = ${esp32.lib_deps}
boschsensortec/BSEC Software Library @ ^1.8.1492 ; USERMOD: BME680
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32}
-D USERMOD_BME68X ; USERMOD: BME680
```
## Revision History
### Version 1.0.0
- First version of the BME68X_v user module
### Version 1.0.1
- Rebased to WELD Version 0.15
- Reworked some default settings
- A problem with the default settings has been fixed
## Known problems
- MQTT goes online at device start. Shortly afterwards it goes offline and takes quite a while until it goes online again. The problem does not come from this user module, but from the WLED core.
- If you save the settings often, WLED can get stuck.
- If many LEDS are connected to WLED, reading the sensor can cause a small but noticeable hang. The "Pause While WLED Active" option was introduced as a workaround.
<div><img src="pics/GeoGab.svg" width="20%"/> </div>
Gabriel Sieben (gsieben@geogab.net)

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xml:space="preserve"
style="enable-background:new 0 0 595.28 127.56;"
viewBox="0 0 600 135"
y="0px"
x="0px"
id="Layer_1"
version="1.1"><metadata
id="metadata2372"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs2370"><linearGradient
osb:paint="solid"
id="linearGradient3877"><stop
id="stop3875"
offset="0"
style="stop-color:#808285;stop-opacity:1;" /></linearGradient><clipPath
id="clipPath2379"
clipPathUnits="userSpaceOnUse"><g
style="fill:#808285;fill-opacity:1;fill-rule:nonzero;stroke:#230065;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99607843"
id="use2381"><path
style="fill:#808285;fill-opacity:1;fill-rule:nonzero;stroke:#230065;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99607843"
class="st0"
d="m 588.34,94.29 c 0,13.28 -10.77,24.04 -24.04,24.04 H 31.38 C 18.1,118.33 7.34,107.57 7.34,94.29 V 32.38 C 7.34,19.1 18.1,8.34 31.38,8.34 h 532.91 c 13.28,0 24.04,10.76 24.04,24.04 V 94.29 Z M 159.44,69.66 c 0,17.15 11.68,19.07 21.89,19.07 h 14.23 c 14.6,0 23.44,-3.2 23.44,-13.87 v -0.91 h -7.84 c -0.45,7.11 -4.47,8.39 -14.32,8.39 h -10.76 c -13.68,0 -18.79,-2.74 -18.79,-13.32 V 66.65 H 219 V 60.9 C 219,44.3 208.88,40.74 194.83,40.74 h -12.59 c -11.12,0 -22.8,1.92 -22.8,18.79 z m 51.72,-9.95 h -43.87 c 0.73,-10.58 3.65,-12.59 16.05,-12.59 h 11.49 c 12.77,0 16.33,4.74 16.33,9.49 z m 18.62,10.13 c 0,15.33 10.86,18.88 25.73,18.88 h 11.22 c 14.87,0 25.72,-3.56 25.72,-18.88 V 59.62 c 0,-15.32 -10.85,-18.88 -25.72,-18.88 h -11.22 c -14.87,0 -25.73,3.56 -25.73,18.88 z m 54.82,-0.46 c 0,10.86 -6.38,12.95 -15.51,12.95 h -15.96 c -9.12,0 -15.51,-2.09 -15.51,-12.95 v -9.31 c 0,-10.85 6.39,-12.95 15.51,-12.95 h 15.96 c 9.12,0 15.51,2.1 15.51,12.95 z m 173.79,18.61 v -31.2 c 0,-13.87 -9.85,-16.06 -24.45,-16.06 h -12.41 c -14.05,0 -19.43,3.47 -19.43,11.95 v 2.28 h 7.84 v -1.64 c 0,-3.83 1.92,-6.2 11.77,-6.2 h 11.49 c 12.04,0 17.33,1.09 17.33,9.49 v 8.76 h -0.18 c -2.74,-4.47 -6.39,-5.56 -16.6,-5.56 H 421.16 C 407.48,59.81 400,61.09 400,71.67 v 3.1 c 0,8.76 3.1,13.96 14.96,13.96 h 18.79 z m -7.84,-12.5 c 0,5.84 -5.47,6.84 -19.7,6.84 h -10.4 c -10.76,0 -12.59,-2.19 -12.59,-7.39 v -1.46 c 0,-5.84 2.83,-7.3 12.95,-7.3 h 12.04 c 12.04,0 17.7,0.82 17.7,7.2 z M 73.6,66.69 h 10.88 l 5.03,0.01 h 48.67 v 2.41 c 0,9.12 -5.47,12.23 -14.41,12.23 H 88.83 c -8.58,0 -15.51,-2.55 -15.51,-14.05 v -0.35 -0.26 z m -9.16,-0.01 c 0,0.06 0,0.14 0,0.2 0.67,14.68 6.68,21.76 23.47,21.76 h 36.85 c 16.51,0 22.35,-6.39 22.35,-24.36 V 59.4 H 89.51 L 85.39,59.39 H 73.32 v -0.01 -16.9 c 0,-11.49 6.93,-14.05 15.51,-14.05 H 112 c 22.07,0 25.81,0.91 25.81,13.23 h 8.39 v -2.37 c 0,-15.23 -12.68,-18.15 -24.54,-18.15 H 87.92 c -17.88,0 -23.53,8.03 -23.53,24.72 V 59.39 L 64.38,59.4 H 44.6 c -11.86,0 -24.54,2.92 -24.54,18.15 v 2.37 5.02 2.37 c 0,15.24 12.68,18.16 24.54,18.16 h 40.79 432.59 34.03 c 17.88,0 23.54,-8.03 23.54,-24.72 V 45.88 c 0,-16.69 -5.65,-24.72 -23.54,-24.72 l -0.16,-0.02 h -223 c -17.88,0 -23.53,8.03 -23.53,24.72 v 18.06 c 0,16.69 5.65,24.72 23.53,24.72 h 36.85 c 16.51,0 22.35,-6.39 22.35,-24.36 V 59.4 h -42.78 v 7.3 h 33.84 v 2.41 c 0,9.12 -5.47,12.23 -14.41,12.23 h -34.94 c -8.58,0 -15.5,-2.55 -15.5,-14.05 V 42.48 c 0,-11.49 6.93,-14.05 15.5,-14.05 l 142.5,0.02 v 61.24 l 24.35,0.73 h 10.95 c 14.23,0 24.18,-3.56 24.18,-19.61 V 62.6 c 0,-14.87 -5.75,-20.16 -24.63,-20.16 h -11.95 -14.88 -0.17 l -0.02,-14.01 h 71.75 l -0.75,0.02 c 8.58,0 15.51,2.55 15.51,14.04 v 41.62 c 0,11.49 -6.93,14.05 -15.51,14.05 H 518.97 86.87 54.27 c -22.08,0 -25.81,-0.91 -25.81,-13.23 v -5.02 c 0,-12.31 3.74,-13.23 25.81,-13.23 h 9.84 z m 459.45,4.04 c 0,9.03 -2.83,13.32 -15.6,13.32 h -12.77 c -11.67,0 -15.42,-4.93 -15.42,-13.41 v -8.85 c 0,-11.13 6.48,-12.95 17.06,-12.95 h 10.58 c 10.76,0 16.14,2.01 16.14,12.77 v 9.12 z"
id="path3935" /><path
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#230065;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99607843"
class="st0"
d="m 611.07375,-48.387188 c 0,13.28 -10.77,24.039999 -24.04,24.039999 H 54.113747 c -13.27999,0 -24.04,-10.76 -24.04,-24.039999 v -61.910002 c 0,-13.28 10.76001,-24.04 24.04,-24.04 H 587.02375 c 13.28,0 24.04,10.76 24.04,24.04 v 61.910002 z"
id="path3937" /></g></clipPath><clipPath
id="clipPath2398"
clipPathUnits="userSpaceOnUse"><g
id="use2400"
style="fill:#268298;fill-opacity:1"><g
id="g3959"
clip-path="url(#clipPath2407)"
style="fill:#268298;fill-opacity:1"><g
id="g3957"
style="fill:#268298;fill-opacity:1"><rect
style="opacity:1;fill:#268298;fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="rect3955"
width="350.98587"
height="147.57361"
x="95.224861"
y="-97.290329" /></g></g></g></clipPath><clipPath
id="clipPath2407"
clipPathUnits="userSpaceOnUse"><g
id="use2409"
style="fill:#268298;fill-opacity:1"><rect
style="opacity:1;fill:#268298;fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="rect3963"
width="350.98587"
height="147.57361"
x="95.224861"
y="-97.290329" /></g></clipPath></defs>
<style
id="style2363"
type="text/css">
.st0{fill:#808285;}
</style>
<path
style="opacity:1;fill:#ffffff;fill-opacity:0.9859813;fill-rule:nonzero;stroke:#5c7823;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99607843"
class="st0"
d="M 600,103.51782 C 600,116.79902 588.8778,127.56 575.17384,127.56 H 24.826163 C 11.111876,127.56 5.1635108e-7,116.79902 5.1635108e-7,103.51782 V 41.602186 C 5.1635108e-7,28.320979 11.111876,17.560001 24.826163,17.560001 H 575.16351 c 13.71429,0 24.82616,10.760978 24.82616,24.042185 v 61.915634 z"
id="path2365-0" /><path
style="fill:#808285;fill-opacity:1;fill-rule:nonzero;stroke:#230065;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.99607843"
class="st0"
d="M 600,103.51782 C 600,116.79902 588.8778,127.56 575.17384,127.56 H 24.826162 C 11.111877,127.56 5.1635111e-7,116.79902 5.1635111e-7,103.51782 V 41.602187 C 5.1635111e-7,28.320977 11.111876,17.559997 24.826162,17.559997 H 575.16351 c 13.71429,0 24.82616,10.76098 24.82616,24.04219 V 103.51782 Z M 157.07401,78.885567 c 0,17.15156 12.06196,19.07173 22.60585,19.07173 h 14.69535 c 15.07745,0 24.20654,-3.20029 24.20654,-13.87125 v -0.91009 h -8.09638 c -0.46472,7.11065 -4.61618,8.39076 -14.7883,8.39076 h -11.11188 c -14.12736,0 -19.40447,-2.74024 -19.40447,-13.3212 v -2.37022 h 53.40103 v -5.75052 c 0,-16.60151 -10.45094,-20.16183 -24.96041,-20.16183 h -13.00172 c -11.48365,0 -23.54561,1.92017 -23.54561,18.79171 z m 53.41136,-9.9509 h -45.30465 c 0.75387,-10.58096 3.76936,-12.59114 16.57487,-12.59114 h 11.86575 c 13.18761,0 16.86403,4.74043 16.86403,9.49086 z m 19.22891,10.13092 c 0,15.33139 11.21515,18.88171 26.57143,18.88171 h 11.58692 c 15.35629,0 26.56111,-3.56032 26.56111,-18.88171 v -10.22093 c 0,-15.32139 -11.20482,-18.88171 -26.56111,-18.88171 h -11.58692 c -15.35628,0 -26.57143,3.56032 -26.57143,18.88171 z m 56.61275,-0.46004 c 0,10.86098 -6.58865,12.95117 -16.01722,12.95117 h -16.48193 c -9.41825,0 -16.01721,-2.09019 -16.01721,-12.95117 v -9.31085 c 0,-10.85098 6.59896,-12.95117 16.01721,-12.95117 h 16.48193 c 9.41824,0 16.01722,2.10019 16.01722,12.95117 z m 179.47332,18.61169 v -31.20283 c 0,-13.87126 -10.17212,-16.06146 -25.24957,-16.06146 h -12.81584 c -14.50946,0 -20.0654,3.47031 -20.0654,11.95108 v 2.28021 h 8.09638 v -1.64015 c 0,-3.83035 1.98279,-6.20056 12.15491,-6.20056 h 11.86575 c 12.43373,0 17.89673,1.0901 17.89673,9.49086 v 8.7608 h -0.18589 c -2.8296,-4.47041 -6.59897,-5.56051 -17.14286,-5.56051 h -13.00172 c -14.12736,0 -21.85198,1.28012 -21.85198,11.86108 v 3.10028 c 0,8.76079 3.20138,13.96126 15.44923,13.96126 h 19.40447 z m -8.09639,-12.50114 c 0,5.84053 -5.64888,6.84062 -20.34423,6.84062 h -10.74011 c -11.11187,0 -13.00172,-2.19019 -13.00172,-7.39067 v -1.46013 c 0,-5.84053 2.92255,-7.30066 13.3735,-7.30066 h 12.43373 c 12.43374,0 18.27883,0.82007 18.27883,7.20065 z m -389.27711,-8.8008 h 11.2358 l 5.194492,0.01 h 50.261618 v 2.41021 c 0,9.12083 -5.64888,12.23111 -14.88124,12.23111 H 84.154905 c -8.860585,0 -16.017212,-2.55023 -16.017212,-14.05127 v -0.35003 -0.26003 z m -9.459552,-0.01 c 0,0.06 0,0.14002 0,0.20002 0.69191,14.68133 6.898451,21.76198 24.237521,21.76198 h 38.055071 c 17.04992,0 23.0809,-6.39058 23.0809,-24.36221 v -4.88045 H 84.857142 l -4.254733,-0.01 H 68.137693 v -0.01 -16.90153 c 0,-11.49104 7.156627,-14.05129 16.017212,-14.05129 h 23.927705 c 22.79174,0 26.65405,0.91009 26.65405,13.23121 h 8.66437 v -2.37021 c 0,-15.23139 -13.09466,-18.15166 -25.34251,-18.15166 H 83.215146 c -18.464717,0 -24.299483,8.03073 -24.299483,24.72226 v 13.53122 l -0.01033,0.01 h -20.42685 c -12.247849,0 -25.342513,2.92027 -25.342513,18.15165 v 2.37022 5.02045 2.37022 c 0,15.241393 13.094664,18.161653 25.342513,18.161653 h 42.123923 446.736664 35.14286 c 18.46471,0 24.30981,-8.03073 24.30981,-24.722253 v -34.87316 c 0,-16.69153 -5.83477,-24.72226 -24.30981,-24.72226 l -0.16523,-0.02 H 332.0241 c -18.46471,0 -24.29948,8.03073 -24.29948,24.72226 v 18.06163 c 0,16.69152 5.83477,24.72225 24.29948,24.72225 h 38.05508 c 17.04991,0 23.08089,-6.39058 23.08089,-24.36221 v -4.88045 h -44.179 v 7.30067 h 34.94664 v 2.41021 c 0,9.12083 -5.64888,12.23111 -14.88123,12.23111 h -36.08262 c -8.86059,0 -16.00688,-2.55023 -16.00688,-14.05127 v -24.81225 c 0,-11.49104 7.15662,-14.05129 16.00688,-14.05129 l 147.16007,0.02 v 61.24556 l 25.14629,0.73007 h 11.30809 c 14.69536,0 24.97074,-3.56033 24.97074,-19.61178 v -8.21075 c 0,-14.87135 -5.93803,-20.16183 -25.43545,-20.16183 h -12.34079 -15.36661 -0.17556 l -0.0207,-14.01128 h 74.09639 l -0.77453,0.02 c 8.86059,0 16.01721,2.55024 16.01721,14.04128 v 41.62378 c 0,11.491053 -7.15662,14.051283 -16.01721,14.051283 H 528.36145 82.130808 48.464716 c -22.802065,0 -26.654044,-0.91008 -26.654044,-13.231213 v -5.02046 c 0,-12.31111 3.862306,-13.2312 26.654044,-13.2312 h 10.161789 z m 474.475042,4.04037 c 0,9.03082 -2.92255,13.32121 -16.11015,13.32121 h -13.18761 c -12.05164,0 -15.92427,-4.93045 -15.92427,-13.41122 v -8.8508 c 0,-11.13101 6.69191,-12.95118 17.6179,-12.95118 h 10.92599 c 11.11188,0 16.66781,2.01019 16.66781,12.77116 v 9.12083 z"
id="path2365" />
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
#ifndef UMBBattery_h
#define UMBBattery_h
#include "battery_defaults.h"
/**
* Battery base class
* all other battery classes should inherit from this
*/
class UMBattery
{
private:
protected:
float minVoltage;
float maxVoltage;
float voltage;
int8_t level = 100;
float calibration; // offset or calibration value to fine tune the calculated voltage
float voltageMultiplier; // ratio for the voltage divider
float linearMapping(float v, float min, float max, float oMin = 0.0f, float oMax = 100.0f)
{
return (v-min) * (oMax-oMin) / (max-min) + oMin;
}
public:
UMBattery()
{
this->setVoltageMultiplier(USERMOD_BATTERY_VOLTAGE_MULTIPLIER);
this->setCalibration(USERMOD_BATTERY_CALIBRATION);
}
virtual void update(batteryConfig cfg)
{
if(cfg.minVoltage) this->setMinVoltage(cfg.minVoltage);
if(cfg.maxVoltage) this->setMaxVoltage(cfg.maxVoltage);
if(cfg.level) this->setLevel(cfg.level);
if(cfg.calibration) this->setCalibration(cfg.calibration);
if(cfg.voltageMultiplier) this->setVoltageMultiplier(cfg.voltageMultiplier);
}
/**
* Corresponding battery curves
* calculates the level in % (0-100) with given voltage and possible voltage range
*/
virtual float mapVoltage(float v, float min, float max) = 0;
// {
// example implementation, linear mapping
// return (v-min) * 100 / (max-min);
// };
virtual void calculateAndSetLevel(float voltage) = 0;
/*
*
* Getter and Setter
*
*/
/*
* Get lowest configured battery voltage
*/
virtual float getMinVoltage()
{
return this->minVoltage;
}
/*
* Set lowest battery voltage
* can't be below 0 volt
*/
virtual void setMinVoltage(float voltage)
{
this->minVoltage = max(0.0f, voltage);
}
/*
* Get highest configured battery voltage
*/
virtual float getMaxVoltage()
{
return this->maxVoltage;
}
/*
* Set highest battery voltage
* can't be below minVoltage
*/
virtual void setMaxVoltage(float voltage)
{
this->maxVoltage = max(getMinVoltage()+.5f, voltage);
}
float getVoltage()
{
return this->voltage;
}
/**
* check if voltage is within specified voltage range, allow 10% over/under voltage
*/
void setVoltage(float voltage)
{
// this->voltage = ( (voltage < this->getMinVoltage() * 0.85f) || (voltage > this->getMaxVoltage() * 1.1f) )
// ? -1.0f
// : voltage;
this->voltage = voltage;
}
float getLevel()
{
return this->level;
}
void setLevel(float level)
{
this->level = constrain(level, 0.0f, 110.0f);
}
/*
* Get the configured calibration value
* a offset value to fine-tune the calculated voltage.
*/
virtual float getCalibration()
{
return calibration;
}
/*
* Set the voltage calibration offset value
* a offset value to fine-tune the calculated voltage.
*/
virtual void setCalibration(float offset)
{
calibration = offset;
}
/*
* Get the configured calibration value
* a value to set the voltage divider ratio
*/
virtual float getVoltageMultiplier()
{
return voltageMultiplier;
}
/*
* Set the voltage multiplier value
* a value to set the voltage divider ratio.
*/
virtual void setVoltageMultiplier(float multiplier)
{
voltageMultiplier = multiplier;
}
};
#endif

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,140 @@
#ifndef UMBDefaults_h
#define UMBDefaults_h
#include "wled.h"
// pin defaults
// for the esp32 it is best to use the ADC1: GPIO32 - GPIO39
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html
#ifndef USERMOD_BATTERY_MEASUREMENT_PIN
#ifdef ARDUINO_ARCH_ESP32
#define USERMOD_BATTERY_MEASUREMENT_PIN 35
#else //ESP8266 boards
#define USERMOD_BATTERY_MEASUREMENT_PIN A0
#endif
#endif
// The initial delay before the first battery voltage reading after power-on.
// This allows the voltage to stabilize before readings are taken, improving accuracy of initial reading.
#ifndef USERMOD_BATTERY_INITIAL_DELAY
#define USERMOD_BATTERY_INITIAL_DELAY 10000 // (milliseconds)
#endif
// the frequency to check the battery, 30 sec
#ifndef USERMOD_BATTERY_MEASUREMENT_INTERVAL
#define USERMOD_BATTERY_MEASUREMENT_INTERVAL 30000
#endif
/* Default Battery Type
* 0 = unkown
* 1 = Lipo
* 2 = Lion
*/
#ifndef USERMOD_BATTERY_DEFAULT_TYPE
#define USERMOD_BATTERY_DEFAULT_TYPE 0
#endif
/*
*
* Unkown 'Battery' defaults
*
*/
#ifndef USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE
// Extra save defaults
#define USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE 3.3f
#endif
#ifndef USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE
#define USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE 4.2f
#endif
/*
*
* Lithium polymer (Li-Po) defaults
*
*/
#ifndef USERMOD_BATTERY_LIPO_MIN_VOLTAGE
// LiPo "1S" Batteries should not be dischared below 3V !!
#define USERMOD_BATTERY_LIPO_MIN_VOLTAGE 3.2f
#endif
#ifndef USERMOD_BATTERY_LIPO_MAX_VOLTAGE
#define USERMOD_BATTERY_LIPO_MAX_VOLTAGE 4.2f
#endif
/*
*
* Lithium-ion (Li-Ion) defaults
*
*/
#ifndef USERMOD_BATTERY_LION_MIN_VOLTAGE
// default for 18650 battery
#define USERMOD_BATTERY_LION_MIN_VOLTAGE 2.6f
#endif
#ifndef USERMOD_BATTERY_LION_MAX_VOLTAGE
#define USERMOD_BATTERY_LION_MAX_VOLTAGE 4.2f
#endif
// the default ratio for the voltage divider
#ifndef USERMOD_BATTERY_VOLTAGE_MULTIPLIER
#ifdef ARDUINO_ARCH_ESP32
#define USERMOD_BATTERY_VOLTAGE_MULTIPLIER 2.0f
#else //ESP8266 boards
#define USERMOD_BATTERY_VOLTAGE_MULTIPLIER 4.2f
#endif
#endif
#ifndef USERMOD_BATTERY_AVERAGING_ALPHA
#define USERMOD_BATTERY_AVERAGING_ALPHA 0.1f
#endif
// offset or calibration value to fine tune the calculated voltage
#ifndef USERMOD_BATTERY_CALIBRATION
#define USERMOD_BATTERY_CALIBRATION 0
#endif
// auto-off feature
#ifndef USERMOD_BATTERY_AUTO_OFF_ENABLED
#define USERMOD_BATTERY_AUTO_OFF_ENABLED true
#endif
#ifndef USERMOD_BATTERY_AUTO_OFF_THRESHOLD
#define USERMOD_BATTERY_AUTO_OFF_THRESHOLD 10
#endif
// low power indication feature
#ifndef USERMOD_BATTERY_LOW_POWER_INDICATOR_ENABLED
#define USERMOD_BATTERY_LOW_POWER_INDICATOR_ENABLED true
#endif
#ifndef USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET
#define USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET 0
#endif
#ifndef USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD
#define USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD 20
#endif
#ifndef USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION
#define USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION 5
#endif
// battery types
typedef enum
{
unknown=0,
lipo=1,
lion=2
} batteryType;
// used for initial configuration after boot
typedef struct bconfig_t
{
batteryType type;
float minVoltage;
float maxVoltage;
float voltage; // current voltage
int8_t level; // current level
float calibration; // offset or calibration value to fine tune the calculated voltage
float voltageMultiplier;
} batteryConfig;
#endif

178
usermods/Battery/readme.md Normal file
View File

@@ -0,0 +1,178 @@
<p align="center">
<img width="700" src="assets/battery_usermod_logo.png">
</p>
# Welcome to the battery usermod! 🔋
Enables battery level monitoring of your project.
<p align="left">
<img width="700" src="assets/battery_info_screen.png">
</p>
<br>
## ⚙️ Features
- 💯 Displays current battery voltage
- 🚥 Displays battery level
- 🚫 Auto-off with configurable threshold
- 🚨 Low power indicator with many configuration possibilities
<br><br>
## 🎈 Installation
| **Option 1** | **Option 2** |
|--------------|--------------|
| In `wled00/my_config.h`<br>Add the line: `#define USERMOD_BATTERY`<br><br>[Example: my_config.h](assets/installation_my_config_h.png) | In `platformio_override.ini` (or `platformio.ini`)<br>Under: `build_flags =`, add the line: `-D USERMOD_BATTERY`<br><br>[Example: platformio_override.ini](assets/installation_platformio_override_ini.png) |
<br><br>
## 🔌 Example wiring
- (see [Useful Links](#useful-links)).
<table style="width: 100%; table-layout: fixed;">
<tr>
<!-- Column for the first image -->
<td style="width: 50%; vertical-align: bottom;">
<img width="300" src="assets/battery_connection_schematic_01.png" style="display: block;">
<p><strong>ESP8266</strong><br>
With a 100k Ohm resistor, connect the positive<br>
side of the battery to pin `A0`.</p>
</td>
<!-- Column for the second image -->
<td style="width: 50%; vertical-align: bottom;">
<img width="250" src="assets/battery_connection_schematic_esp32.png" style="display: block;">
<p><strong>ESP32</strong> (+S2, S3, C3 etc...)<br>
Use a voltage divider (two resistors of equal value).<br>
Connect to ADC1 (GPIO32 - GPIO39). GPIO35 is Default.</p>
</td>
</tr>
</table>
<br><br>
## Define Your Options
| Name | Unit | Description |
| ----------------------------------------------- | ----------- |-------------------------------------------------------------------------------------- |
| `USERMOD_BATTERY` | | Define this (in `my_config.h`) to have this usermod included wled00\usermods_list.cpp |
| `USERMOD_BATTERY_MEASUREMENT_PIN` | | Defaults to A0 on ESP8266 and GPIO35 on ESP32 |
| `USERMOD_BATTERY_MEASUREMENT_INTERVAL` | ms | Battery check interval. defaults to 30 seconds |
| `USERMOD_BATTERY_INITIAL_DELAY` | ms | Delay before initial reading. defaults to 10 seconds to allow voltage stabilization |
| `USERMOD_BATTERY_{TYPE}_MIN_VOLTAGE` | v | Minimum battery voltage. default is 2.6 (18650 battery standard) |
| `USERMOD_BATTERY_{TYPE}_MAX_VOLTAGE` | v | Maximum battery voltage. default is 4.2 (18650 battery standard) |
| `USERMOD_BATTERY_{TYPE}_TOTAL_CAPACITY` | mAh | The capacity of all cells in parallel summed up |
| `USERMOD_BATTERY_{TYPE}_CALIBRATION` | | Offset / calibration number, fine tune the measured voltage by the microcontroller |
| Auto-Off | --- | --- |
| `USERMOD_BATTERY_AUTO_OFF_ENABLED` | true/false | Enables auto-off |
| `USERMOD_BATTERY_AUTO_OFF_THRESHOLD` | % (0-100) | When this threshold is reached master power turns off |
| Low-Power-Indicator | --- | --- |
| `USERMOD_BATTERY_LOW_POWER_INDICATOR_ENABLED` | true/false | Enables low power indication |
| `USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET` | preset id | When low power is detected then use this preset to indicate low power |
| `USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD` | % (0-100) | When this threshold is reached low power gets indicated |
| `USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION` | seconds | For this long the configured preset is played |
All parameters can be configured at runtime via the Usermods settings page.
<br>
**NOTICE:** Each Battery type can be pre-configured individualy (in `my_config.h`)
| Name | Alias | `my_config.h` example |
| --------------- | ------------- | ------------------------------------- |
| Lithium Polymer | lipo (Li-Po) | `USERMOD_BATTERY_lipo_MIN_VOLTAGE` |
| Lithium Ionen | lion (Li-Ion) | `USERMOD_BATTERY_lion_TOTAL_CAPACITY` |
<br><br>
## 🔧 Calibration
The calibration number is a value that is added to the final computed voltage after it has been scaled by the voltage multiplier.
It fine-tunes the voltage reading so that it more closely matches the actual battery voltage, compensating for inaccuracies inherent in the voltage divider resistors or the ESP's ADC measurements.
Set calibration either in the Usermods settings page or at compile time in `my_config.h` or `platformio_override.ini`.
It can be either a positive or negative number.
<br><br>
## ⚠️ Important
Make sure you know your battery specifications! All batteries are **NOT** the same!
Example:
| Your battery specification table | | Options you can define |
| --------------------------------- | --------------- | ----------------------------- |
| Capacity | 3500mAh 12.5Wh | |
| Minimum capacity | 3350mAh 11.9Wh | |
| Rated voltage | 3.6V - 3.7V | |
| **Charging end voltage** | **4.2V ± 0.05** | `USERMOD_BATTERY_MAX_VOLTAGE` |
| **Discharge voltage** | **2.5V** | `USERMOD_BATTERY_MIN_VOLTAGE` |
| Max. discharge current (constant) | 10A (10000mA) | |
| max. charging current | 1.7A (1700mA) | |
| ... | ... | ... |
| .. | .. | .. |
Specification from: [Molicel INR18650-M35A, 3500mAh 10A Lithium-ion battery, 3.6V - 3.7V](https://www.akkuteile.de/lithium-ionen-akkus/18650/molicel/molicel-inr18650-m35a-3500mah-10a-lithium-ionen-akku-3-6v-3-7v_100833)
<br><br>
## 🌐 Useful Links
- https://lazyzero.de/elektronik/esp8266/wemos_d1_mini_a0/start
- https://arduinodiy.wordpress.com/2016/12/25/monitoring-lipo-battery-voltage-with-wemos-d1-minibattery-shield-and-thingspeak/
<br><br>
## 📝 Change Log
2024-08-19
- Improved MQTT support
- Added battery percentage & battery voltage as MQTT topic
2024-05-11
- Documentation updated
2024-04-30
- Integrate factory pattern to make it easier to add other / custom battery types
- Update readme
- Improved initial reading accuracy by delaying initial measurement to allow voltage to stabilize at power-on
2023-01-04
- Basic support for LiPo rechargeable batteries (`-D USERMOD_BATTERY_USE_LIPO`)
- Improved support for ESP32 (read calibrated voltage)
- Corrected config saving (measurement pin, and battery min/max were lost)
- Various bugfixes
2022-12-25
- Added "auto-off" feature
- Added "low-power-indication" feature
- Added "calibration/offset" field to configuration page
- Added getter and setter, so that user usermods could interact with this one
- Update readme (added new options, made it markdownlint compliant)
2021-09-02
- Added "Battery voltage" to info
- Added circuit diagram to readme
- Added MQTT support, sending battery voltage
- Minor fixes
2021-08-15
- Changed `USERMOD_BATTERY_MIN_VOLTAGE` to 2.6 volt as default for 18650 batteries
- Updated readme, added specification table
2021-08-10
- Created

View File

@@ -0,0 +1,38 @@
#ifndef UMBLion_h
#define UMBLion_h
#include "../battery_defaults.h"
#include "../UMBattery.h"
/**
* LiOn Battery
*
*/
class LionUMBattery : public UMBattery
{
private:
public:
LionUMBattery() : UMBattery()
{
this->setMinVoltage(USERMOD_BATTERY_LION_MIN_VOLTAGE);
this->setMaxVoltage(USERMOD_BATTERY_LION_MAX_VOLTAGE);
}
float mapVoltage(float v, float min, float max) override
{
return this->linearMapping(v, min, max); // basic mapping
};
void calculateAndSetLevel(float voltage) override
{
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
};
virtual void setMaxVoltage(float voltage) override
{
this->maxVoltage = max(getMinVoltage()+1.0f, voltage);
}
};
#endif

View File

@@ -0,0 +1,54 @@
#ifndef UMBLipo_h
#define UMBLipo_h
#include "../battery_defaults.h"
#include "../UMBattery.h"
/**
* LiPo Battery
*
*/
class LipoUMBattery : public UMBattery
{
private:
public:
LipoUMBattery() : UMBattery()
{
this->setMinVoltage(USERMOD_BATTERY_LIPO_MIN_VOLTAGE);
this->setMaxVoltage(USERMOD_BATTERY_LIPO_MAX_VOLTAGE);
}
/**
* LiPo batteries have a differnt discharge curve, see
* https://blog.ampow.com/lipo-voltage-chart/
*/
float mapVoltage(float v, float min, float max) override
{
float lvl = 0.0f;
lvl = this->linearMapping(v, min, max); // basic mapping
if (lvl < 40.0f)
lvl = this->linearMapping(lvl, 0, 40, 0, 12); // last 45% -> drops very quickly
else {
if (lvl < 90.0f)
lvl = this->linearMapping(lvl, 40, 90, 12, 95); // 90% ... 40% -> almost linear drop
else // level > 90%
lvl = this->linearMapping(lvl, 90, 105, 95, 100); // highest 15% -> drop slowly
}
return lvl;
};
void calculateAndSetLevel(float voltage) override
{
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
};
virtual void setMaxVoltage(float voltage) override
{
this->maxVoltage = max(getMinVoltage()+0.7f, voltage);
}
};
#endif

View File

@@ -0,0 +1,39 @@
#ifndef UMBUnkown_h
#define UMBUnkown_h
#include "../battery_defaults.h"
#include "../UMBattery.h"
/**
* Unkown / Default Battery
*
*/
class UnkownUMBattery : public UMBattery
{
private:
public:
UnkownUMBattery() : UMBattery()
{
this->setMinVoltage(USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE);
this->setMaxVoltage(USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE);
}
void update(batteryConfig cfg)
{
if(cfg.minVoltage) this->setMinVoltage(cfg.minVoltage); else this->setMinVoltage(USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE);
if(cfg.maxVoltage) this->setMaxVoltage(cfg.maxVoltage); else this->setMaxVoltage(USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE);
}
float mapVoltage(float v, float min, float max) override
{
return this->linearMapping(v, min, max); // basic mapping
};
void calculateAndSetLevel(float voltage) override
{
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
};
};
#endif

View File

@@ -0,0 +1,859 @@
#pragma once
#include "wled.h"
#include "battery_defaults.h"
#include "UMBattery.h"
#include "types/UnkownUMBattery.h"
#include "types/LionUMBattery.h"
#include "types/LipoUMBattery.h"
/*
* Usermod by Maximilian Mewes
* E-mail: mewes.maximilian@gmx.de
* Created at: 25.12.2022
* If you have any questions, please feel free to contact me.
*/
class UsermodBattery : public Usermod
{
private:
// battery pin can be defined in my_config.h
int8_t batteryPin = USERMOD_BATTERY_MEASUREMENT_PIN;
UMBattery* bat = new UnkownUMBattery();
batteryConfig cfg;
// Initial delay before first reading to allow voltage stabilization
unsigned long initialDelay = USERMOD_BATTERY_INITIAL_DELAY;
bool initialDelayComplete = false;
bool isFirstVoltageReading = true;
// how often to read the battery voltage
unsigned long readingInterval = USERMOD_BATTERY_MEASUREMENT_INTERVAL;
unsigned long nextReadTime = 0;
unsigned long lastReadTime = 0;
// between 0 and 1, to control strength of voltage smoothing filter
float alpha = USERMOD_BATTERY_AVERAGING_ALPHA;
// auto shutdown/shutoff/master off feature
bool autoOffEnabled = USERMOD_BATTERY_AUTO_OFF_ENABLED;
uint8_t autoOffThreshold = USERMOD_BATTERY_AUTO_OFF_THRESHOLD;
// low power indicator feature
bool lowPowerIndicatorEnabled = USERMOD_BATTERY_LOW_POWER_INDICATOR_ENABLED;
uint8_t lowPowerIndicatorPreset = USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET;
uint8_t lowPowerIndicatorThreshold = USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD;
uint8_t lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
uint8_t lowPowerIndicatorDuration = USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION;
bool lowPowerIndicationDone = false;
unsigned long lowPowerActivationTime = 0; // used temporary during active time
uint8_t lastPreset = 0;
//
bool initDone = false;
bool initializing = true;
bool HomeAssistantDiscovery = false;
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
static const char _readInterval[];
static const char _enabled[];
static const char _threshold[];
static const char _preset[];
static const char _duration[];
static const char _init[];
static const char _haDiscovery[];
/**
* Helper for rounding floating point values
*/
float dot2round(float x)
{
float nx = (int)(x * 100 + .5);
return (float)(nx / 100);
}
/**
* Helper for converting a string to lowercase
*/
String stringToLower(String str)
{
for(int i = 0; i < str.length(); i++)
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
return str;
}
/**
* Turn off all leds
*/
void turnOff()
{
bri = 0;
stateUpdated(CALL_MODE_DIRECT_CHANGE);
}
/**
* Indicate low power by activating a configured preset for a given time and then switching back to the preset that was selected previously
*/
void lowPowerIndicator()
{
if (!lowPowerIndicatorEnabled) return;
if (batteryPin < 0) return; // no measurement
if (lowPowerIndicationDone && lowPowerIndicatorReactivationThreshold <= bat->getLevel()) lowPowerIndicationDone = false;
if (lowPowerIndicatorThreshold <= bat->getLevel()) return;
if (lowPowerIndicationDone) return;
if (lowPowerActivationTime <= 1) {
lowPowerActivationTime = millis();
lastPreset = currentPreset;
applyPreset(lowPowerIndicatorPreset);
}
if (lowPowerActivationTime+(lowPowerIndicatorDuration*1000) <= millis()) {
lowPowerIndicationDone = true;
lowPowerActivationTime = 0;
applyPreset(lastPreset);
}
}
/**
* read the battery voltage in different ways depending on the architecture
*/
float readVoltage()
{
#ifdef ARDUINO_ARCH_ESP32
// use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV default attentuation) and divide by 1000 to get from milivolts to volts and multiply by voltage multiplier and apply calibration value
return (analogReadMilliVolts(batteryPin) / 1000.0f) * bat->getVoltageMultiplier() + bat->getCalibration();
#else
// use analog read on esp8266 ( 0V ~ 1V no attenuation options) and divide by ADC precision 1023 and multiply by voltage multiplier and apply calibration value
return (analogRead(batteryPin) / 1023.0f) * bat->getVoltageMultiplier() + bat->getCalibration();
#endif
}
#ifndef WLED_DISABLE_MQTT
void addMqttSensor(const String &name, const String &type, const String &topic, const String &deviceClass, const String &unitOfMeasurement = "", const bool &isDiagnostic = false)
{
StaticJsonDocument<600> doc;
char uid[128], json_str[1024], buf[128];
doc[F("name")] = name;
doc[F("stat_t")] = topic;
sprintf_P(uid, PSTR("%s_%s_%s"), escapedMac.c_str(), stringToLower(name).c_str(), type);
doc[F("uniq_id")] = uid;
doc[F("dev_cla")] = deviceClass;
doc[F("exp_aft")] = 1800;
if(type == "binary_sensor") {
doc[F("pl_on")] = "on";
doc[F("pl_off")] = "off";
}
if(unitOfMeasurement != "")
doc[F("unit_of_measurement")] = unitOfMeasurement;
if(isDiagnostic)
doc[F("entity_category")] = "diagnostic";
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("ids")] = String(F("wled-sensor-")) + mqttClientID;
device[F("mf")] = F(WLED_BRAND);
device[F("mdl")] = F(WLED_PRODUCT_NAME);
device[F("sw")] = versionString;
sprintf_P(buf, PSTR("homeassistant/%s/%s/%s/config"), type, mqttClientID, uid);
DEBUGUM_PRINTLN(buf);
size_t payload_size = serializeJson(doc, json_str);
DEBUGUM_PRINTLN(json_str);
mqtt->publish(buf, 0, true, json_str, payload_size);
}
void publishMqtt(const char* topic, const char* state)
{
if (WLED_MQTT_CONNECTED) {
char buf[128];
snprintf_P(buf, 127, PSTR("%s/%s"), mqttDeviceTopic, topic);
mqtt->publish(buf, 0, false, state);
}
}
#endif
public:
//Functions called by WLED
/**
* setup() is called once at boot. WiFi is not yet connected at this point.
* You can use it to initialize variables, sensors or similar.
*/
void setup()
{
// plug in the right battery type
if(cfg.type == (batteryType)lipo) {
bat = new LipoUMBattery();
} else if(cfg.type == (batteryType)lion) {
bat = new LionUMBattery();
}
// update the choosen battery type with configured values
bat->update(cfg);
#ifdef ARDUINO_ARCH_ESP32
bool success = false;
DEBUGUM_PRINTLN(F("Allocating battery pin..."));
if (batteryPin >= 0 && digitalPinToAnalogChannel(batteryPin) >= 0)
if (PinManager::allocatePin(batteryPin, false, PinOwner::UM_Battery)) {
DEBUGUM_PRINTLN(F("Battery pin allocation succeeded."));
success = true;
}
if (!success) {
DEBUGUM_PRINTLN(F("Battery pin allocation failed."));
batteryPin = -1; // allocation failed
} else {
pinMode(batteryPin, INPUT);
}
#else //ESP8266 boards have only one analog input pin A0
pinMode(batteryPin, INPUT);
#endif
// First voltage reading is delayed to allow voltage stabilization after powering up
nextReadTime = millis() + initialDelay;
lastReadTime = millis();
initDone = true;
}
/**
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
void connected()
{
//Serial.println("Connected to WiFi!");
}
/*
* loop() is called continuously. Here you can check for events, read sensors, etc.
*
*/
void loop()
{
if(strip.isUpdating()) return;
lowPowerIndicator();
// Handling the initial delay
if (!initialDelayComplete && millis() < nextReadTime)
return; // Continue to return until the initial delay is over
// Once the initial delay is over, set it as complete
if (!initialDelayComplete)
{
initialDelayComplete = true;
// Set the regular interval after initial delay
nextReadTime = millis() + readingInterval;
}
// Make the first voltage reading after the initial delay has elapsed
if (isFirstVoltageReading)
{
bat->setVoltage(readVoltage());
isFirstVoltageReading = false;
}
// check the battery level every USERMOD_BATTERY_MEASUREMENT_INTERVAL (ms)
if (millis() < nextReadTime) return;
nextReadTime = millis() + readingInterval;
lastReadTime = millis();
if (batteryPin < 0) return; // nothing to read
initializing = false;
float rawValue = readVoltage();
// filter with exponential smoothing because ADC in esp32 is fluctuating too much for a good single readout
float filteredVoltage = bat->getVoltage() + alpha * (rawValue - bat->getVoltage());
bat->setVoltage(filteredVoltage);
// translate battery voltage into percentage
bat->calculateAndSetLevel(filteredVoltage);
// Auto off -- Master power off
if (autoOffEnabled && (autoOffThreshold >= bat->getLevel()))
turnOff();
#ifndef WLED_DISABLE_MQTT
publishMqtt("battery", String(bat->getLevel(), 0).c_str());
publishMqtt("voltage", String(bat->getVoltage()).c_str());
#endif
}
/**
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
void addToJsonInfo(JsonObject& root)
{
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
if (batteryPin < 0) {
JsonArray infoVoltage = user.createNestedArray(F("Battery voltage"));
infoVoltage.add(F("n/a"));
infoVoltage.add(F(" invalid GPIO"));
return; // no GPIO - nothing to report
}
// info modal display names
JsonArray infoPercentage = user.createNestedArray(F("Battery level"));
JsonArray infoVoltage = user.createNestedArray(F("Battery voltage"));
JsonArray infoNextUpdate = user.createNestedArray(F("Next update"));
infoNextUpdate.add((nextReadTime - millis()) / 1000);
infoNextUpdate.add(F(" sec"));
if (initializing) {
infoPercentage.add(FPSTR(_init));
infoVoltage.add(FPSTR(_init));
return;
}
if (bat->getLevel() < 0) {
infoPercentage.add(F("invalid"));
} else {
infoPercentage.add(bat->getLevel());
}
infoPercentage.add(F(" %"));
if (bat->getVoltage() < 0) {
infoVoltage.add(F("invalid"));
} else {
infoVoltage.add(dot2round(bat->getVoltage()));
}
infoVoltage.add(F(" V"));
}
void addBatteryToJsonObject(JsonObject& battery, bool forJsonState)
{
if(forJsonState) { battery[F("type")] = cfg.type; } else {battery[F("type")] = (String)cfg.type; } // has to be a String otherwise it won't get converted to a Dropdown
battery[F("min-voltage")] = bat->getMinVoltage();
battery[F("max-voltage")] = bat->getMaxVoltage();
battery[F("calibration")] = bat->getCalibration();
battery[F("voltage-multiplier")] = bat->getVoltageMultiplier();
battery[FPSTR(_readInterval)] = readingInterval;
battery[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section
ao[FPSTR(_enabled)] = autoOffEnabled;
ao[FPSTR(_threshold)] = autoOffThreshold;
JsonObject lp = battery.createNestedObject(F("indicator")); // low power section
lp[FPSTR(_enabled)] = lowPowerIndicatorEnabled;
lp[FPSTR(_preset)] = lowPowerIndicatorPreset; // dropdown trickery (String)lowPowerIndicatorPreset;
lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold;
lp[FPSTR(_duration)] = lowPowerIndicatorDuration;
}
void getUsermodConfigFromJsonObject(JsonObject& battery)
{
getJsonValue(battery[F("type")], cfg.type);
getJsonValue(battery[F("min-voltage")], cfg.minVoltage);
getJsonValue(battery[F("max-voltage")], cfg.maxVoltage);
getJsonValue(battery[F("calibration")], cfg.calibration);
getJsonValue(battery[F("voltage-multiplier")], cfg.voltageMultiplier);
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
setHomeAssistantDiscovery(battery[FPSTR(_haDiscovery)] | HomeAssistantDiscovery);
JsonObject ao = battery[F("auto-off")];
setAutoOffEnabled(ao[FPSTR(_enabled)] | autoOffEnabled);
setAutoOffThreshold(ao[FPSTR(_threshold)] | autoOffThreshold);
JsonObject lp = battery[F("indicator")];
setLowPowerIndicatorEnabled(lp[FPSTR(_enabled)] | lowPowerIndicatorEnabled);
setLowPowerIndicatorPreset(lp[FPSTR(_preset)] | lowPowerIndicatorPreset);
setLowPowerIndicatorThreshold(lp[FPSTR(_threshold)] | lowPowerIndicatorThreshold);
lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
setLowPowerIndicatorDuration(lp[FPSTR(_duration)] | lowPowerIndicatorDuration);
if(initDone)
bat->update(cfg);
}
/**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void addToJsonState(JsonObject& root)
{
JsonObject battery = root.createNestedObject(FPSTR(_name));
if (battery.isNull())
battery = root.createNestedObject(FPSTR(_name));
addBatteryToJsonObject(battery, true);
DEBUGUM_PRINTLN(F("Battery state exposed in JSON API."));
}
/**
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
/*
void readFromJsonState(JsonObject& root)
{
if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject battery = root[FPSTR(_name)];
if (!battery.isNull()) {
getUsermodConfigFromJsonObject(battery);
DEBUGUM_PRINTLN(F("Battery state read from JSON API."));
}
}
*/
/**
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
* If you want to force saving the current state, use serializeConfig() in your loop().
*
* CAUTION: serializeConfig() will initiate a filesystem write operation.
* It might cause the LEDs to stutter and will cause flash wear if called too often.
* Use it sparingly and always in the loop, never in network callbacks!
*
* addToConfig() will make your settings editable through the Usermod Settings page automatically.
*
* Usermod Settings Overview:
* - Numeric values are treated as floats in the browser.
* - If the numeric value entered into the browser contains a decimal point, it will be parsed as a C float
* before being returned to the Usermod. The float data type has only 6-7 decimal digits of precision, and
* doubles are not supported, numbers will be rounded to the nearest float value when being parsed.
* The range accepted by the input field is +/- 1.175494351e-38 to +/- 3.402823466e+38.
* - If the numeric value entered into the browser doesn't contain a decimal point, it will be parsed as a
* C int32_t (range: -2147483648 to 2147483647) before being returned to the usermod.
* Overflows or underflows are truncated to the max/min value for an int32_t, and again truncated to the type
* used in the Usermod when reading the value from ArduinoJson.
* - Pin values can be treated differently from an integer value by using the key name "pin"
* - "pin" can contain a single or array of integer values
* - On the Usermod Settings page there is simple checking for pin conflicts and warnings for special pins
* - Red color indicates a conflict. Yellow color indicates a pin with a warning (e.g. an input-only pin)
* - Tip: use int8_t to store the pin value in the Usermod, so a -1 value (pin not set) can be used
*
* See usermod_v2_auto_save.h for an example that saves Flash space by reusing ArduinoJson key name strings
*
* If you need a dedicated settings page with custom layout for your Usermod, that takes a lot more work.
* You will have to add the setting to the HTML, xml.cpp and set.cpp manually.
* See the WLED Soundreactive fork (code and wiki) for reference. https://github.com/atuline/WLED
*
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
*/
void addToConfig(JsonObject& root)
{
JsonObject battery = root.createNestedObject(FPSTR(_name));
if (battery.isNull()) {
battery = root.createNestedObject(FPSTR(_name));
}
#ifdef ARDUINO_ARCH_ESP32
battery[F("pin")] = batteryPin;
#endif
addBatteryToJsonObject(battery, false);
// read voltage in case calibration or voltage multiplier changed to see immediate effect
bat->setVoltage(readVoltage());
DEBUGUM_PRINTLN(F("Battery config saved."));
}
void appendConfigData()
{
// Total: 462 Bytes
oappend(SET_F("td=addDropdown('Battery','type');")); // 34 Bytes
oappend(SET_F("addOption(td,'Unkown','0');")); // 28 Bytes
oappend(SET_F("addOption(td,'LiPo','1');")); // 26 Bytes
oappend(SET_F("addOption(td,'LiOn','2');")); // 26 Bytes
oappend(SET_F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
oappend(SET_F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes
oappend(SET_F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes
oappend(SET_F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes
oappend(SET_F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes
oappend(SET_F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes
oappend(SET_F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes
oappend(SET_F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes
// this option list would exeed the oappend() buffer
// a list of all presets to select one from
// oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
// the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);"));
// for(int8_t i=1; i < 42; i++) {
// oappend(SET_F("addOption(bd, 'Preset#"));
// oappendi(i);
// oappend(SET_F("',"));
// oappendi(i);
// oappend(SET_F(");"));
// }
}
/**
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
* This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page)
*
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
*
* Return true in case the config values returned from Usermod Settings were complete, or false if you'd like WLED to save your defaults to disk (so any missing values are editable in Usermod Settings)
*
* getJsonValue() returns false if the value is missing, or copies the value into the variable provided and returns true if the value is present
* The configComplete variable is true only if the "exampleUsermod" object and all values are present. If any values are missing, WLED will know to call addToConfig() to save them
*
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
*/
bool readFromConfig(JsonObject& root)
{
#ifdef ARDUINO_ARCH_ESP32
int8_t newBatteryPin = batteryPin;
#endif
JsonObject battery = root[FPSTR(_name)];
if (battery.isNull())
{
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
#ifdef ARDUINO_ARCH_ESP32
newBatteryPin = battery[F("pin")] | newBatteryPin;
#endif
setMinBatteryVoltage(battery[F("min-voltage")] | bat->getMinVoltage());
setMaxBatteryVoltage(battery[F("max-voltage")] | bat->getMaxVoltage());
setCalibration(battery[F("calibration")] | bat->getCalibration());
setVoltageMultiplier(battery[F("voltage-multiplier")] | bat->getVoltageMultiplier());
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
setHomeAssistantDiscovery(battery[FPSTR(_haDiscovery)] | HomeAssistantDiscovery);
getUsermodConfigFromJsonObject(battery);
#ifdef ARDUINO_ARCH_ESP32
if (!initDone)
{
// first run: reading from cfg.json
batteryPin = newBatteryPin;
DEBUGUM_PRINTLN(F(" config loaded."));
}
else
{
DEBUGUM_PRINTLN(F(" config (re)loaded."));
// changing parameters from settings page
if (newBatteryPin != batteryPin)
{
// deallocate pin
PinManager::deallocatePin(batteryPin, PinOwner::UM_Battery);
batteryPin = newBatteryPin;
// initialise
setup();
}
}
#endif
return !battery[FPSTR(_readInterval)].isNull();
}
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent)
{
// Home Assistant Autodiscovery
if (!HomeAssistantDiscovery)
return;
// battery percentage
char mqttBatteryTopic[128];
snprintf_P(mqttBatteryTopic, 127, PSTR("%s/battery"), mqttDeviceTopic);
this->addMqttSensor(F("Battery"), "sensor", mqttBatteryTopic, "battery", "%", true);
// voltage
char mqttVoltageTopic[128];
snprintf_P(mqttVoltageTopic, 127, PSTR("%s/voltage"), mqttDeviceTopic);
this->addMqttSensor(F("Voltage"), "sensor", mqttVoltageTopic, "voltage", "V", true);
}
#endif
/*
*
* Getter and Setter. Just in case some other usermod wants to interact with this in the future
*
*/
/**
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
{
return USERMOD_ID_BATTERY;
}
/**
* get currently active battery type
*/
batteryType getBatteryType()
{
return cfg.type;
}
/**
*
*/
unsigned long getReadingInterval()
{
return readingInterval;
}
/**
* minimum repetition is 3000ms (3s)
*/
void setReadingInterval(unsigned long newReadingInterval)
{
readingInterval = max((unsigned long)3000, newReadingInterval);
}
/**
* Get lowest configured battery voltage
*/
float getMinBatteryVoltage()
{
return bat->getMinVoltage();
}
/**
* Set lowest battery voltage
* can't be below 0 volt
*/
void setMinBatteryVoltage(float voltage)
{
bat->setMinVoltage(voltage);
}
/**
* Get highest configured battery voltage
*/
float getMaxBatteryVoltage()
{
return bat->getMaxVoltage();
}
/**
* Set highest battery voltage
* can't be below minBatteryVoltage
*/
void setMaxBatteryVoltage(float voltage)
{
bat->setMaxVoltage(voltage);
}
/**
* Get the calculated voltage
* formula: (adc pin value / adc precision * max voltage) + calibration
*/
float getVoltage()
{
return bat->getVoltage();
}
/**
* Get the mapped battery level (0 - 100) based on voltage
* important: voltage can drop when a load is applied, so its only an estimate
*/
int8_t getBatteryLevel()
{
return bat->getLevel();
}
/**
* Get the configured calibration value
* a offset value to fine-tune the calculated voltage.
*/
float getCalibration()
{
return bat->getCalibration();
}
/**
* Set the voltage calibration offset value
* a offset value to fine-tune the calculated voltage.
*/
void setCalibration(float offset)
{
bat->setCalibration(offset);
}
/**
* Set the voltage multiplier value
* A multiplier that may need adjusting for different voltage divider setups
*/
void setVoltageMultiplier(float multiplier)
{
bat->setVoltageMultiplier(multiplier);
}
/*
* Get the voltage multiplier value
* A multiplier that may need adjusting for different voltage divider setups
*/
float getVoltageMultiplier()
{
return bat->getVoltageMultiplier();
}
/**
* Get auto-off feature enabled status
* is auto-off enabled, true/false
*/
bool getAutoOffEnabled()
{
return autoOffEnabled;
}
/**
* Set auto-off feature status
*/
void setAutoOffEnabled(bool enabled)
{
autoOffEnabled = enabled;
}
/**
* Get auto-off threshold in percent (0-100)
*/
int8_t getAutoOffThreshold()
{
return autoOffThreshold;
}
/**
* Set auto-off threshold in percent (0-100)
*/
void setAutoOffThreshold(int8_t threshold)
{
autoOffThreshold = min((int8_t)100, max((int8_t)0, threshold));
// when low power indicator is enabled the auto-off threshold cannot be above indicator threshold
autoOffThreshold = lowPowerIndicatorEnabled /*&& autoOffEnabled*/ ? min(lowPowerIndicatorThreshold-1, (int)autoOffThreshold) : autoOffThreshold;
}
/**
* Get low-power-indicator feature enabled status
* is the low-power-indicator enabled, true/false
*/
bool getLowPowerIndicatorEnabled()
{
return lowPowerIndicatorEnabled;
}
/**
* Set low-power-indicator feature status
*/
void setLowPowerIndicatorEnabled(bool enabled)
{
lowPowerIndicatorEnabled = enabled;
}
/**
* Get low-power-indicator preset to activate when low power is detected
*/
int8_t getLowPowerIndicatorPreset()
{
return lowPowerIndicatorPreset;
}
/**
* Set low-power-indicator preset to activate when low power is detected
*/
void setLowPowerIndicatorPreset(int8_t presetId)
{
// String tmp = ""; For what ever reason this doesn't work :(
// lowPowerIndicatorPreset = getPresetName(presetId, tmp) ? presetId : lowPowerIndicatorPreset;
lowPowerIndicatorPreset = presetId;
}
/*
* Get low-power-indicator threshold in percent (0-100)
*/
int8_t getLowPowerIndicatorThreshold()
{
return lowPowerIndicatorThreshold;
}
/**
* Set low-power-indicator threshold in percent (0-100)
*/
void setLowPowerIndicatorThreshold(int8_t threshold)
{
lowPowerIndicatorThreshold = threshold;
// when auto-off is enabled the indicator threshold cannot be below auto-off threshold
lowPowerIndicatorThreshold = autoOffEnabled /*&& lowPowerIndicatorEnabled*/ ? max(autoOffThreshold+1, (int)lowPowerIndicatorThreshold) : max(5, (int)lowPowerIndicatorThreshold);
}
/**
* Get low-power-indicator duration in seconds
*/
int8_t getLowPowerIndicatorDuration()
{
return lowPowerIndicatorDuration;
}
/**
* Set low-power-indicator duration in seconds
*/
void setLowPowerIndicatorDuration(int8_t duration)
{
lowPowerIndicatorDuration = duration;
}
/**
* Get low-power-indicator status when the indication is done this returns true
*/
bool getLowPowerIndicatorDone()
{
return lowPowerIndicationDone;
}
/**
* Set Home Assistant auto discovery
*/
void setHomeAssistantDiscovery(bool enable)
{
HomeAssistantDiscovery = enable;
}
/**
* Get Home Assistant auto discovery
*/
bool getHomeAssistantDiscovery()
{
return HomeAssistantDiscovery;
}
};
// strings to reduce flash memory usage (used more than twice)
const char UsermodBattery::_name[] PROGMEM = "Battery";
const char UsermodBattery::_readInterval[] PROGMEM = "interval";
const char UsermodBattery::_enabled[] PROGMEM = "enabled";
const char UsermodBattery::_threshold[] PROGMEM = "threshold";
const char UsermodBattery::_preset[] PROGMEM = "preset";
const char UsermodBattery::_duration[] PROGMEM = "duration";
const char UsermodBattery::_init[] PROGMEM = "init";
const char UsermodBattery::_haDiscovery[] PROGMEM = "HA-discovery";

View File

@@ -114,8 +114,8 @@ class UsermodCronixie : public Usermod {
//W Week of Month | WW Week of Year
//D Day of Week | DD Day Of Month | DDD Day Of Year
DEBUG_PRINT("cset ");
DEBUG_PRINTLN(cronixieDisplay);
DEBUGUM_PRINT(F("cset "));
DEBUGUM_PRINTLN(cronixieDisplay);
for (int i = 0; i < 6; i++)
{
@@ -160,13 +160,13 @@ class UsermodCronixie : public Usermod {
//case 'v': break; //user var1
}
}
DEBUG_PRINT("result ");
DEBUGUM_PRINT(F("result "));
for (int i = 0; i < 5; i++)
{
DEBUG_PRINT((int)dP[i]);
DEBUG_PRINT(" ");
DEBUGUM_PRINT((int)dP[i]);
DEBUGUM_PRINT(" ");
}
DEBUG_PRINTLN((int)dP[5]);
DEBUGUM_PRINTLN((int)dP[5]);
_overlayCronixie(); // refresh
}
@@ -271,6 +271,7 @@ class UsermodCronixie : public Usermod {
{
if (root["nx"].is<const char*>()) {
strncpy(cronixieDisplay, root["nx"], 6);
setCronixie();
}
}

View File

@@ -1,6 +1,10 @@
#pragma once
#include "wled.h"
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#include <dht_nonblocking.h>
@@ -45,7 +49,7 @@
#endif
// how many seconds after boot to take first measurement, 90 seconds
// 90 gives enough time to OTA update firmware if this crashses
// 90 gives enough time to OTA update firmware if this crashes
#ifndef USERMOD_DHT_FIRST_MEASUREMENT_AT
#define USERMOD_DHT_FIRST_MEASUREMENT_AT 90000
#endif

View File

@@ -22,8 +22,12 @@
//class name. Use something descriptive and leave the ": public Usermod" part :)
class MyExampleUsermod : public Usermod {
private:
//Private class members. You can declare variables and functions only accessible to your usermod here
// Private class members. You can declare variables and functions only accessible to your usermod here
bool enabled = false;
bool initDone = false;
unsigned long lastTime = 0;
// set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer)
@@ -37,15 +41,56 @@ class MyExampleUsermod : public Usermod {
long testLong;
int8_t testPins[2];
// string that are used multiple time (this will save some flash memory)
static const char _name[];
static const char _enabled[];
// any private methods should go here (non-inline method should be defined out of class)
void publishMqtt(const char* state, bool retain = false); // example for publishing MQTT message
public:
//Functions called by WLED
// non WLED related methods, may be used for data exchange between usermods (non-inline methods should be defined out of class)
/**
* Enable/Disable the usermod
*/
inline void enable(bool enable) { enabled = enable; }
/**
* Get usermod enabled/disabled state
*/
inline bool isEnabled() { return enabled; }
// in such case add the following to another usermod:
// in private vars:
// #ifdef USERMOD_EXAMPLE
// MyExampleUsermod* UM;
// #endif
// in setup()
// #ifdef USERMOD_EXAMPLE
// UM = (MyExampleUsermod*) UsermodManager::lookup(USERMOD_ID_EXAMPLE);
// #endif
// somewhere in loop() or other member method
// #ifdef USERMOD_EXAMPLE
// if (UM != nullptr) isExampleEnabled = UM->isEnabled();
// if (!isExampleEnabled) UM->enable(true);
// #endif
// methods called by WLED (can be inlined as they are called only once but if you call them explicitly define them out of class)
/*
* setup() is called once at boot. WiFi is not yet connected at this point.
* readFromConfig() is called prior to setup()
* You can use it to initialize variables, sensors or similar.
*/
void setup() {
void setup() override {
// do your set-up here
//Serial.println("Hello from my usermod!");
initDone = true;
}
@@ -53,7 +98,7 @@ class MyExampleUsermod : public Usermod {
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
void connected() {
void connected() override {
//Serial.println("Connected to WiFi!");
}
@@ -68,7 +113,12 @@ class MyExampleUsermod : public Usermod {
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
* Instead, use a timer check as shown here.
*/
void loop() {
void loop() override {
// if usermod is disabled or called during strip updating just exit
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
if (!enabled || strip.isUpdating()) return;
// do your magic here
if (millis() - lastTime > 1000) {
//Serial.println("I'm alive!");
lastTime = millis();
@@ -81,28 +131,39 @@ class MyExampleUsermod : public Usermod {
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
/*
void addToJsonInfo(JsonObject& root)
void addToJsonInfo(JsonObject& root) override
{
int reading = 20;
//this code adds "u":{"Light":[20," lux"]} to the info object
// if "u" object does not exist yet wee need to create it
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray lightArr = user.createNestedArray("Light"); //name
lightArr.add(reading); //value
lightArr.add(" lux"); //unit
//this code adds "u":{"ExampleUsermod":[20," lux"]} to the info object
//int reading = 20;
//JsonArray lightArr = user.createNestedArray(FPSTR(_name))); //name
//lightArr.add(reading); //value
//lightArr.add(F(" lux")); //unit
// if you are implementing a sensor usermod, you may publish sensor data
//JsonObject sensor = root[F("sensor")];
//if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
//temp = sensor.createNestedArray(F("light"));
//temp.add(reading);
//temp.add(F("lux"));
}
*/
/*
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void addToJsonState(JsonObject& root)
void addToJsonState(JsonObject& root) override
{
//root["user0"] = userVar0;
if (!initDone || !enabled) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (usermod.isNull()) usermod = root.createNestedObject(FPSTR(_name));
//usermod["user0"] = userVar0;
}
@@ -110,9 +171,16 @@ class MyExampleUsermod : public Usermod {
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject& root)
void readFromJsonState(JsonObject& root) override
{
userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) {
// expect JSON usermod data in usermod name object: {"ExampleUsermod:{"user0":10}"}
userVar0 = usermod["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
}
// you can as well check WLED state JSON keys
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
}
@@ -152,10 +220,12 @@ class MyExampleUsermod : public Usermod {
*
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
*/
void addToConfig(JsonObject& root)
void addToConfig(JsonObject& root) override
{
JsonObject top = root.createNestedObject("exampleUsermod");
top["great"] = userVar0; //save these vars persistently whenever settings are saved
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
//save these vars persistently whenever settings are saved
top["great"] = userVar0;
top["testBool"] = testBool;
top["testInt"] = testInt;
top["testLong"] = testLong;
@@ -183,12 +253,12 @@ class MyExampleUsermod : public Usermod {
*
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
*/
bool readFromConfig(JsonObject& root)
bool readFromConfig(JsonObject& root) override
{
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
JsonObject top = root["exampleUsermod"];
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
@@ -201,6 +271,8 @@ class MyExampleUsermod : public Usermod {
// A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing
configComplete &= getJsonValue(top["testInt"], testInt, 42);
configComplete &= getJsonValue(top["testLong"], testLong, -42424242);
// "pin" fields have special handling in settings page (or some_pin as well)
configComplete &= getJsonValue(top["pin"][0], testPins[0], -1);
configComplete &= getJsonValue(top["pin"][1], testPins[1], -1);
@@ -208,26 +280,127 @@ class MyExampleUsermod : public Usermod {
}
/*
* appendConfigData() is called when user enters usermod settings page
* it may add additional metadata for certain entry fields (adding drop down is possible)
* be careful not to add too much as oappend() buffer is limited to 3k
*/
void appendConfigData() override
{
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'<i>(this is a great config value)</i>');"));
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');"));
oappend(SET_F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F("','testInt');"));
oappend(SET_F("addOption(dd,'Nothing',0);"));
oappend(SET_F("addOption(dd,'Everything',42);"));
}
/*
* handleOverlayDraw() is called just before every show() (LED strip update frame) after effects have set the colors.
* Use this to blank out some LEDs or set them to a different color regardless of the set effect mode.
* Commonly used for custom clocks (Cronixie, 7 segment)
*/
void handleOverlayDraw()
void handleOverlayDraw() override
{
//strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black
}
/**
* handleButton() can be used to override default button behaviour. Returning true
* will prevent button working in a default way.
* Replicating button.cpp
*/
bool handleButton(uint8_t b) override {
yield();
// ignore certain button types as they may have other consequences
if (!enabled
|| buttonType[b] == BTN_TYPE_NONE
|| buttonType[b] == BTN_TYPE_RESERVED
|| buttonType[b] == BTN_TYPE_PIR_SENSOR
|| buttonType[b] == BTN_TYPE_ANALOG
|| buttonType[b] == BTN_TYPE_ANALOG_INVERTED) {
return false;
}
bool handled = false;
// do your button handling here
return handled;
}
#ifndef WLED_DISABLE_MQTT
/**
* handling of MQTT message
* topic only contains stripped topic (part after /wled/MAC)
*/
bool onMqttMessage(char* topic, char* payload) override {
// check if we received a command
//if (strlen(topic) == 8 && strncmp_P(topic, PSTR("/command"), 8) == 0) {
// String action = payload;
// if (action == "on") {
// enabled = true;
// return true;
// } else if (action == "off") {
// enabled = false;
// return true;
// } else if (action == "toggle") {
// enabled = !enabled;
// return true;
// }
//}
return false;
}
/**
* onMqttConnect() is called when MQTT connection is established
*/
void onMqttConnect(bool sessionPresent) override {
// do any MQTT related initialisation here
//publishMqtt("I am alive!");
}
#endif
/**
* onStateChanged() is used to detect WLED state change
* @mode parameter is CALL_MODE_... parameter used for notifications
*/
void onStateChange(uint8_t mode) override {
// do something if WLED state changed (color, brightness, effect, preset, etc)
}
/*
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
uint16_t getId() override
{
return USERMOD_ID_EXAMPLE;
}
//More methods can be added in the future, this example will then be extended.
//Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
};
};
// add more strings here to reduce flash memory usage
const char MyExampleUsermod::_name[] PROGMEM = "ExampleUsermod";
const char MyExampleUsermod::_enabled[] PROGMEM = "enabled";
// implementation of non-inline member methods
void MyExampleUsermod::publishMqtt(const char* state, bool retain)
{
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED) {
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
strcat_P(subuf, PSTR("/example"));
mqtt->publish(subuf, 0, retain, state);
}
#endif
}

View File

@@ -133,13 +133,13 @@ private:
return false;
}
read32(bmpFS); // filesize in bytes
read32(bmpFS); // reserved
(void) read32(bmpFS); // filesize in bytes
(void) read32(bmpFS); // reserved
seekOffset = read32(bmpFS); // start of bitmap
headerSize = read32(bmpFS); // header size
w = read32(bmpFS); // width
h = read32(bmpFS); // height
read16(bmpFS); // color planes (must be 1)
(void) read16(bmpFS); // color planes (must be 1)
bitDepth = read16(bmpFS);
if (read32(bmpFS) != 0 || (bitDepth != 24 && bitDepth != 1 && bitDepth != 4 && bitDepth != 8)) {
@@ -151,9 +151,9 @@ private:
uint32_t palette[256];
if (bitDepth <= 8) // 1,4,8 bit bitmap: read color palette
{
read32(bmpFS); read32(bmpFS); read32(bmpFS); // size, w resolution, h resolution
(void) read32(bmpFS); (void) read32(bmpFS); (void) read32(bmpFS); // size, w resolution, h resolution
paletteSize = read32(bmpFS);
if (paletteSize == 0) paletteSize = bitDepth * bitDepth; //if 0, size is 2^bitDepth
if (paletteSize == 0) paletteSize = 1 << bitDepth; //if 0, size is 2^bitDepth
bmpFS.seek(14 + headerSize); // start of color palette
for (uint16_t i = 0; i < paletteSize; i++) {
palette[i] = read32(bmpFS);
@@ -198,7 +198,7 @@ private:
}
b = c; g = c >> 8; r = c >> 16;
}
if (dimming != 255) { // only dimm when needed
if (dimming != 255) { // only dim when needed
r *= dimming; g *= dimming; b *= dimming;
r = r >> 8; g = g >> 8; b = b >> 8;
}

View File

@@ -91,7 +91,7 @@ class ElekstubeIPSUsermod : public Usermod {
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_tubeSeg)] = tfts.tubeSegment;
top[FPSTR(_digitOffset)] = tfts.digitOffset;
DEBUG_PRINTLN(F("EleksTube config saved."));
DEBUGUM_PRINTLN(F("EleksTube config saved."));
}
/**
@@ -101,11 +101,11 @@ class ElekstubeIPSUsermod : public Usermod {
*/
bool readFromConfig(JsonObject &root) {
// we look for JSON object: {"EleksTubeIPS": {"tubeSegment": 1, "digitOffset": 0}}
DEBUG_PRINT(FPSTR(_name));
DEBUGUM_PRINT(FPSTR(_name));
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}

View File

@@ -1,3 +1,7 @@
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
@@ -11,23 +15,23 @@ OneWire oneWire(13);
DallasTemperature sensor(&oneWire);
long temptimer = millis();
long lastMeasure = 0;
#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit
#define Celsius // Show temperature measurement in Celsius otherwise is in Fahrenheit
// If display does not work or looks corrupted check the
// constructor reference:
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
// or check the gallery:
// https://github.com/olikraus/u8g2/wiki/gallery
// --> First choise of cheap I2C OLED 128X32 0.91"
// --> First choice of cheap I2C OLED 128X32 0.91"
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA
// --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3"
// --> Second choice of cheap I2C OLED 128X64 0.96" or 1.3"
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA
// gets called once at boot. Do all initialization that doesn't depend on
// network here
void userSetup() {
sensor.begin(); //Start Dallas temperature sensor
u8x8.begin();
//u8x8.setFlipMode(1); //Uncoment if using WLED Wemos shield
//u8x8.setFlipMode(1); //Un-comment if using WLED Wemos shield
u8x8.setPowerSave(0);
u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
u8x8.setFont(u8x8_font_chroma48medium8_r);
@@ -67,7 +71,7 @@ void userLoop() {
if (mqtt != nullptr)
{
sensor.requestTemperatures();
//Gets prefered temperature scale based on selection in definitions section
//Gets preferred temperature scale based on selection in definitions section
#ifdef Celsius
float board_temperature = sensor.getTempCByIndex(0);
#else
@@ -134,11 +138,11 @@ void userLoop() {
// First row with Wifi name
u8x8.setCursor(1, 0);
u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
// Print `~` char to indicate that SSID is longer, than owr dicplay
// Print `~` char to indicate that SSID is longer than our display
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
// Second row with IP or Password
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)

View File

@@ -1,3 +1,7 @@
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
@@ -6,7 +10,7 @@
void UpdateBME280Data();
#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit
#define Celsius // Show temperature measurement in Celsius otherwise is in Fahrenheit
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
@@ -16,14 +20,14 @@ uint8_t SDA_PIN = 21;
#else //ESP8266 boards
uint8_t SCL_PIN = 5;
uint8_t SDA_PIN = 4;
// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8
// uint8_t RST_PIN = 16; // Un-comment for Heltec WiFi-Kit-8
#endif
//The SCL and SDA pins are defined here.
//ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21
#define U8X8_PIN_SCL SCL_PIN
#define U8X8_PIN_SDA SDA_PIN
//#define U8X8_PIN_RESET RST_PIN // Uncoment for Heltec WiFi-Kit-8
//#define U8X8_PIN_RESET RST_PIN // Un-comment for Heltec WiFi-Kit-8
// If display does not work or looks corrupted check the
// constructor reference:
@@ -32,9 +36,9 @@ uint8_t SDA_PIN = 4;
// https://github.com/olikraus/u8g2/wiki/gallery
// --> First choise of cheap I2C OLED 128X32 0.91"
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA
// --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3"
// --> Second choice of cheap I2C OLED 128X64 0.96" or 1.3"
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA
// --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91"
// --> Third choice of Heltec WiFi-Kit-8 OLED 128X32 0.91"
//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constructor for Heltec WiFi-Kit-8
// gets called once at boot. Do all initialization that doesn't depend on network here
@@ -177,11 +181,11 @@ void userLoop() {
// First row with Wifi name
u8x8.setCursor(1, 0);
u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
// Print `~` char to indicate that SSID is longer, than owr dicplay
// Print `~` char to indicate that SSID is longer than our display
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
// Second row with IP or Password
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)

View File

@@ -2,7 +2,7 @@
**Attention: This usermod compiles only for ESP8266**
This usermod-v2 modification performs a ping request to a local IP address every 60 seconds. This ensures WLED net services remain accessible in some problematic WLAN environments.
This usermod-v2 modification performs a ping request to a local IP address every 60 seconds. This ensures WLED net services remain accessible in some problematic WiFi environments.
The modification works with static or DHCP IP address configuration.
@@ -24,7 +24,7 @@ The usermod supports the following state changes:
| JSON key | Value range | Description |
|-------------|------------------|---------------------------------|
| PingDelayMs | 5000 to 18000000 | Deactivdate/activate the sensor |
| PingDelayMs | 5000 to 18000000 | Deactivate/activate the sensor |
Changes also persist after a reboot.
@@ -59,10 +59,10 @@ void registerUsermods()
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
//usermods.add(new UsermodTemperature());
//usermods.add(new UsermodRenameMe());
usermods.add(new FixUnreachableNetServices());
//UsermodManager::add(new MyExampleUsermod());
//UsermodManager::add(new UsermodTemperature());
//UsermodManager::add(new UsermodRenameMe());
UsermodManager::add(new FixUnreachableNetServices());
}
```

View File

@@ -0,0 +1,77 @@
# Usermod INA226
This Usermod is designed to read values from an INA226 sensor and output the following:
- Current
- Voltage
- Power
- Shunt Voltage
- Overflow status
## Configuration
The following settings can be configured in the Usermod Menu:
- **Enabled**: Enable or disable the usermod.
- **I2CAddress**: The I2C address in decimal. Default is 64 (0x40).
- **CheckInterval**: Number of seconds between readings. This should be higher than the time it takes to make a reading, determined by the two next options.
- **INASamples**: The number of samples to configure the INA226 to use for a measurement. Higher counts provide more accuracy. See the 'Understanding Samples and Conversion Times' section for more details.
- **INAConversionTime**: The time to use on converting and preparing readings on the INA226. Higher times provide more precision. See the 'Understanding Samples and Conversion Times' section for more details.
- **Decimals**: Number of decimals in the output.
- **ShuntResistor**: Shunt resistor value in milliohms. An R100 shunt resistor should be written as "100", while R010 should be "10".
- **CurrentRange**: Expected maximum current in milliamps (e.g., 5 A = 5000 mA).
- **MqttPublish**: Enable or disable MQTT publishing.
- **MqttPublishAlways**: Publish always, regardless if there is a change.
- **MqttHomeAssistantDiscovery**: Enable Home Assistant discovery.
## Dependencies
These must be added under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
- Libraries
- `wollewald/INA226_WE@~1.2.9` (by [wollewald](https://registry.platformio.org/libraries/wollewald/INA226_WE))
- `Wire`
## Understanding Samples and Conversion Times
The INA226 uses a programmable ADC with configurable conversion times and averaging to optimize the measurement accuracy and speed. The conversion time and number of samples are determined based on the `INASamples` and `INAConversionTime` settings. The following table outlines the possible combinations:
| Conversion Time (μs) | 1 Sample | 4 Samples | 16 Samples | 64 Samples | 128 Samples | 256 Samples | 512 Samples | 1024 Samples |
|----------------------|----------|-----------|------------|------------|-------------|-------------|-------------|--------------|
| 140 | 0.28 ms | 1.12 ms | 4.48 ms | 17.92 ms | 35.84 ms | 71.68 ms | 143.36 ms | 286.72 ms |
| 204 | 0.408 ms | 1.632 ms | 6.528 ms | 26.112 ms | 52.224 ms | 104.448 ms | 208.896 ms | 417.792 ms |
| 332 | 0.664 ms | 2.656 ms | 10.624 ms | 42.496 ms | 84.992 ms | 169.984 ms | 339.968 ms | 679.936 ms |
| 588 | 1.176 ms | 4.704 ms | 18.816 ms | 75.264 ms | 150.528 ms | 301.056 ms | 602.112 ms | 1204.224 ms |
| 1100 | 2.2 ms | 8.8 ms | 35.2 ms | 140.8 ms | 281.6 ms | 563.2 ms | 1126.4 ms | 2252.8 ms |
| 2116 | 4.232 ms | 16.928 ms | 67.712 ms | 270.848 ms | 541.696 ms | 1083.392 ms | 2166.784 ms | 4333.568 ms |
| 4156 | 8.312 ms | 33.248 ms | 132.992 ms | 531.968 ms | 1063.936 ms | 2127.872 ms | 4255.744 ms | 8511.488 ms |
| 8244 | 16.488 ms| 65.952 ms | 263.808 ms | 1055.232 ms| 2110.464 ms | 4220.928 ms | 8441.856 ms | 16883.712 ms |
It is important to pick a combination that provides the needed balance between accuracy and precision while ensuring new readings within the `CheckInterval` setting. When `USERMOD_INA226_DEBUG` is defined, the info pane contains the expected time to make a reading, which can be seen in the table above.
As an example, if you want a new reading every 5 seconds (`CheckInterval`), a valid combination is `256 samples` and `4156 μs` which would provide new values every 2.1 seconds.
The picked values also slightly affect power usage. If the `CheckInterval` is set to more than 20 seconds, the INA226 is configured in `triggered` reading mode, where it only uses power as long as it's working. Then the conversion time and average samples counts determine how long the chip stays turned on every `CheckInterval` time.
### Calculating Current and Power
The INA226 calculates current by measuring the differential voltage across a shunt resistor and using the calibration register value to convert this measurement into current. Power is calculated by multiplying the current by the bus voltage.
For detailed programming information and register configurations, refer to the [INA226 datasheet](https://www.ti.com/product/INA226).
## Author
[@LordMike](https://github.com/LordMike)
## Compiling
To enable, compile with `USERMOD_INA226` defined (e.g. in `platformio_override.ini`).
```ini
[env:ina226_example]
extends = env:esp32dev
build_flags =
${common.build_flags} ${esp32.build_flags}
-D USERMOD_INA226
; -D USERMOD_INA226_DEBUG ; -- add a debug status to the info modal
lib_deps =
${esp32.lib_deps}
wollewald/INA226_WE@~1.2.9
```

View File

@@ -0,0 +1,9 @@
[env:ina226_example]
extends = env:esp32dev
build_flags =
${common.build_flags} ${esp32.build_flags}
-D USERMOD_INA226
; -D USERMOD_INA226_DEBUG ; -- add a debug status to the info modal
lib_deps =
${esp32.lib_deps}
wollewald/INA226_WE@~1.2.9

View File

@@ -0,0 +1,556 @@
#pragma once
#include "wled.h"
#include <INA226_WE.h>
#define INA226_ADDRESS 0x40 // Default I2C address for INA226
#define DEFAULT_CHECKINTERVAL 60000
#define DEFAULT_INASAMPLES 128
#define DEFAULT_INASAMPLESENUM AVERAGE_128
#define DEFAULT_INACONVERSIONTIME 1100
#define DEFAULT_INACONVERSIONTIMEENUM CONV_TIME_1100
// A packed version of all INA settings enums and their human friendly counterparts packed into a 32 bit structure
// Some values are shifted and need to be preprocessed before usage
struct InaSettingLookup
{
uint16_t avgSamples : 11; // Max 1024, which could be in 10 bits if we shifted by 1; if we somehow handle the edge case with "1"
uint8_t avgEnum : 4; // Shift by 8 to get the INA226_AVERAGES value, accepts 0x00 to 0x0F, we need 0x00 to 0x0E
uint16_t convTimeUs : 14; // We could save 2 bits by shifting this, but we won't save anything at present.
INA226_CONV_TIME convTimeEnum : 3; // Only the lowest 3 bits are defined in the conversion time enumerations
};
const InaSettingLookup _inaSettingsLookup[] = {
{1024, AVERAGE_1024 >> 8, 8244, CONV_TIME_8244},
{512, AVERAGE_512 >> 8, 4156, CONV_TIME_4156},
{256, AVERAGE_256 >> 8, 2116, CONV_TIME_2116},
{128, AVERAGE_128 >> 8, 1100, CONV_TIME_1100},
{64, AVERAGE_64 >> 8, 588, CONV_TIME_588},
{16, AVERAGE_16 >> 8, 332, CONV_TIME_332},
{4, AVERAGE_4 >> 8, 204, CONV_TIME_204},
{1, AVERAGE_1 >> 8, 140, CONV_TIME_140}};
// Note: Will update the provided arg to be the correct value
INA226_AVERAGES getAverageEnum(uint16_t &samples)
{
for (const auto &setting : _inaSettingsLookup)
{
// If a user supplies 2000 samples, we serve up the highest possible value
if (samples >= setting.avgSamples)
{
samples = setting.avgSamples;
return static_cast<INA226_AVERAGES>(setting.avgEnum << 8);
}
}
// Default value if not found
samples = DEFAULT_INASAMPLES;
return DEFAULT_INASAMPLESENUM;
}
INA226_CONV_TIME getConversionTimeEnum(uint16_t &timeUs)
{
for (const auto &setting : _inaSettingsLookup)
{
// If a user supplies 9000 μs, we serve up the highest possible value
if (timeUs >= setting.convTimeUs)
{
timeUs = setting.convTimeUs;
return setting.convTimeEnum;
}
}
// Default value if not found
timeUs = DEFAULT_INACONVERSIONTIME;
return DEFAULT_INACONVERSIONTIMEENUM;
}
class UsermodINA226 : public Usermod
{
private:
static const char _name[];
unsigned long _lastLoopCheck = 0;
unsigned long _lastTriggerTime = 0;
bool _settingEnabled : 1; // Enable the usermod
bool _mqttPublish : 1; // Publish MQTT values
bool _mqttPublishAlways : 1; // Publish always, regardless if there is a change
bool _mqttHomeAssistant : 1; // Enable Home Assistant docs
bool _initDone : 1; // Initialization is done
bool _isTriggeredOperationMode : 1; // false = continuous, true = triggered
bool _measurementTriggered : 1; // if triggered mode, then true indicates we're waiting for measurements
uint16_t _settingInaConversionTimeUs : 12; // Conversion time, shift by 2
uint16_t _settingInaSamples : 11; // Number of samples for averaging, max 1024
uint8_t _i2cAddress;
uint16_t _checkInterval; // milliseconds, user settings is in seconds
float _decimalFactor; // a power of 10 factor. 1 would be no change, 10 is one decimal, 100 is two etc. User sees a power of 10 (0, 1, 2, ..)
uint16_t _shuntResistor; // Shunt resistor value in milliohms
uint16_t _currentRange; // Expected maximum current in milliamps
uint8_t _lastStatus = 0;
float _lastCurrent = 0;
float _lastVoltage = 0;
float _lastPower = 0;
float _lastShuntVoltage = 0;
bool _lastOverflow = false;
#ifndef WLED_MQTT_DISABLE
float _lastCurrentSent = 0;
float _lastVoltageSent = 0;
float _lastPowerSent = 0;
float _lastShuntVoltageSent = 0;
bool _lastOverflowSent = false;
#endif
INA226_WE *_ina226 = nullptr;
float truncateDecimals(float val)
{
return roundf(val * _decimalFactor) / _decimalFactor;
}
void initializeINA226()
{
if (_ina226 != nullptr)
{
delete _ina226;
}
_ina226 = new INA226_WE(_i2cAddress);
if (!_ina226->init())
{
DEBUGUM_PRINTLN(F("INA226 initialization failed!"));
return;
}
_ina226->setCorrectionFactor(1.0);
uint16_t tmpShort = _settingInaSamples;
_ina226->setAverage(getAverageEnum(tmpShort));
tmpShort = _settingInaConversionTimeUs << 2;
_ina226->setConversionTime(getConversionTimeEnum(tmpShort));
if (_checkInterval >= 20000)
{
_isTriggeredOperationMode = true;
_ina226->setMeasureMode(TRIGGERED);
}
else
{
_isTriggeredOperationMode = false;
_ina226->setMeasureMode(CONTINUOUS);
}
_ina226->setResistorRange(static_cast<float>(_shuntResistor) / 1000.0, static_cast<float>(_currentRange) / 1000.0);
}
void fetchAndPushValues()
{
_lastStatus = _ina226->getI2cErrorCode();
if (_lastStatus != 0)
return;
float current = truncateDecimals(_ina226->getCurrent_mA() / 1000.0);
float voltage = truncateDecimals(_ina226->getBusVoltage_V());
float power = truncateDecimals(_ina226->getBusPower() / 1000.0);
float shuntVoltage = truncateDecimals(_ina226->getShuntVoltage_V());
bool overflow = _ina226->overflow;
#ifndef WLED_DISABLE_MQTT
mqttPublishIfChanged(F("current"), _lastCurrentSent, current, 0.01f);
mqttPublishIfChanged(F("voltage"), _lastVoltageSent, voltage, 0.01f);
mqttPublishIfChanged(F("power"), _lastPowerSent, power, 0.1f);
mqttPublishIfChanged(F("shunt_voltage"), _lastShuntVoltageSent, shuntVoltage, 0.01f);
mqttPublishIfChanged(F("overflow"), _lastOverflowSent, overflow);
#endif
_lastCurrent = current;
_lastVoltage = voltage;
_lastPower = power;
_lastShuntVoltage = shuntVoltage;
_lastOverflow = overflow;
}
void handleTriggeredMode(unsigned long currentTime)
{
if (_measurementTriggered)
{
// Test if we have a measurement every 400ms
if (currentTime - _lastTriggerTime >= 400)
{
_lastTriggerTime = currentTime;
if (_ina226->isBusy())
return;
fetchAndPushValues();
_measurementTriggered = false;
}
}
else
{
if (currentTime - _lastLoopCheck >= _checkInterval)
{
// Start a measurement and use isBusy() later to determine when it is done
_ina226->startSingleMeasurementNoWait();
_lastLoopCheck = currentTime;
_lastTriggerTime = currentTime;
_measurementTriggered = true;
}
}
}
void handleContinuousMode(unsigned long currentTime)
{
if (currentTime - _lastLoopCheck >= _checkInterval)
{
_lastLoopCheck = currentTime;
fetchAndPushValues();
}
}
~UsermodINA226()
{
delete _ina226;
_ina226 = nullptr;
}
#ifndef WLED_DISABLE_MQTT
void mqttInitialize()
{
if (!WLED_MQTT_CONNECTED || !_mqttPublish || !_mqttHomeAssistant)
return;
char topic[128];
snprintf_P(topic, 127, "%s/current", mqttDeviceTopic);
mqttCreateHassSensor(F("Current"), topic, F("current"), F("A"));
snprintf_P(topic, 127, "%s/voltage", mqttDeviceTopic);
mqttCreateHassSensor(F("Voltage"), topic, F("voltage"), F("V"));
snprintf_P(topic, 127, "%s/power", mqttDeviceTopic);
mqttCreateHassSensor(F("Power"), topic, F("power"), F("W"));
snprintf_P(topic, 127, "%s/shunt_voltage", mqttDeviceTopic);
mqttCreateHassSensor(F("Shunt Voltage"), topic, F("voltage"), F("V"));
snprintf_P(topic, 127, "%s/overflow", mqttDeviceTopic);
mqttCreateHassBinarySensor(F("Overflow"), topic);
}
void mqttPublishIfChanged(const __FlashStringHelper *topic, float &lastState, float state, float minChange)
{
if (WLED_MQTT_CONNECTED && _mqttPublish && (_mqttPublishAlways || fabsf(lastState - state) > minChange))
{
char subuf[128];
snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, (const char *)topic);
mqtt->publish(subuf, 0, false, String(state).c_str());
lastState = state;
}
}
void mqttPublishIfChanged(const __FlashStringHelper *topic, bool &lastState, bool state)
{
if (WLED_MQTT_CONNECTED && _mqttPublish && (_mqttPublishAlways || lastState != state))
{
char subuf[128];
snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, (const char *)topic);
mqtt->publish(subuf, 0, false, state ? "true" : "false");
lastState = state;
}
}
void mqttCreateHassSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement)
{
String t = String(F("homeassistant/sensor/")) + mqttClientID + "/" + name + F("/config");
StaticJsonDocument<600> doc;
doc[F("name")] = name;
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
if (unitOfMeasurement != "")
doc[F("unit_of_measurement")] = unitOfMeasurement;
if (deviceClass != "")
doc[F("device_class")] = deviceClass;
doc[F("expire_after")] = 1800;
JsonObject device = doc.createNestedObject(F("device"));
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F(WLED_BRAND);
device[F("model")] = F(WLED_PRODUCT_NAME);
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
void mqttCreateHassBinarySensor(const String &name, const String &topic)
{
String t = String(F("homeassistant/binary_sensor/")) + mqttClientID + "/" + name + F("/config");
StaticJsonDocument<600> doc;
doc[F("name")] = name;
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
JsonObject device = doc.createNestedObject(F("device"));
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F(WLED_BRAND);
device[F("model")] = F(WLED_PRODUCT_NAME);
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
#endif
public:
UsermodINA226()
{
// Default values
_settingInaSamples = DEFAULT_INASAMPLES;
_settingInaConversionTimeUs = DEFAULT_INACONVERSIONTIME;
_i2cAddress = INA226_ADDRESS;
_checkInterval = DEFAULT_CHECKINTERVAL;
_decimalFactor = 100;
_shuntResistor = 1000;
_currentRange = 1000;
}
void setup()
{
initializeINA226();
}
void loop()
{
if (!_settingEnabled || strip.isUpdating())
return;
unsigned long currentTime = millis();
if (_isTriggeredOperationMode)
{
handleTriggeredMode(currentTime);
}
else
{
handleContinuousMode(currentTime);
}
}
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent)
{
mqttInitialize();
}
#endif
uint16_t getId()
{
return USERMOD_ID_INA226;
}
void addToJsonInfo(JsonObject &root) override
{
JsonObject user = root["u"];
if (user.isNull())
user = root.createNestedObject("u");
#ifdef USERMOD_INA226_DEBUG
JsonArray temp = user.createNestedArray(F("INA226 last loop"));
temp.add(_lastLoopCheck);
temp = user.createNestedArray(F("INA226 last status"));
temp.add(_lastStatus);
temp = user.createNestedArray(F("INA226 average samples"));
temp.add(_settingInaSamples);
temp.add(F("samples"));
temp = user.createNestedArray(F("INA226 conversion time"));
temp.add(_settingInaConversionTimeUs << 2);
temp.add(F("μs"));
// INA226 uses (2 * conversion time * samples) time to take a reading.
temp = user.createNestedArray(F("INA226 expected sample time"));
uint32_t sampleTimeNeededUs = (static_cast<uint32_t>(_settingInaConversionTimeUs) << 2) * _settingInaSamples * 2;
temp.add(truncateDecimals(sampleTimeNeededUs / 1000.0));
temp.add(F("ms"));
temp = user.createNestedArray(F("INA226 mode"));
temp.add(_isTriggeredOperationMode ? F("triggered") : F("continuous"));
if (_isTriggeredOperationMode)
{
temp = user.createNestedArray(F("INA226 triggered"));
temp.add(_measurementTriggered ? F("waiting for measurement") : F(""));
}
#endif
JsonArray jsonCurrent = user.createNestedArray(F("Current"));
JsonArray jsonVoltage = user.createNestedArray(F("Voltage"));
JsonArray jsonPower = user.createNestedArray(F("Power"));
JsonArray jsonShuntVoltage = user.createNestedArray(F("Shunt Voltage"));
JsonArray jsonOverflow = user.createNestedArray(F("Overflow"));
if (_lastLoopCheck == 0)
{
jsonCurrent.add(F("Not read yet"));
jsonVoltage.add(F("Not read yet"));
jsonPower.add(F("Not read yet"));
jsonShuntVoltage.add(F("Not read yet"));
jsonOverflow.add(F("Not read yet"));
return;
}
if (_lastStatus != 0)
{
jsonCurrent.add(F("An error occurred"));
jsonVoltage.add(F("An error occurred"));
jsonPower.add(F("An error occurred"));
jsonShuntVoltage.add(F("An error occurred"));
jsonOverflow.add(F("An error occurred"));
return;
}
jsonCurrent.add(_lastCurrent);
jsonCurrent.add(F("A"));
jsonVoltage.add(_lastVoltage);
jsonVoltage.add(F("V"));
jsonPower.add(_lastPower);
jsonPower.add(F("W"));
jsonShuntVoltage.add(_lastShuntVoltage);
jsonShuntVoltage.add(F("V"));
jsonOverflow.add(_lastOverflow ? F("true") : F("false"));
}
void addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[F("Enabled")] = _settingEnabled;
top[F("I2CAddress")] = static_cast<uint8_t>(_i2cAddress);
top[F("CheckInterval")] = _checkInterval / 1000;
top[F("INASamples")] = _settingInaSamples;
top[F("INAConversionTime")] = _settingInaConversionTimeUs << 2;
top[F("Decimals")] = log10f(_decimalFactor);
top[F("ShuntResistor")] = _shuntResistor;
top[F("CurrentRange")] = _currentRange;
#ifndef WLED_DISABLE_MQTT
top[F("MqttPublish")] = _mqttPublish;
top[F("MqttPublishAlways")] = _mqttPublishAlways;
top[F("MqttHomeAssistantDiscovery")] = _mqttHomeAssistant;
#endif
DEBUGUM_PRINTLN(F("INA226 config saved."));
}
bool readFromConfig(JsonObject &root) override
{
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
if (!configComplete)
return false;
bool tmpBool;
if (getJsonValue(top[F("Enabled")], tmpBool))
_settingEnabled = tmpBool;
else
configComplete = false;
configComplete &= getJsonValue(top[F("I2CAddress")], _i2cAddress);
if (getJsonValue(top[F("CheckInterval")], _checkInterval))
{
if (1 <= _checkInterval && _checkInterval <= 600)
_checkInterval *= 1000;
else
_checkInterval = DEFAULT_CHECKINTERVAL;
}
else
configComplete = false;
uint16_t tmpShort;
if (getJsonValue(top[F("INASamples")], tmpShort))
{
// The method below will fix the provided value to a valid one
getAverageEnum(tmpShort);
_settingInaSamples = tmpShort;
}
else
configComplete = false;
if (getJsonValue(top[F("INAConversionTime")], tmpShort))
{
// The method below will fix the provided value to a valid one
getConversionTimeEnum(tmpShort);
_settingInaConversionTimeUs = tmpShort >> 2;
}
else
configComplete = false;
if (getJsonValue(top[F("Decimals")], _decimalFactor))
{
if (0 <= _decimalFactor && _decimalFactor <= 5)
_decimalFactor = pow10f(_decimalFactor);
else
_decimalFactor = 100;
}
else
configComplete = false;
configComplete &= getJsonValue(top[F("ShuntResistor")], _shuntResistor);
configComplete &= getJsonValue(top[F("CurrentRange")], _currentRange);
#ifndef WLED_DISABLE_MQTT
if (getJsonValue(top[F("MqttPublish")], tmpBool))
_mqttPublish = tmpBool;
else
configComplete = false;
if (getJsonValue(top[F("MqttPublishAlways")], tmpBool))
_mqttPublishAlways = tmpBool;
else
configComplete = false;
if (getJsonValue(top[F("MqttHomeAssistantDiscovery")], tmpBool))
_mqttHomeAssistant = tmpBool;
else
configComplete = false;
#endif
if (_initDone)
{
initializeINA226();
#ifndef WLED_DISABLE_MQTT
mqttInitialize();
#endif
}
_initDone = true;
return configComplete;
}
};
const char UsermodINA226::_name[] PROGMEM = "INA226";

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -0,0 +1,44 @@
# Internal Temperature Usermod
![Screenshot of WLED info page](assets/screenshot_info.png)
![Screenshot of WLED usermod settings page](assets/screenshot_settings.png)
## Features
- 🌡️ Adds the internal temperature readout of the chip to the `Info` tab
- 🥵 High temperature indicator/action. (Configurable threshold and preset)
- 📣 Publishes the internal temperature over the MQTT topic: `mcutemp`
## Use Examples
- Warn of excessive/damaging temperatures by the triggering of a 'warning' preset
- Activate a cooling fan (when used with the multi-relay usermod)
## Compatibility
- A shown temp of 53,33°C might indicate that the internal temp is not supported
- ESP8266 does not have a internal temp sensor -> Disabled (Indicated with a readout of '-1')
- ESP32S2 seems to crash on reading the sensor -> Disabled (Indicated with a readout of '-1')
## Installation
- Add a build flag `-D USERMOD_INTERNAL_TEMPERATURE` to your `platformio.ini` (or `platformio_override.ini`).
## 📝 Change Log
2024-06-26
- Added "high-temperature-indication" feature
- Documentation updated
2023-09-01
* "Internal Temperature" usermod created
## Authors
- Soeren Willrodt [@lost-hope](https://github.com/lost-hope)
- Dimitry Zhemkov [@dima-zhemkov](https://github.com/dima-zhemkov)
- Adam Matthews [@adamsthws](https://github.com/adamsthws)

View File

@@ -0,0 +1,195 @@
#pragma once
#include "wled.h"
class InternalTemperatureUsermod : public Usermod
{
private:
static constexpr unsigned long minLoopInterval = 1000; // minimum allowable interval (ms)
unsigned long loopInterval = 10000;
unsigned long lastTime = 0;
bool isEnabled = false;
float temperature = 0.0f;
uint8_t previousPlaylist = 0; // Stores the playlist that was active before high-temperature activation
uint8_t previousPreset = 0; // Stores the preset that was active before high-temperature activation
uint8_t presetToActivate = 0; // Preset to activate when temp goes above threshold (0 = disabled)
float activationThreshold = 95.0f; // Temperature threshold to trigger high-temperature actions
float resetMargin = 2.0f; // Margin below the activation threshold (Prevents frequent toggling when close to threshold)
bool isAboveThreshold = false; // Flag to track if the high temperature preset is currently active
static const char _name[];
static const char _enabled[];
static const char _loopInterval[];
static const char _activationThreshold[];
static const char _presetToActivate[];
// any private methods should go here (non-inline method should be defined out of class)
void publishMqtt(const char *state, bool retain = false); // example for publishing MQTT message
public:
void setup()
{
}
void loop()
{
// if usermod is disabled or called during strip updating just exit
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
if (!isEnabled || strip.isUpdating() || millis() - lastTime <= loopInterval)
return;
lastTime = millis();
// Measure the temperature
#ifdef ESP8266 // ESP8266
// does not seem possible
temperature = -1;
#elif defined(CONFIG_IDF_TARGET_ESP32S2) // ESP32S2
temperature = -1;
#else // ESP32 ESP32S3 and ESP32C3
temperature = roundf(temperatureRead() * 10) / 10;
#endif
// Check if temperature has exceeded the activation threshold
if (temperature >= activationThreshold) {
// Update the state flag if not already set
if (!isAboveThreshold) {
isAboveThreshold = true;
}
// Check if a 'high temperature' preset is configured and it's not already active
if (presetToActivate != 0 && currentPreset != presetToActivate) {
// If a playlist is active, store it for reactivation later
if (currentPlaylist > 0) {
previousPlaylist = currentPlaylist;
}
// If a preset is active, store it for reactivation later
else if (currentPreset > 0) {
previousPreset = currentPreset;
// If no playlist or preset is active, save current state for reactivation later
} else {
saveTemporaryPreset();
}
// Activate the 'high temperature' preset
applyPreset(presetToActivate);
}
}
// Check if temperature is back below the threshold
else if (temperature <= (activationThreshold - resetMargin)) {
// Update the state flag if not already set
if (isAboveThreshold){
isAboveThreshold = false;
}
// Check if the 'high temperature' preset is active
if (currentPreset == presetToActivate) {
// Check if a previous playlist was stored
if (previousPlaylist > 0) {
// Reactivate the stored playlist
applyPreset(previousPlaylist);
// Clear the stored playlist
previousPlaylist = 0;
}
// Check if a previous preset was stored
else if (previousPreset > 0) {
// Reactivate the stored preset
applyPreset(previousPreset);
// Clear the stored preset
previousPreset = 0;
// If no previous playlist or preset was stored, revert to the stored state
} else {
applyTemporaryPreset();
}
}
}
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED)
{
char array[10];
snprintf(array, sizeof(array), "%f", temperature);
publishMqtt(array);
}
#endif
}
void addToJsonInfo(JsonObject &root)
{
if (!isEnabled)
return;
// if "u" object does not exist yet wee need to create it
JsonObject user = root["u"];
if (user.isNull())
user = root.createNestedObject("u");
JsonArray userTempArr = user.createNestedArray(FPSTR(_name));
userTempArr.add(temperature);
userTempArr.add(F(" °C"));
// if "sensor" object does not exist yet wee need to create it
JsonObject sensor = root[F("sensor")];
if (sensor.isNull())
sensor = root.createNestedObject(F("sensor"));
JsonArray sensorTempArr = sensor.createNestedArray(FPSTR(_name));
sensorTempArr.add(temperature);
sensorTempArr.add(F("°C"));
}
void addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = isEnabled;
top[FPSTR(_loopInterval)] = loopInterval;
top[FPSTR(_activationThreshold)] = activationThreshold;
top[FPSTR(_presetToActivate)] = presetToActivate;
}
// Append useful info to the usermod settings gui
void appendConfigData()
{
// Display 'ms' next to the 'Loop Interval' setting
oappend(SET_F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');"));
// Display '°C' next to the 'Activation Threshold' setting
oappend(SET_F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');"));
// Display '0 = Disabled' next to the 'Preset To Activate' setting
oappend(SET_F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');"));
}
bool readFromConfig(JsonObject &root)
{
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
configComplete &= getJsonValue(top[FPSTR(_enabled)], isEnabled);
configComplete &= getJsonValue(top[FPSTR(_loopInterval)], loopInterval);
loopInterval = max(loopInterval, minLoopInterval); // Makes sure the loop interval isn't too small.
configComplete &= getJsonValue(top[FPSTR(_presetToActivate)], presetToActivate);
configComplete &= getJsonValue(top[FPSTR(_activationThreshold)], activationThreshold);
return configComplete;
}
uint16_t getId()
{
return USERMOD_ID_INTERNAL_TEMPERATURE;
}
};
const char InternalTemperatureUsermod::_name[] PROGMEM = "Internal Temperature";
const char InternalTemperatureUsermod::_enabled[] PROGMEM = "Enabled";
const char InternalTemperatureUsermod::_loopInterval[] PROGMEM = "Loop Interval";
const char InternalTemperatureUsermod::_activationThreshold[] PROGMEM = "Activation Threshold";
const char InternalTemperatureUsermod::_presetToActivate[] PROGMEM = "Preset To Activate";
void InternalTemperatureUsermod::publishMqtt(const char *state, bool retain)
{
#ifndef WLED_DISABLE_MQTT
// Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED)
{
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
strcat_P(subuf, PSTR("/mcutemp"));
mqtt->publish(subuf, 0, retain, state);
}
#endif
}

View File

@@ -0,0 +1,36 @@
# BH1750 usermod
> This usermod requires a second UART and was only tested on the ESP32
This usermod will read from a LD2410 movement/presence sensor.
The movement and presence state are displayed in both the Info section of the web UI, as well as published to the `/movement` and `/stationary` MQTT topics respectively.
## Dependencies
- Libraries
- `ncmreynolds/ld2410@^0.1.3`
- This must be added under `lib_deps` in your `platformio.ini` (or `platformio_override.ini`).
- Data is published over MQTT - make sure you've enabled the MQTT sync interface.
## Compilation
To enable, compile with `USERMOD_LD2410` defined (e.g. in `platformio_override.ini`)
```ini
[env:usermod_USERMOD_LD2410_esp32dev]
extends = env:esp32dev
build_flags =
${common.build_flags_esp32}
-D USERMOD_LD2410
lib_deps =
${esp32.lib_deps}
ncmreynolds/ld2410@^0.1.3
```
### Configuration Options
The Usermod screen allows you to:
- enable/disable the usermod
- Configure the RX/TX pins
## Change log
- 2024-06 Created by @wesleygas (https://github.com/wesleygas/)

View File

@@ -0,0 +1,237 @@
#warning **** Included USERMOD_LD2410 ****
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#pragma once
#include "wled.h"
#include <ld2410.h>
class LD2410Usermod : public Usermod {
private:
bool enabled = true;
bool initDone = false;
bool sensorFound = false;
unsigned long lastTime = 0;
unsigned long last_mqtt_sent = 0;
int8_t default_uart_rx = 19;
int8_t default_uart_tx = 18;
String mqttMovementTopic = F("");
String mqttStationaryTopic = F("");
bool mqttInitialized = false;
bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages
ld2410 radar;
bool stationary_detected = false;
bool last_stationary_state = false;
bool movement_detected = false;
bool last_movement_state = false;
// These config variables have defaults set inside readFromConfig()
int8_t uart_rx_pin;
int8_t uart_tx_pin;
// string that are used multiple time (this will save some flash memory)
static const char _name[];
static const char _enabled[];
void publishMqtt(const char* topic, const char* state, bool retain); // example for publishing MQTT message
void _mqttInitialize()
{
mqttMovementTopic = String(mqttDeviceTopic) + F("/ld2410/movement");
mqttStationaryTopic = String(mqttDeviceTopic) + F("/ld2410/stationary");
if (HomeAssistantDiscovery){
_createMqttSensor(F("Movement"), mqttMovementTopic, F("motion"), F(""));
_createMqttSensor(F("Stationary"), mqttStationaryTopic, F("occupancy"), F(""));
}
}
// Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement)
{
String t = String(F("homeassistant/binary_sensor/")) + mqttClientID + F("/") + name + F("/config");
StaticJsonDocument<600> doc;
doc[F("name")] = String(serverDescription) + F(" Module");
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
if (unitOfMeasurement != "")
doc[F("unit_of_measurement")] = unitOfMeasurement;
if (deviceClass != "")
doc[F("device_class")] = deviceClass;
doc[F("expire_after")] = 1800;
doc[F("payload_off")] = "OFF";
doc[F("payload_on")] = "ON";
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F("WLED");
device[F("model")] = F("FOSS");
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
public:
inline bool isEnabled() { return enabled; }
void setup() {
Serial1.begin(256000, SERIAL_8N1, uart_rx_pin, uart_tx_pin);
Serial.print(F("\nLD2410 radar sensor initialising: "));
if(radar.begin(Serial1)){
Serial.println(F("OK"));
} else {
Serial.println(F("not connected"));
}
initDone = true;
}
void loop() {
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
if (!enabled || strip.isUpdating()) return;
radar.read();
unsigned long curr_time = millis();
if(curr_time - lastTime > 1000) //Try to Report every 1000ms
{
lastTime = curr_time;
sensorFound = radar.isConnected();
if(!sensorFound) return;
stationary_detected = radar.presenceDetected();
if(stationary_detected != last_stationary_state){
if (WLED_MQTT_CONNECTED){
publishMqtt("/ld2410/stationary", stationary_detected ? "ON":"OFF", false);
last_stationary_state = stationary_detected;
}
}
movement_detected = radar.movingTargetDetected();
if(movement_detected != last_movement_state){
if (WLED_MQTT_CONNECTED){
publishMqtt("/ld2410/movement", movement_detected ? "ON":"OFF", false);
last_movement_state = movement_detected;
}
}
// If there hasn't been any activity, send current state to confirm sensor is alive
if(curr_time - last_mqtt_sent > 1000*60*5 && WLED_MQTT_CONNECTED){
publishMqtt("/ld2410/stationary", stationary_detected ? "ON":"OFF", false);
publishMqtt("/ld2410/movement", movement_detected ? "ON":"OFF", false);
}
}
}
void addToJsonInfo(JsonObject& root)
{
// if "u" object does not exist yet wee need to create it
JsonObject user = root[F("u")];
if (user.isNull()) user = root.createNestedObject(F("u"));
JsonArray ld2410_sta_json = user.createNestedArray(F("LD2410 Stationary"));
JsonArray ld2410_mov_json = user.createNestedArray(F("LD2410 Movement"));
if (!enabled){
ld2410_sta_json.add(F("disabled"));
ld2410_mov_json.add(F("disabled"));
} else if(!sensorFound){
ld2410_sta_json.add(F("LD2410"));
ld2410_sta_json.add(" Not Found");
} else {
ld2410_sta_json.add("Sta ");
ld2410_sta_json.add(stationary_detected ? "ON":"OFF");
ld2410_mov_json.add("Mov ");
ld2410_mov_json.add(movement_detected ? "ON":"OFF");
}
}
void addToConfig(JsonObject& root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
//save these vars persistently whenever settings are saved
top["uart_rx_pin"] = default_uart_rx;
top["uart_tx_pin"] = default_uart_tx;
}
bool readFromConfig(JsonObject& root)
{
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
if (!configComplete)
{
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINT(F("LD2410"));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
configComplete &= getJsonValue(top["uart_rx_pin"], uart_rx_pin, default_uart_rx);
configComplete &= getJsonValue(top["uart_tx_pin"], uart_tx_pin, default_uart_tx);
return configComplete;
}
#ifndef WLED_DISABLE_MQTT
/**
* onMqttConnect() is called when MQTT connection is established
*/
void onMqttConnect(bool sessionPresent) {
// do any MQTT related initialisation here
if(!radar.isConnected()) return;
publishMqtt("/ld2410/status", "I am alive!", false);
if (!mqttInitialized)
{
_mqttInitialize();
mqttInitialized = true;
}
}
#endif
uint16_t getId()
{
return USERMOD_ID_LD2410;
}
};
// add more strings here to reduce flash memory usage
const char LD2410Usermod::_name[] PROGMEM = "LD2410Usermod";
const char LD2410Usermod::_enabled[] PROGMEM = "enabled";
// implementation of non-inline member methods
void LD2410Usermod::publishMqtt(const char* topic, const char* state, bool retain)
{
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash
if (WLED_MQTT_CONNECTED) {
last_mqtt_sent = millis();
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, topic);
mqtt->publish(subuf, 0, retain, state);
}
#endif
}

View File

@@ -0,0 +1,26 @@
# LDR_Dusk_Dawn_v2
This usermod will obtain readings from a Light Dependent Resistor (LDR) and will turn on/off specific presets based on those readings. This is useful for exterior lighting situations where you want the lights to only be on when it is dark out.
# Installation
Add "-D USERMOD_LDR_DUSK_DAWN" to your platformio.ini [common] build_flags and build.
Example:
```
[common]
build_flags =
-D USERMOD_LDR_DUSK_DAWN # Enable LDR Dusk Dawn Usermod
```
# Usermod Settings
Setting | Description | Default
--- | --- | ---
Enabled | Enable/Disable the LDR functionality. | Disabled
LDR Pin | The analog capable pin your LDR is connected to. | 34
Threshold Minutes | The number of minutes of consistent readings above/below the on/off threshold before the LED state will change. | 5
Threshold | The analog read value threshold from the LDR. Readings lower than this number will count towards changing the LED state to off. You can see the current LDR reading by going into the info section when LDR functionality is enabled. | 1000
On Preset | The WLED preset to be used for the LED on state. | 1
Off Preset | The WLED preset to be used for the LED off state. | 2
## Author
[@jeffwdh](https://github.com/jeffwdh)
jeffwdh@tarball.ca

View File

@@ -0,0 +1,153 @@
#pragma once
#include "wled.h"
#ifndef ARDUINO_ARCH_ESP32
// 8266 does not support analogRead on user selectable pins
#error only ESP32 is supported by usermod LDR_DUSK_DAWN
#endif
class LDR_Dusk_Dawn_v2 : public Usermod {
private:
// Defaults
bool ldrEnabled = false;
int ldrPin = 34; //A2 on Adafruit Huzzah32
int ldrThresholdMinutes = 5; // How many minutes of readings above/below threshold until it switches LED state
int ldrThreshold = 1000; // Readings higher than this number will turn off LED.
int ldrOnPreset = 1; // Default "On" Preset
int ldrOffPreset = 2; // Default "Off" Preset
// Variables
bool initDone = false;
bool ldrEnabledPreviously = false; // Was LDR enabled for the previous check? First check is always no.
int ldrOffCount; // Number of readings above the threshold
int ldrOnCount; // Number of readings below the threshold
int ldrReading = 0; // Last LDR reading
int ldrLEDState; // Current LED on/off state
unsigned long lastMillis = 0;
static const char _name[];
public:
void setup() {
// register ldrPin
if ((ldrPin >= 0) && (digitalPinToAnalogChannel(ldrPin) >= 0)) {
if(!PinManager::allocatePin(ldrPin, false, PinOwner::UM_LDR_DUSK_DAWN)) ldrEnabled = false; // pin already in use -> disable usermod
else pinMode(ldrPin, INPUT); // alloc success -> configure pin for input
} else ldrEnabled = false; // invalid pin -> disable usermod
initDone = true;
}
void loop() {
// Only update every 10 seconds
if (millis() - lastMillis > 10000) {
if ( (ldrEnabled == true)
&& (ldrPin >= 0) && (digitalPinToAnalogChannel(ldrPin) >= 0) ) { // make sure that pin is valid for analogread()
// Default state is off
if (ldrEnabledPreviously == false) {
applyPreset(ldrOffPreset);
ldrEnabledPreviously = true;
ldrLEDState = 0;
}
// Get LDR reading and increment counter by number of seconds since last read
ldrReading = analogRead(ldrPin);
if (ldrReading <= ldrThreshold) {
ldrOnCount = ldrOnCount + 10;
ldrOffCount = 0;
} else {
ldrOffCount = ldrOffCount + 10;
ldrOnCount = 0;
}
if (ldrOnCount >= (ldrThresholdMinutes * 60)) {
ldrOnCount = 0;
// If LEDs were previously off, turn on
if (ldrLEDState == 0) {
applyPreset(ldrOnPreset);
ldrLEDState = 1;
}
}
if (ldrOffCount >= (ldrThresholdMinutes * 60)) {
ldrOffCount = 0;
// If LEDs were previously on, turn off
if (ldrLEDState == 1) {
applyPreset(ldrOffPreset);
ldrLEDState = 0;
}
}
} else {
// LDR is disabled, reset variables to default
ldrReading = 0;
ldrOnCount = 0;
ldrOffCount = 0;
ldrLEDState = 0;
ldrEnabledPreviously = false;
}
lastMillis = millis();
}
}
void addToConfig(JsonObject& root) {
JsonObject top = root.createNestedObject(FPSTR(_name));
top["Enabled"] = ldrEnabled;
top["LDR Pin"] = ldrPin;
top["Threshold Minutes"] = ldrThresholdMinutes;
top["Threshold"] = ldrThreshold;
top["On Preset"] = ldrOnPreset;
top["Off Preset"] = ldrOffPreset;
}
bool readFromConfig(JsonObject& root) {
int8_t oldLdrPin = ldrPin;
JsonObject top = root[FPSTR(_name)];
bool configComplete = !top.isNull();
configComplete &= getJsonValue(top["Enabled"], ldrEnabled);
configComplete &= getJsonValue(top["LDR Pin"], ldrPin);
configComplete &= getJsonValue(top["Threshold Minutes"], ldrThresholdMinutes);
configComplete &= getJsonValue(top["Threshold"], ldrThreshold);
configComplete &= getJsonValue(top["On Preset"], ldrOnPreset);
configComplete &= getJsonValue(top["Off Preset"], ldrOffPreset);
if (initDone && (ldrPin != oldLdrPin)) {
// pin changed - un-register previous pin, register new pin
if (oldLdrPin >= 0) PinManager::deallocatePin(oldLdrPin, PinOwner::UM_LDR_DUSK_DAWN);
setup(); // setup new pin
}
return configComplete;
}
void addToJsonInfo(JsonObject& root) {
// If "u" object does not exist yet we need to create it
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray LDR_Enabled = user.createNestedArray("LDR dusk/dawn enabled");
LDR_Enabled.add(ldrEnabled);
if (!ldrEnabled) return; // do not add more if usermod is disabled
JsonArray LDR_Reading = user.createNestedArray("LDR reading");
LDR_Reading.add(ldrReading);
JsonArray LDR_State = user.createNestedArray("LDR turned LEDs on");
LDR_State.add(bool(ldrLEDState));
// Optional debug information:
//JsonArray LDR_On_Count = user.createNestedArray("LDR on count");
//LDR_On_Count.add(ldrOnCount);
//JsonArray LDR_Off_Count = user.createNestedArray("LDR off count");
//LDR_Off_Count.add(ldrOffCount);
//bool pinValid = ((ldrPin >= 0) && (digitalPinToAnalogChannel(ldrPin) >= 0));
//if (PinManager::getPinOwner(ldrPin) != PinOwner::UM_LDR_DUSK_DAWN) pinValid = false;
//JsonArray LDR_valid = user.createNestedArray(F("LDR pin"));
//LDR_valid.add(ldrPin);
//LDR_valid.add(pinValid ? F(" OK"): F(" invalid"));
}
uint16_t getId() {
return USERMOD_ID_LDR_DUSK_DAWN;
}
};
const char LDR_Dusk_Dawn_v2::_name[] PROGMEM = "LDR_Dusk_Dawn_v2";

View File

@@ -0,0 +1,64 @@
# Adafruit MAX17048 Usermod (LiPo & LiIon Battery Monitor & Fuel Gauge)
This usermod reads information from an Adafruit MAX17048 and outputs the following:
- Battery Voltage
- Battery Level Percentage
## Dependencies
Libraries:
- `Adafruit_BusIO@~1.14.5` (by [adafruit](https://github.com/adafruit/Adafruit_BusIO))
- `Adafruit_MAX1704X@~1.0.2` (by [adafruit](https://github.com/adafruit/Adafruit_MAX1704X))
These must be added under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
Data is published over MQTT - make sure you've enabled the MQTT sync interface.
## Compilation
To enable, compile with `USERMOD_MAX17048` define in the build_flags (e.g. in `platformio.ini` or `platformio_override.ini`) such as in the example below:
```ini
[env:usermod_max17048_d1_mini]
extends = env:d1_mini
build_flags =
${common.build_flags_esp8266}
-D USERMOD_MAX17048
lib_deps =
${esp8266.lib_deps}
https://github.com/adafruit/Adafruit_BusIO @ 1.14.5
https://github.com/adafruit/Adafruit_MAX1704X @ 1.0.2
```
### Configuration Options
The following settings can be set at compile-time but are configurable on the usermod menu (except First Monitor time):
- USERMOD_MAX17048_MIN_MONITOR_INTERVAL (the min number of milliseconds between checks, defaults to 10,000 ms)
- USERMOD_MAX17048_MAX_MONITOR_INTERVAL (the max number of milliseconds between checks, defaults to 10,000 ms)
- USERMOD_MAX17048_FIRST_MONITOR_AT
Additionally, the Usermod Menu allows you to:
- Enable or Disable the usermod
- Enable or Disable Home Assistant Discovery (turn on/off to sent MQTT Discovery entries for Home Assistant)
- Configure SCL/SDA GPIO Pins
## API
The following method is available to interact with the usermod from other code modules:
- `getBatteryVoltageV` read the last battery voltage (in Volt) obtained from the sensor
- `getBatteryPercent` reads the last battery percentage obtained from the sensor
## MQTT
MQTT topics are as follows (`<deviceTopic>` is set in MQTT section of Sync Setup menu):
Measurement type | MQTT topic
--- | ---
Battery Voltage | `<deviceTopic>/batteryVoltage`
Battery Percent | `<deviceTopic>/batteryPercent`
## Authors
Carlos Cruz [@ccruz09](https://github.com/ccruz09)
## Revision History
Jan 2024
- Added Home Assistant Discovery
- Implemented PinManager to register pins
- Added API call for other modules to read battery voltage and percentage
- Added info-screen outputs
- Updated `readme.md`

View File

@@ -0,0 +1,281 @@
// force the compiler to show a warning to confirm that this file is included
#warning **** Included USERMOD_MAX17048 V2.0 ****
#pragma once
#include "wled.h"
#include "Adafruit_MAX1704X.h"
// the max interval to check battery level, 10 seconds
#ifndef USERMOD_MAX17048_MAX_MONITOR_INTERVAL
#define USERMOD_MAX17048_MAX_MONITOR_INTERVAL 10000
#endif
// the min interval to check battery level, 500 ms
#ifndef USERMOD_MAX17048_MIN_MONITOR_INTERVAL
#define USERMOD_MAX17048_MIN_MONITOR_INTERVAL 500
#endif
// how many seconds after boot to perform the first check, 10 seconds
#ifndef USERMOD_MAX17048_FIRST_MONITOR_AT
#define USERMOD_MAX17048_FIRST_MONITOR_AT 10000
#endif
/*
* Usermod to display Battery Life using Adafruit's MAX17048 LiPoly/ LiIon Fuel Gauge and Battery Monitor.
*/
class Usermod_MAX17048 : public Usermod {
private:
bool enabled = true;
unsigned long maxReadingInterval = USERMOD_MAX17048_MAX_MONITOR_INTERVAL;
unsigned long minReadingInterval = USERMOD_MAX17048_MIN_MONITOR_INTERVAL;
unsigned long lastCheck = UINT32_MAX - (USERMOD_MAX17048_MAX_MONITOR_INTERVAL - USERMOD_MAX17048_FIRST_MONITOR_AT);
unsigned long lastSend = UINT32_MAX - (USERMOD_MAX17048_MAX_MONITOR_INTERVAL - USERMOD_MAX17048_FIRST_MONITOR_AT);
uint8_t VoltageDecimals = 3; // Number of decimal places in published voltage values
uint8_t PercentDecimals = 1; // Number of decimal places in published percent values
// string that are used multiple time (this will save some flash memory)
static const char _name[];
static const char _enabled[];
static const char _maxReadInterval[];
static const char _minReadInterval[];
static const char _HomeAssistantDiscovery[];
bool monitorFound = false;
bool firstReadComplete = false;
bool initDone = false;
Adafruit_MAX17048 maxLipo;
float lastBattVoltage = -10;
float lastBattPercent = -1;
// MQTT and Home Assistant Variables
bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information
bool mqttInitialized = false;
void _mqttInitialize()
{
char mqttBatteryVoltageTopic[128];
char mqttBatteryPercentTopic[128];
snprintf_P(mqttBatteryVoltageTopic, 127, PSTR("%s/batteryVoltage"), mqttDeviceTopic);
snprintf_P(mqttBatteryPercentTopic, 127, PSTR("%s/batteryPercent"), mqttDeviceTopic);
if (HomeAssistantDiscovery) {
_createMqttSensor(F("BatteryVoltage"), mqttBatteryVoltageTopic, "voltage", F("V"));
_createMqttSensor(F("BatteryPercent"), mqttBatteryPercentTopic, "battery", F("%"));
}
}
void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement)
{
String t = String(F("homeassistant/sensor/")) + mqttClientID + F("/") + name + F("/config");
StaticJsonDocument<600> doc;
doc[F("name")] = String(serverDescription) + " " + name;
doc[F("state_topic")] = topic;
doc[F("unique_id")] = String(mqttClientID) + name;
if (unitOfMeasurement != "")
doc[F("unit_of_measurement")] = unitOfMeasurement;
if (deviceClass != "")
doc[F("device_class")] = deviceClass;
doc[F("expire_after")] = 1800;
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
device[F("manufacturer")] = F("WLED");
device[F("model")] = F("FOSS");
device[F("sw_version")] = versionString;
String temp;
serializeJson(doc, temp);
DEBUGUM_PRINTLN(t);
DEBUGUM_PRINTLN(temp);
mqtt->publish(t.c_str(), 0, true, temp.c_str());
}
void publishMqtt(const char *topic, const char* state) {
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED){
char subuf[128];
snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, topic);
mqtt->publish(subuf, 0, false, state);
}
#endif
}
public:
inline void enable(bool enable) { enabled = enable; }
inline bool isEnabled() { return enabled; }
void setup() {
// do your set-up here
if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; }
monitorFound = maxLipo.begin();
initDone = true;
}
void loop() {
// if usermod is disabled or called during strip updating just exit
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
if (!enabled || strip.isUpdating()) return;
unsigned long now = millis();
if (now - lastCheck < minReadingInterval) { return; }
bool shouldUpdate = now - lastSend > maxReadingInterval;
float battVoltage = maxLipo.cellVoltage();
float battPercent = maxLipo.cellPercent();
lastCheck = millis();
firstReadComplete = true;
if (shouldUpdate)
{
lastBattVoltage = roundf(battVoltage * powf(10, VoltageDecimals)) / powf(10, VoltageDecimals);
lastBattPercent = roundf(battPercent * powf(10, PercentDecimals)) / powf(10, PercentDecimals);
lastSend = millis();
publishMqtt("batteryVoltage", String(lastBattVoltage, VoltageDecimals).c_str());
publishMqtt("batteryPercent", String(lastBattPercent, PercentDecimals).c_str());
DEBUGUM_PRINTLN(F("Battery Voltage: ") + String(lastBattVoltage, VoltageDecimals) + F("V"));
DEBUGUM_PRINTLN(F("Battery Percent: ") + String(lastBattPercent, PercentDecimals) + F("%"));
}
}
void onMqttConnect(bool sessionPresent)
{
if (WLED_MQTT_CONNECTED && !mqttInitialized)
{
_mqttInitialize();
mqttInitialized = true;
}
}
inline float getBatteryVoltageV() {
return (float) lastBattVoltage;
}
inline float getBatteryPercent() {
return (float) lastBattPercent;
}
void addToJsonInfo(JsonObject& root)
{
// if "u" object does not exist yet wee need to create it
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray battery_json = user.createNestedArray(F("Battery Monitor"));
if (!enabled) {
battery_json.add(F("Disabled"));
}
else if(!monitorFound) {
battery_json.add(F("MAX17048 Not Found"));
}
else if (!firstReadComplete) {
// if we haven't read the sensor yet, let the user know
// that we are still waiting for the first measurement
battery_json.add((USERMOD_MAX17048_FIRST_MONITOR_AT - millis()) / 1000);
battery_json.add(F(" sec until read"));
} else {
battery_json.add(F("Enabled"));
JsonArray voltage_json = user.createNestedArray(F("Battery Voltage"));
voltage_json.add(lastBattVoltage);
voltage_json.add(F("V"));
JsonArray percent_json = user.createNestedArray(F("Battery Percent"));
percent_json.add(lastBattPercent);
percent_json.add(F("%"));
}
}
void addToJsonState(JsonObject& root)
{
JsonObject usermod = root[FPSTR(_name)];
if (usermod.isNull())
{
usermod = root.createNestedObject(FPSTR(_name));
}
usermod[FPSTR(_enabled)] = enabled;
}
void readFromJsonState(JsonObject& root)
{
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull())
{
if (usermod[FPSTR(_enabled)].is<bool>())
{
enabled = usermod[FPSTR(_enabled)].as<bool>();
}
}
}
void addToConfig(JsonObject& root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
top[FPSTR(_maxReadInterval)] = maxReadingInterval;
top[FPSTR(_minReadInterval)] = minReadingInterval;
top[FPSTR(_HomeAssistantDiscovery)] = HomeAssistantDiscovery;
DEBUGUM_PRINT(F(_name));
DEBUGUM_PRINTLN(F(" config saved."));
}
bool readFromConfig(JsonObject& root)
{
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUGUM_PRINT(F(_name));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
bool configComplete = !top.isNull();
configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
configComplete &= getJsonValue(top[FPSTR(_maxReadInterval)], maxReadingInterval, USERMOD_MAX17048_MAX_MONITOR_INTERVAL);
configComplete &= getJsonValue(top[FPSTR(_minReadInterval)], minReadingInterval, USERMOD_MAX17048_MIN_MONITOR_INTERVAL);
configComplete &= getJsonValue(top[FPSTR(_HomeAssistantDiscovery)], HomeAssistantDiscovery, false);
DEBUGUM_PRINT(FPSTR(_name));
if (!initDone) {
// first run: reading from cfg.json
DEBUGUM_PRINTLN(F(" config loaded."));
} else {
DEBUGUM_PRINTLN(F(" config (re)loaded."));
// changing parameters from settings page
}
return configComplete;
}
uint16_t getId()
{
return USERMOD_ID_MAX17048;
}
};
// add more strings here to reduce flash memory usage
const char Usermod_MAX17048::_name[] PROGMEM = "Adafruit MAX17048 Battery Monitor";
const char Usermod_MAX17048::_enabled[] PROGMEM = "enabled";
const char Usermod_MAX17048::_maxReadInterval[] PROGMEM = "max-read-interval-ms";
const char Usermod_MAX17048::_minReadInterval[] PROGMEM = "min-read-interval-ms";
const char Usermod_MAX17048::_HomeAssistantDiscovery[] PROGMEM = "HomeAssistantDiscovery";

View File

@@ -23,7 +23,7 @@ You can also use usermod's off timer instead of sensor's. In such case rotate th
## Usermod installation
**NOTE:** Usermod has been included in master branch of WLED so it can be compiled in directly just by defining `-D USERMOD_PIRSWITCH` and optionaly `-D PIR_SENSOR_PIN=16` to override default pin. You can also change the default off time by adding `-D PIR_SENSOR_OFF_SEC=30`.
**NOTE:** Usermod has been included in master branch of WLED so it can be compiled in directly just by defining `-D USERMOD_PIRSWITCH` and optionally `-D PIR_SENSOR_PIN=16` to override default pin. You can also change the default off time by adding `-D PIR_SENSOR_OFF_SEC=30`.
## API to enable/disable the PIR sensor from outside. For example from another usermod:
@@ -31,7 +31,7 @@ To query or change the PIR sensor state the methods `bool PIRsensorEnabled()` an
When the PIR sensor state changes an MQTT message is broadcasted with topic `wled/deviceMAC/motion` and message `on` or `off`.
Usermod can also be configured to send just the MQTT message but not change WLED state using settings page as well as responding to motion only at night
(assuming NTP and lattitude/longitude are set to determine sunrise/sunset times).
(assuming NTP and latitude/longitude are set to determine sunrise/sunset times).
### There are two options to get access to the usermod instance:
@@ -52,7 +52,7 @@ class MyUsermod : public Usermod {
void togglePIRSensor() {
#ifdef USERMOD_PIR_SENSOR_SWITCH
PIRsensorSwitch *PIRsensor = (PIRsensorSwitch::*) usermods.lookup(USERMOD_ID_PIRSWITCH);
PIRsensorSwitch *PIRsensor = (PIRsensorSwitch::*) UsermodManager::lookup(USERMOD_ID_PIRSWITCH);
if (PIRsensor != nullptr) {
PIRsensor->EnablePIRsensor(!PIRsensor->PIRsensorEnabled());
}
@@ -75,6 +75,9 @@ Usermod can be configured via the Usermods settings page.
* `mqtt-only` - send only MQTT messages, do not interact with WLED
* `off-only` - only trigger presets or turn WLED on/off if WLED is not already on (displaying effect)
* `notifications` - enable or disable sending notifications to other WLED instances using Sync button
* `HA-discovery` - enable automatic discovery in Home Assistant
* `override` - override PIR input when WLED state is changed using UI
* `domoticz-idx` - Domoticz virtual switch ID (used with MQTT `domoticz/in`)
Have fun - @gegu & @blazoncek
@@ -85,9 +88,16 @@ Have fun - @gegu & @blazoncek
2021-11
* Added information about dynamic configuration options
* Added option to temporary enable/disble usermod from WLED UI (Info dialog)
* Added option to temporary enable/disable usermod from WLED UI (Info dialog)
2022-11
* Added compile time option for off timer.
* Added Home Assistant autodiscovery MQTT broadcast.
* Updated info on compiling.
2023-??
* Override option
* Domoticz virtual switch ID (used with MQTT `domoticz/in`)
2024-02
* Added compile time option to expand number of PIR sensors (they are logically ORed) `-D PIR_SENSOR_MAX_SENSORS=3`

View File

@@ -15,12 +15,15 @@
#define PIR_SENSOR_OFF_SEC 600
#endif
#ifndef PIR_SENSOR_MAX_SENSORS
#define PIR_SENSOR_MAX_SENSORS 1
#endif
/*
* This usermod handles PIR sensor states.
* The strip will be switched on and the off timer will be resetted when the sensor goes HIGH.
* When the sensor state goes LOW, the off timer is started and when it expires, the strip is switched off.
*
* Maintained by: @blazoncek
*
* Usermods allow you to add own functionality to WLED more easily
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
@@ -38,26 +41,29 @@ public:
~PIRsensorSwitch() {}
//Enable/Disable the PIR sensor
void EnablePIRsensor(bool en) { enabled = en; }
inline void EnablePIRsensor(bool en) { enabled = en; }
// Get PIR sensor enabled/disabled state
bool PIRsensorEnabled() { return enabled; }
inline bool PIRsensorEnabled() { return enabled; }
private:
byte prevPreset = 0;
byte prevPlaylist = 0;
uint32_t offTimerStart = 0; // off timer start time
byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for stateUpdated(): CALL_MODE_NO_NOTIFY or CALL_MODE_DIRECT_CHANGE
byte sensorPinState = LOW; // current PIR sensor pin state
bool initDone = false; // status of initialization
bool PIRtriggered = false;
unsigned long lastLoop = 0;
volatile unsigned long offTimerStart = 0; // off timer start time
volatile bool PIRtriggered = false; // did PIR trigger?
bool initDone = false; // status of initialization
unsigned long lastLoop = 0;
bool sensorPinState[PIR_SENSOR_MAX_SENSORS] = {LOW}; // current PIR sensor pin state
// configurable parameters
#if PIR_SENSOR_PIN < 0
bool enabled = false; // PIR sensor disabled
#else
bool enabled = true; // PIR sensor enabled
int8_t PIRsensorPin = PIR_SENSOR_PIN; // PIR sensor pin
#endif
int8_t PIRsensorPin[PIR_SENSOR_MAX_SENSORS] = {PIR_SENSOR_PIN}; // PIR sensor pin
uint32_t m_switchOffDelay = PIR_SENSOR_OFF_SEC*1000; // delay before switch off after the sensor state goes LOW (10min)
uint8_t m_onPreset = 0; // on preset
uint8_t m_offPreset = 0; // off preset
@@ -66,9 +72,11 @@ private:
// flag to enable triggering only if WLED is initially off (LEDs are not on, preventing running effect being overwritten by PIR)
bool m_offOnly = false;
bool m_offMode = offMode;
bool m_override = false;
// Home Assistant
bool HomeAssistantDiscovery = false; // is HA discovery turned on
int16_t idx = -1; // Domoticz virtual switch idx
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
@@ -80,169 +88,34 @@ private:
static const char _mqttOnly[];
static const char _offOnly[];
static const char _haDiscovery[];
static const char _notify[];
static const char _override[];
static const char _domoticzIDX[];
/**
* check if it is daytime
* if sunrise/sunset is not defined (no NTP or lat/lon) default to nighttime
*/
bool isDayTime() {
updateLocalTime();
uint8_t hr = hour(localTime);
uint8_t mi = minute(localTime);
if (sunrise && sunset) {
if (hour(sunrise)<hr && hour(sunset)>hr) {
return true;
} else {
if (hour(sunrise)==hr && minute(sunrise)<mi) {
return true;
}
if (hour(sunset)==hr && minute(sunset)>mi) {
return true;
}
}
}
return false;
}
static bool isDayTime();
/**
* switch strip on/off
*/
void switchStrip(bool switchOn)
{
if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing
if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing
PIRtriggered = switchOn;
if (switchOn) {
if (m_onPreset) {
if (currentPlaylist>0 && !offMode) {
prevPlaylist = currentPlaylist;
unloadPlaylist();
} else if (currentPreset>0 && !offMode) {
prevPreset = currentPreset;
} else {
saveTemporaryPreset();
prevPlaylist = 0;
prevPreset = 255;
}
applyPreset(m_onPreset, NotifyUpdateMode);
return;
}
// preset not assigned
if (bri == 0) {
bri = briLast;
stateUpdated(NotifyUpdateMode);
}
} else {
if (m_offPreset) {
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(m_offPreset, NotifyUpdateMode);
return;
} else if (prevPlaylist) {
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, NotifyUpdateMode);
prevPlaylist = 0;
return;
} else if (prevPreset) {
if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, NotifyUpdateMode); }
else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); }
prevPreset = 0;
return;
}
// preset not assigned
if (bri != 0) {
briLast = bri;
bri = 0;
stateUpdated(NotifyUpdateMode);
}
}
}
void publishMqtt(const char* state)
{
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED) {
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
strcat_P(subuf, PSTR("/motion"));
mqtt->publish(subuf, 0, false, state);
}
}
void switchStrip(bool switchOn);
void publishMqtt(bool switchOn);
// Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
void publishHomeAssistantAutodiscovery()
{
if (WLED_MQTT_CONNECTED) {
StaticJsonDocument<600> doc;
char uid[24], json_str[1024], buf[128];
sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40
doc[F("name")] = buf;
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
doc[F("stat_t")] = buf;
doc[F("pl_on")] = "on";
doc[F("pl_off")] = "off";
sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str());
doc[F("uniq_id")] = uid;
doc[F("dev_cla")] = F("motion");
doc[F("exp_aft")] = 1800;
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("ids")] = String(F("wled-sensor-")) + mqttClientID;
device[F("mf")] = "WLED";
device[F("mdl")] = F("FOSS");
device[F("sw")] = versionString;
sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid);
DEBUG_PRINTLN(buf);
size_t payload_size = serializeJson(doc, json_str);
DEBUG_PRINTLN(json_str);
mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain?
}
}
void publishHomeAssistantAutodiscovery();
/**
* Read and update PIR sensor state.
* Initilize/reset switch off timer
* Initialize/reset switch off timer
*/
bool updatePIRsensorState()
{
bool pinState = digitalRead(PIRsensorPin);
if (pinState != sensorPinState) {
sensorPinState = pinState; // change previous state
if (sensorPinState == HIGH) {
offTimerStart = 0;
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true);
else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
publishMqtt("on");
} else {
// start switch off timer
offTimerStart = millis();
if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
}
return true;
}
return false;
}
bool updatePIRsensorState();
/**
* switch off the strip if the delay has elapsed
*/
bool handleOffTimer()
{
if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) {
offTimerStart = 0;
if (enabled == true) {
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false);
else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
publishMqtt("off");
}
return true;
}
return false;
}
bool handleOffTimer();
public:
//Functions called by WLED
@@ -251,172 +124,57 @@ public:
* setup() is called once at boot. WiFi is not yet connected at this point.
* You can use it to initialize variables, sensors or similar.
*/
void setup()
{
if (enabled) {
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
if (PIRsensorPin >= 0 && pinManager.allocatePin(PIRsensorPin, false, PinOwner::UM_PIR)) {
// PIR Sensor mode INPUT_PULLUP
pinMode(PIRsensorPin, INPUT_PULLUP);
sensorPinState = digitalRead(PIRsensorPin);
} else {
if (PIRsensorPin >= 0) {
DEBUG_PRINTLN(F("PIRSensorSwitch pin allocation failed."));
}
PIRsensorPin = -1; // allocation failed
enabled = false;
}
}
initDone = true;
}
void setup() override;
/**
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
void connected()
{
}
//void connected();
/**
* onMqttConnect() is called when MQTT connection is established
*/
void onMqttConnect(bool sessionPresent) {
if (HomeAssistantDiscovery) {
publishHomeAssistantAutodiscovery();
}
}
void onMqttConnect(bool sessionPresent) override;
/**
* loop() is called continuously. Here you can check for events, read sensors, etc.
*/
void loop()
{
// only check sensors 4x/s
if (!enabled || millis() - lastLoop < 250 || strip.isUpdating()) return;
lastLoop = millis();
if (!updatePIRsensorState()) {
handleOffTimer();
}
}
void loop() override;
/**
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
*
* Add PIR sensor state and switch off timer duration to jsoninfo
*/
void addToJsonInfo(JsonObject &root)
{
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
void addToJsonInfo(JsonObject &root) override;
JsonArray infoArr = user.createNestedArray(FPSTR(_name));
String uiDomString;
if (enabled) {
if (offTimerStart > 0)
{
uiDomString = "";
unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000;
if (offSeconds >= 3600)
{
uiDomString += (offSeconds / 3600);
uiDomString += F("h ");
offSeconds %= 3600;
}
if (offSeconds >= 60)
{
uiDomString += (offSeconds / 60);
offSeconds %= 60;
}
else if (uiDomString.length() > 0)
{
uiDomString += 0;
}
if (uiDomString.length() > 0)
{
uiDomString += F("min ");
}
uiDomString += (offSeconds);
infoArr.add(uiDomString + F("s"));
} else {
infoArr.add(sensorPinState ? F("sensor on") : F("inactive"));
}
} else {
infoArr.add(F("disabled"));
}
uiDomString = F(" <button class=\"btn btn-xs\" onclick=\"requestJson({");
uiDomString += FPSTR(_name);
uiDomString += F(":{");
uiDomString += FPSTR(_enabled);
if (enabled) {
uiDomString += F(":false}});\">");
uiDomString += F("<i class=\"icons on\">&#xe325;</i>");
} else {
uiDomString += F(":true}});\">");
uiDomString += F("<i class=\"icons off\">&#xe08f;</i>");
}
uiDomString += F("</button>");
infoArr.add(uiDomString);
JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
sensor[F("motion")] = sensorPinState || offTimerStart>0 ? true : false;
}
/**
* onStateChanged() is used to detect WLED state change
*/
void onStateChange(uint8_t mode) override;
/**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
/*
void addToJsonState(JsonObject &root)
{
}
*/
//void addToJsonState(JsonObject &root);
/**
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject &root)
{
if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) {
if (usermod[FPSTR(_enabled)].is<bool>()) {
enabled = usermod[FPSTR(_enabled)].as<bool>();
}
}
}
void readFromJsonState(JsonObject &root) override;
/**
* provide the changeable values
*/
void addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000;
top["pin"] = PIRsensorPin;
top[FPSTR(_onPreset)] = m_onPreset;
top[FPSTR(_offPreset)] = m_offPreset;
top[FPSTR(_nightTime)] = m_nightTimeOnly;
top[FPSTR(_mqttOnly)] = m_mqttOnly;
top[FPSTR(_offOnly)] = m_offOnly;
top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY);
DEBUG_PRINTLN(F("PIR config saved."));
}
void addToConfig(JsonObject &root) override;
void appendConfigData()
{
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('PIRsensorSwitch:notifications',1,'Periodic WS updates');")); // 0 is field type, 1 is actual field
}
/**
* provide UI information and allow extending UI options
*/
void appendConfigData() override;
/**
* restore the changeable values
@@ -424,72 +182,13 @@ public:
*
* The function should return true if configuration was successfully loaded or false if there was no configuration.
*/
bool readFromConfig(JsonObject &root)
{
bool oldEnabled = enabled;
int8_t oldPin = PIRsensorPin;
DEBUG_PRINT(FPSTR(_name));
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
PIRsensorPin = top["pin"] | PIRsensorPin;
enabled = top[FPSTR(_enabled)] | enabled;
m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000;
m_onPreset = top[FPSTR(_onPreset)] | m_onPreset;
m_onPreset = max(0,min(250,(int)m_onPreset));
m_offPreset = top[FPSTR(_offPreset)] | m_offPreset;
m_offPreset = max(0,min(250,(int)m_offPreset));
m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly;
m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly;
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery;
NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY;
if (!initDone) {
// reading config prior to setup()
DEBUG_PRINTLN(F(" config loaded."));
} else {
if (oldPin != PIRsensorPin || oldEnabled != enabled) {
// check if pin is OK
if (oldPin != PIRsensorPin && oldPin >= 0) {
// if we are changing pin in settings page
// deallocate old pin
pinManager.deallocatePin(oldPin, PinOwner::UM_PIR);
if (pinManager.allocatePin(PIRsensorPin, false, PinOwner::UM_PIR)) {
pinMode(PIRsensorPin, INPUT_PULLUP);
} else {
// allocation failed
PIRsensorPin = -1;
enabled = false;
}
}
if (enabled) {
sensorPinState = digitalRead(PIRsensorPin);
}
}
DEBUG_PRINTLN(F(" config (re)loaded."));
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[FPSTR(_haDiscovery)].isNull();
}
bool readFromConfig(JsonObject &root) override;
/**
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
{
return USERMOD_ID_PIRSWITCH;
}
uint16_t getId() override { return USERMOD_ID_PIRSWITCH; }
};
// strings to reduce flash memory usage (used more than twice)
@@ -502,4 +201,373 @@ const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only";
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";
const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";
const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery";
const char PIRsensorSwitch::_notify[] PROGMEM = "notifications";
const char PIRsensorSwitch::_override[] PROGMEM = "override";
const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx";
bool PIRsensorSwitch::isDayTime() {
updateLocalTime();
uint8_t hr = hour(localTime);
uint8_t mi = minute(localTime);
if (sunrise && sunset) {
if (hour(sunrise)<hr && hour(sunset)>hr) {
return true;
} else {
if (hour(sunrise)==hr && minute(sunrise)<mi) {
return true;
}
if (hour(sunset)==hr && minute(sunset)>mi) {
return true;
}
}
}
return false;
}
void PIRsensorSwitch::switchStrip(bool switchOn)
{
if (m_offOnly && bri && (switchOn || (!PIRtriggered && !switchOn))) return; //if lights on and off only, do nothing
if (PIRtriggered && switchOn) return; //if already on and triggered before, do nothing
PIRtriggered = switchOn;
DEBUGUM_PRINTF_P(PSTR("PIR: strip=%s\n"), switchOn?"on":"off");
if (switchOn) {
if (m_onPreset) {
if (currentPlaylist>0 && !offMode) {
prevPlaylist = currentPlaylist;
unloadPlaylist();
} else if (currentPreset>0 && !offMode) {
prevPreset = currentPreset;
} else {
saveTemporaryPreset();
prevPlaylist = 0;
prevPreset = 255;
}
applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET);
return;
}
// preset not assigned
if (bri == 0) {
bri = briLast;
stateUpdated(CALL_MODE_BUTTON);
}
} else {
if (m_offPreset) {
applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET);
return;
} else if (prevPlaylist) {
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET);
prevPlaylist = 0;
return;
} else if (prevPreset) {
if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); }
else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); }
prevPreset = 0;
return;
}
// preset not assigned
if (bri != 0) {
briLast = bri;
bri = 0;
stateUpdated(CALL_MODE_BUTTON);
}
}
}
void PIRsensorSwitch::publishMqtt(bool switchOn)
{
#ifndef WLED_DISABLE_MQTT
//Check if MQTT Connected, otherwise it will crash the 8266
if (WLED_MQTT_CONNECTED) {
char buf[128];
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
mqtt->publish(buf, 0, false, switchOn?"on":"off");
// Domoticz formatted message
if (idx > 0) {
StaticJsonDocument <128> msg;
msg[F("idx")] = idx;
msg[F("RSSI")] = WiFi.RSSI();
msg[F("command")] = F("switchlight");
msg[F("switchcmd")] = switchOn ? F("On") : F("Off");
serializeJson(msg, buf, 128);
mqtt->publish("domoticz/in", 0, false, buf);
}
}
#endif
}
void PIRsensorSwitch::publishHomeAssistantAutodiscovery()
{
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED) {
StaticJsonDocument<600> doc;
char uid[24], json_str[1024], buf[128];
sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40
doc[F("name")] = buf;
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
doc[F("stat_t")] = buf;
doc[F("pl_on")] = "on";
doc[F("pl_off")] = "off";
sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str());
doc[F("uniq_id")] = uid;
doc[F("dev_cla")] = F("motion");
doc[F("exp_aft")] = 1800;
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
device[F("name")] = serverDescription;
device[F("ids")] = String(F("wled-sensor-")) + mqttClientID;
device[F("mf")] = F(WLED_BRAND);
device[F("mdl")] = F(WLED_PRODUCT_NAME);
device[F("sw")] = versionString;
sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid);
DEBUGUM_PRINTLN(buf);
size_t payload_size = serializeJson(doc, json_str);
DEBUGUM_PRINTLN(json_str);
mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain?
}
#endif
}
bool PIRsensorSwitch::updatePIRsensorState()
{
bool stateChanged = false;
bool allOff = true;
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
if (PIRsensorPin[i] < 0) continue;
bool pinState = digitalRead(PIRsensorPin[i]);
if (pinState != sensorPinState[i]) {
sensorPinState[i] = pinState; // change previous state
stateChanged = true;
if (sensorPinState[i] == HIGH) {
offTimerStart = 0;
allOff = false;
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true);
}
}
}
if (stateChanged) {
publishMqtt(!allOff);
// start switch off timer
if (allOff) offTimerStart = millis();
}
return stateChanged;
}
bool PIRsensorSwitch::handleOffTimer()
{
if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) {
offTimerStart = 0;
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false);
return true;
}
return false;
}
//Functions called by WLED
void PIRsensorSwitch::setup()
{
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
sensorPinState[i] = LOW;
if (PIRsensorPin[i] < 0) continue;
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
if (PinManager::allocatePin(PIRsensorPin[i], false, PinOwner::UM_PIR)) {
// PIR Sensor mode INPUT_PULLDOWN
#ifdef ESP8266
pinMode(PIRsensorPin[i], PIRsensorPin[i]==16 ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // ESP8266 has INPUT_PULLDOWN on GPIO16 only
#else
pinMode(PIRsensorPin[i], INPUT_PULLDOWN);
#endif
sensorPinState[i] = digitalRead(PIRsensorPin[i]);
} else {
DEBUGUM_PRINTF_P(PSTR("PIRSensorSwitch: pin %d allocation failed.\n"), i);
PIRsensorPin[i] = -1; // allocation failed
}
}
initDone = true;
}
void PIRsensorSwitch::onMqttConnect(bool sessionPresent)
{
if (HomeAssistantDiscovery) {
publishHomeAssistantAutodiscovery();
}
}
void PIRsensorSwitch::loop()
{
// only check sensors 5x/s
if (!enabled || millis() - lastLoop < 200) return;
lastLoop = millis();
if (!updatePIRsensorState()) {
handleOffTimer();
}
}
void PIRsensorSwitch::addToJsonInfo(JsonObject &root)
{
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
bool state = LOW;
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++)
if (PIRsensorPin[i] >= 0) state |= sensorPinState[i];
JsonArray infoArr = user.createNestedArray(FPSTR(_name));
String uiDomString;
if (enabled) {
if (offTimerStart > 0) {
uiDomString = "";
unsigned int offSeconds = (m_switchOffDelay - (millis() - offTimerStart)) / 1000;
if (offSeconds >= 3600) {
uiDomString += (offSeconds / 3600);
uiDomString += F("h ");
offSeconds %= 3600;
}
if (offSeconds >= 60) {
uiDomString += (offSeconds / 60);
offSeconds %= 60;
} else if (uiDomString.length() > 0) {
uiDomString += 0;
}
if (uiDomString.length() > 0) {
uiDomString += F("min ");
}
uiDomString += (offSeconds);
infoArr.add(uiDomString + F("s"));
} else {
infoArr.add(state ? F("sensor on") : F("inactive"));
}
} else {
infoArr.add(F("disabled"));
}
uiDomString = F(" <button class=\"btn btn-xs\" onclick=\"requestJson({");
uiDomString += FPSTR(_name);
uiDomString += F(":{");
uiDomString += FPSTR(_enabled);
if (enabled) {
uiDomString += F(":false}});\">");
uiDomString += F("<i class=\"icons on\">&#xe325;</i>");
} else {
uiDomString += F(":true}});\">");
uiDomString += F("<i class=\"icons off\">&#xe08f;</i>");
}
uiDomString += F("</button>");
infoArr.add(uiDomString);
if (enabled) {
JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
sensor[F("motion")] = state || offTimerStart>0 ? true : false;
}
}
void PIRsensorSwitch::onStateChange(uint8_t mode) {
if (!initDone) return;
DEBUGUM_PRINTF_P(PSTR("PIR: offTimerStart=%lu\n"), offTimerStart);
if (m_override && PIRtriggered && offTimerStart) { // debounce
// checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger
DEBUGUM_PRINTLN(F("PIR: Canceled."));
offTimerStart = 0;
PIRtriggered = false;
}
}
void PIRsensorSwitch::readFromJsonState(JsonObject &root)
{
if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) {
if (usermod[FPSTR(_enabled)].is<bool>()) {
enabled = usermod[FPSTR(_enabled)].as<bool>();
}
}
}
void PIRsensorSwitch::addToConfig(JsonObject &root)
{
JsonObject top = root.createNestedObject(FPSTR(_name));
top[FPSTR(_enabled)] = enabled;
top[FPSTR(_switchOffDelay)] = m_switchOffDelay / 1000;
JsonArray pinArray = top.createNestedArray("pin");
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) pinArray.add(PIRsensorPin[i]);
top[FPSTR(_onPreset)] = m_onPreset;
top[FPSTR(_offPreset)] = m_offPreset;
top[FPSTR(_nightTime)] = m_nightTimeOnly;
top[FPSTR(_mqttOnly)] = m_mqttOnly;
top[FPSTR(_offOnly)] = m_offOnly;
top[FPSTR(_override)] = m_override;
top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
top[FPSTR(_domoticzIDX)] = idx;
DEBUGUM_PRINTLN(F("PIR config saved."));
}
void PIRsensorSwitch::appendConfigData()
{
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
char str[128];
sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i);
oappend(str);
}
}
bool PIRsensorSwitch::readFromConfig(JsonObject &root)
{
int8_t oldPin[PIR_SENSOR_MAX_SENSORS];
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) {
oldPin[i] = PIRsensorPin[i];
PIRsensorPin[i] = -1;
}
DEBUGUM_PRINT(FPSTR(_name));
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
JsonArray pins = top["pin"];
if (!pins.isNull()) {
for (size_t i = 0; i < PIR_SENSOR_MAX_SENSORS; i++)
if (i < pins.size()) PIRsensorPin[i] = pins[i] | PIRsensorPin[i];
} else {
PIRsensorPin[0] = top["pin"] | oldPin[0];
}
enabled = top[FPSTR(_enabled)] | enabled;
m_switchOffDelay = (top[FPSTR(_switchOffDelay)] | m_switchOffDelay/1000) * 1000;
m_onPreset = top[FPSTR(_onPreset)] | m_onPreset;
m_onPreset = max(0,min(250,(int)m_onPreset));
m_offPreset = top[FPSTR(_offPreset)] | m_offPreset;
m_offPreset = max(0,min(250,(int)m_offPreset));
m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly;
m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly;
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
m_override = top[FPSTR(_override)] | m_override;
HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery;
idx = top[FPSTR(_domoticzIDX)] | idx;
if (!initDone) {
// reading config prior to setup()
DEBUGUM_PRINTLN(F(": config loaded."));
} else {
for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++)
if (oldPin[i] >= 0) PinManager::deallocatePin(oldPin[i], PinOwner::UM_PIR);
setup();
DEBUGUM_PRINTLN(F(": config (re)loaded."));
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !(pins.isNull() || pins.size() != PIR_SENSOR_MAX_SENSORS);
}

View File

@@ -5,7 +5,7 @@ v2 Usermod to to control PWM fan with RPM feedback and temperature control
This usermod requires the Dallas Temperature usermod to obtain temperature information. If it's not available, the fan will run at 100% speed.
If the fan does not have _tachometer_ (RPM) output you can set the _tachometer-pin_ to -1 to disable that feature.
You can also set the thershold temperature at which fan runs at lowest speed. If the measured temperature is 3°C greater than the threshold temperature, the fan will run at 100%.
You can also set the threshold temperature at which fan runs at lowest speed. If the measured temperature is 3°C greater than the threshold temperature, the fan will run at 100%.
If the _tachometer_ is supported, the current speed (in RPM) will be displayed on the WLED Info page.
@@ -22,7 +22,7 @@ This includes:
* PWM output pin (can be configured at compile time `-D PWM_PIN=xx`)
* tachometer input pin (can be configured at compile time `-D TACHO_PIN=xx`)
* sampling frequency in seconds
* threshold temperature in degees C
* threshold temperature in degrees Celsius
_NOTE:_ You may also need to tweak Dallas Temperature usermod sampling frequency to match PWM fan sampling frequency.

View File

@@ -1,7 +1,7 @@
#pragma once
#ifndef USERMOD_DALLASTEMPERATURE
#error The "PWM fan" usermod requires "Dallas Temeprature" usermod to function properly.
#if !defined(USERMOD_DALLASTEMPERATURE) && !defined(USERMOD_SHT)
#error The "PWM fan" usermod requires "Dallas Temeprature" or "SHT" usermod to function properly.
#endif
#include "wled.h"
@@ -42,6 +42,8 @@ class PWMFanUsermod : public Usermod {
#ifdef USERMOD_DALLASTEMPERATURE
UsermodTemperature* tempUM;
#elif defined(USERMOD_SHT)
ShtUsermod* tempUM;
#endif
// configurable parameters
@@ -50,9 +52,15 @@ class PWMFanUsermod : public Usermod {
uint8_t tachoUpdateSec = 30;
float targetTemperature = 35.0;
uint8_t minPWMValuePct = 0;
uint8_t maxPWMValuePct = 100;
uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups.
uint8_t pwmValuePct = 0;
// constant values
static const uint8_t _pwmMaxValue = 255;
static const uint8_t _pwmMaxStepCount = 7;
float _pwmTempStepSize = 0.5f;
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
static const char _enabled[];
@@ -61,25 +69,26 @@ class PWMFanUsermod : public Usermod {
static const char _temperature[];
static const char _tachoUpdateSec[];
static const char _minPWMValuePct[];
static const char _maxPWMValuePct[];
static const char _IRQperRotation[];
static const char _speed[];
static const char _lock[];
void initTacho(void) {
if (tachoPin < 0 || !pinManager.allocatePin(tachoPin, false, PinOwner::UM_Unspecified)){
if (tachoPin < 0 || !PinManager::allocatePin(tachoPin, false, PinOwner::UM_Unspecified)){
tachoPin = -1;
return;
}
pinMode(tachoPin, INPUT);
digitalWrite(tachoPin, HIGH);
attachInterrupt(digitalPinToInterrupt(tachoPin), rpm_fan, FALLING);
DEBUG_PRINTLN(F("Tacho sucessfully initialized."));
DEBUGUM_PRINTLN(F("Tacho sucessfully initialized."));
}
void deinitTacho(void) {
if (tachoPin < 0) return;
detachInterrupt(digitalPinToInterrupt(tachoPin));
pinManager.deallocatePin(tachoPin, PinOwner::UM_Unspecified);
PinManager::deallocatePin(tachoPin, PinOwner::UM_Unspecified);
tachoPin = -1;
}
@@ -102,7 +111,7 @@ class PWMFanUsermod : public Usermod {
// https://randomnerdtutorials.com/esp32-pwm-arduino-ide/
void initPWMfan(void) {
if (pwmPin < 0 || !pinManager.allocatePin(pwmPin, true, PinOwner::UM_Unspecified)) {
if (pwmPin < 0 || !PinManager::allocatePin(pwmPin, true, PinOwner::UM_Unspecified)) {
enabled = false;
pwmPin = -1;
return;
@@ -112,7 +121,7 @@ class PWMFanUsermod : public Usermod {
analogWriteRange(255);
analogWriteFreq(WLED_PWM_FREQ);
#else
pwmChannel = pinManager.allocateLedc(1);
pwmChannel = PinManager::allocateLedc(1);
if (pwmChannel == 255) { //no more free LEDC channels
deinitPWMfan(); return;
}
@@ -121,15 +130,15 @@ class PWMFanUsermod : public Usermod {
// attach the channel to the GPIO to be controlled
ledcAttachPin(pwmPin, pwmChannel);
#endif
DEBUG_PRINTLN(F("Fan PWM sucessfully initialized."));
DEBUGUM_PRINTLN(F("Fan PWM sucessfully initialized."));
}
void deinitPWMfan(void) {
if (pwmPin < 0) return;
pinManager.deallocatePin(pwmPin, PinOwner::UM_Unspecified);
PinManager::deallocatePin(pwmPin, PinOwner::UM_Unspecified);
#ifdef ARDUINO_ARCH_ESP32
pinManager.deallocateLedc(pwmChannel, 1);
PinManager::deallocateLedc(pwmChannel, 1);
#endif
pwmPin = -1;
}
@@ -145,7 +154,7 @@ class PWMFanUsermod : public Usermod {
}
float getActualTemperature(void) {
#ifdef USERMOD_DALLASTEMPERATURE
#if defined(USERMOD_DALLASTEMPERATURE) || defined(USERMOD_SHT)
if (tempUM != nullptr)
return tempUM->getTemperatureC();
#endif
@@ -154,41 +163,37 @@ class PWMFanUsermod : public Usermod {
void setFanPWMbasedOnTemperature(void) {
float temp = getActualTemperature();
float difftemp = temp - targetTemperature;
// Default to run fan at full speed.
int newPWMvalue = 255;
int pwmStep = ((100 - minPWMValuePct) * newPWMvalue) / (7*100);
int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100;
// dividing minPercent and maxPercent into equal pwmvalue sizes
int pwmStepSize = ((maxPWMValuePct - minPWMValuePct) * _pwmMaxValue) / (_pwmMaxStepCount*100);
int pwmStep = calculatePwmStep(temp - targetTemperature);
// minimum based on full speed - not entered MaxPercent
int pwmMinimumValue = (minPWMValuePct * _pwmMaxValue) / 100;
updateFanSpeed(pwmMinimumValue + pwmStep*pwmStepSize);
}
if ((temp == NAN) || (temp <= -100.0)) {
DEBUG_PRINTLN(F("WARNING: no temperature value available. Cannot do temperature control. Will set PWM fan to 255."));
} else if (difftemp <= 0.0) {
// Temperature is below target temperature. Run fan at minimum speed.
newPWMvalue = pwmMinimumValue;
} else if (difftemp <= 0.5) {
newPWMvalue = pwmMinimumValue + pwmStep;
} else if (difftemp <= 1.0) {
newPWMvalue = pwmMinimumValue + 2*pwmStep;
} else if (difftemp <= 1.5) {
newPWMvalue = pwmMinimumValue + 3*pwmStep;
} else if (difftemp <= 2.0) {
newPWMvalue = pwmMinimumValue + 4*pwmStep;
} else if (difftemp <= 2.5) {
newPWMvalue = pwmMinimumValue + 5*pwmStep;
} else if (difftemp <= 3.0) {
newPWMvalue = pwmMinimumValue + 6*pwmStep;
uint8_t calculatePwmStep(float diffTemp){
if ((diffTemp == NAN) || (diffTemp <= -100.0)) {
DEBUGUM_PRINTLN(F("WARNING: no temperature value available. Cannot do temperature control. Will set PWM fan to 255."));
return _pwmMaxStepCount;
}
updateFanSpeed(newPWMvalue);
if(diffTemp <=0){
return 0;
}
int calculatedStep = (diffTemp / _pwmTempStepSize)+1;
// anything greater than max stepcount gets max
return (uint8_t)min((int)_pwmMaxStepCount,calculatedStep);
}
public:
// gets called once at boot. Do all initialization that doesn't depend on
// network here
void setup() {
void setup() override {
#ifdef USERMOD_DALLASTEMPERATURE
// This Usermod requires Temperature usermod
tempUM = (UsermodTemperature*) usermods.lookup(USERMOD_ID_TEMPERATURE);
tempUM = (UsermodTemperature*) UsermodManager::lookup(USERMOD_ID_TEMPERATURE);
#elif defined(USERMOD_SHT)
tempUM = (ShtUsermod*) UsermodManager::lookup(USERMOD_ID_SHT);
#endif
initTacho();
initPWMfan();
@@ -198,12 +203,12 @@ class PWMFanUsermod : public Usermod {
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void connected() {}
void connected() override {}
/*
* Da loop.
*/
void loop() {
void loop() override {
if (!enabled || strip.isUpdating()) return;
unsigned long now = millis();
@@ -218,7 +223,7 @@ class PWMFanUsermod : public Usermod {
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
void addToJsonInfo(JsonObject& root) {
void addToJsonInfo(JsonObject& root) override {
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
@@ -267,7 +272,7 @@ class PWMFanUsermod : public Usermod {
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject& root) {
void readFromJsonState(JsonObject& root) override {
if (!initDone) return; // prevent crash on boot applyPreset()
JsonObject usermod = root[FPSTR(_name)];
if (!usermod.isNull()) {
@@ -300,7 +305,7 @@ class PWMFanUsermod : public Usermod {
*
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
*/
void addToConfig(JsonObject& root) {
void addToConfig(JsonObject& root) override {
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_enabled)] = enabled;
top[FPSTR(_pwmPin)] = pwmPin;
@@ -308,8 +313,9 @@ class PWMFanUsermod : public Usermod {
top[FPSTR(_tachoUpdateSec)] = tachoUpdateSec;
top[FPSTR(_temperature)] = targetTemperature;
top[FPSTR(_minPWMValuePct)] = minPWMValuePct;
top[FPSTR(_maxPWMValuePct)] = maxPWMValuePct;
top[FPSTR(_IRQperRotation)] = numberOfInterrupsInOneSingleRotation;
DEBUG_PRINTLN(F("Autosave config saved."));
DEBUGUM_PRINTLN(F("Autosave config saved."));
}
/*
@@ -322,14 +328,14 @@ class PWMFanUsermod : public Usermod {
*
* The function should return true if configuration was successfully loaded or false if there was no configuration.
*/
bool readFromConfig(JsonObject& root) {
bool readFromConfig(JsonObject& root) override {
int8_t newTachoPin = tachoPin;
int8_t newPwmPin = pwmPin;
JsonObject top = root[FPSTR(_name)];
DEBUG_PRINT(FPSTR(_name));
DEBUGUM_PRINT(FPSTR(_name));
if (top.isNull()) {
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
@@ -341,6 +347,8 @@ class PWMFanUsermod : public Usermod {
targetTemperature = top[FPSTR(_temperature)] | targetTemperature;
minPWMValuePct = top[FPSTR(_minPWMValuePct)] | minPWMValuePct;
minPWMValuePct = (uint8_t) min(100,max(0,(int)minPWMValuePct)); // bounds checking
maxPWMValuePct = top[FPSTR(_maxPWMValuePct)] | maxPWMValuePct;
maxPWMValuePct = (uint8_t) min(100,max((int)minPWMValuePct,(int)maxPWMValuePct)); // bounds checking
numberOfInterrupsInOneSingleRotation = top[FPSTR(_IRQperRotation)] | numberOfInterrupsInOneSingleRotation;
numberOfInterrupsInOneSingleRotation = (uint8_t) max(1,(int)numberOfInterrupsInOneSingleRotation); // bounds checking
@@ -348,12 +356,12 @@ class PWMFanUsermod : public Usermod {
// first run: reading from cfg.json
tachoPin = newTachoPin;
pwmPin = newPwmPin;
DEBUG_PRINTLN(F(" config loaded."));
DEBUGUM_PRINTLN(F(" config loaded."));
} else {
DEBUG_PRINTLN(F(" config (re)loaded."));
DEBUGUM_PRINTLN(F(" config (re)loaded."));
// changing paramters from settings page
if (tachoPin != newTachoPin || pwmPin != newPwmPin) {
DEBUG_PRINTLN(F("Re-init pins."));
DEBUGUM_PRINTLN(F("Re-init pins."));
// deallocate pin and release interrupts
deinitTacho();
deinitPWMfan();
@@ -372,7 +380,7 @@ class PWMFanUsermod : public Usermod {
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId() {
uint16_t getId() override {
return USERMOD_ID_PWM_FAN;
}
};
@@ -385,6 +393,7 @@ const char PWMFanUsermod::_pwmPin[] PROGMEM = "PWM-pin";
const char PWMFanUsermod::_temperature[] PROGMEM = "target-temp-C";
const char PWMFanUsermod::_tachoUpdateSec[] PROGMEM = "tacho-update-s";
const char PWMFanUsermod::_minPWMValuePct[] PROGMEM = "min-PWM-percent";
const char PWMFanUsermod::_maxPWMValuePct[] PROGMEM = "max-PWM-percent";
const char PWMFanUsermod::_IRQperRotation[] PROGMEM = "IRQs-per-rotation";
const char PWMFanUsermod::_speed[] PROGMEM = "speed";
const char PWMFanUsermod::_lock[] PROGMEM = "lock";

View File

@@ -12,8 +12,7 @@ class RTCUsermod : public Usermod {
public:
void setup() {
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; }
if (i2c_scl<0 || i2c_sda<0) { disabled = true; return; }
RTC.begin();
time_t rtcTime = RTC.get();
if (rtcTime) {
@@ -25,8 +24,8 @@ class RTCUsermod : public Usermod {
}
void loop() {
if (strip.isUpdating()) return;
if (!disabled && toki.isTick()) {
if (disabled || strip.isUpdating()) return;
if (toki.isTick()) {
time_t t = toki.second();
if (t != RTC.get()) RTC.set(t); //set RTC to NTP/UI-provided value
}

View File

@@ -43,12 +43,12 @@ void handleRelay()
digitalWrite(PIN_UP_RELAY, LOW);
upActiveBefore = true;
upStartTime = millis();
DEBUG_PRINTLN("UPA");
DEBUGUM_PRINTLN(F("UPA"));
}
if (millis()- upStartTime > PIN_ON_TIME)
{
upActive = false;
DEBUG_PRINTLN("UPN");
DEBUGUM_PRINTLN(F("UPN"));
}
} else if (upActiveBefore)
{

View File

@@ -3,7 +3,9 @@
#include "wled.h"
//Pin defaults for QuinLed Dig-Uno (A0)
#ifndef PHOTORESISTOR_PIN
#define PHOTORESISTOR_PIN A0
#endif
// the frequency to check photoresistor, 10 seconds
#ifndef USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL
@@ -30,7 +32,7 @@
#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f
#endif
// only report if differance grater than offset value
// only report if difference grater than offset value
#ifndef USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE
#define USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE 5
#endif
@@ -109,6 +111,7 @@ public:
{
lastLDRValue = currentLDRValue;
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED)
{
char subuf[45];
@@ -118,9 +121,10 @@ public:
}
else
{
DEBUG_PRINTLN("Missing MQTT connection. Not publishing data");
DEBUGUM_PRINTLN(F("Missing MQTT connection. Not publishing data"));
}
}
#endif
}
uint16_t getLastLDRValue()
@@ -168,7 +172,7 @@ public:
top[FPSTR(_adcPrecision)] = adcPrecision;
top[FPSTR(_offset)] = offset;
DEBUG_PRINTLN(F("Photoresistor config saved."));
DEBUGUM_PRINTLN(F("Photoresistor config saved."));
}
/**
@@ -179,8 +183,8 @@ public:
// we look for JSON object.
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINT(FPSTR(_name));
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
@@ -190,8 +194,8 @@ public:
resistorValue = top[FPSTR(_resistorValue)] | resistorValue;
adcPrecision = top[FPSTR(_adcPrecision)] | adcPrecision;
offset = top[FPSTR(_offset)] | offset;
DEBUG_PRINT(FPSTR(_name));
DEBUG_PRINTLN(F(" config (re)loaded."));
DEBUGUM_PRINT(FPSTR(_name));
DEBUGUM_PRINTLN(F(" config (re)loaded."));
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return true;
@@ -205,4 +209,4 @@ const char Usermod_SN_Photoresistor::_readInterval[] PROGMEM = "read-interval-s"
const char Usermod_SN_Photoresistor::_referenceVoltage[] PROGMEM = "supplied-voltage";
const char Usermod_SN_Photoresistor::_resistorValue[] PROGMEM = "resistor-value";
const char Usermod_SN_Photoresistor::_adcPrecision[] PROGMEM = "adc-precision";
const char Usermod_SN_Photoresistor::_offset[] PROGMEM = "offset";
const char Usermod_SN_Photoresistor::_offset[] PROGMEM = "offset";

View File

@@ -9,6 +9,6 @@
void registerUsermods()
{
#ifdef USERMOD_SN_PHOTORESISTOR
usermods.add(new Usermod_SN_Photoresistor());
UsermodManager::add(new Usermod_SN_Photoresistor());
#endif
}

View File

@@ -17,18 +17,15 @@
#ifndef TFT_HEIGHT
#error Please define TFT_HEIGHT
#endif
#ifndef TFT_MOSI
#error Please define TFT_MOSI
#endif
#ifndef TFT_SCLK
#error Please define TFT_SCLK
#endif
#ifndef TFT_DC
#error Please define TFT_DC
#endif
#ifndef TFT_RST
#error Please define TFT_RST
#endif
#ifndef TFT_CS
#error Please define TFT_CS
#endif
#ifndef LOAD_GLCD
#error Please define LOAD_GLCD
#endif
@@ -138,10 +135,16 @@ class St7789DisplayUsermod : public Usermod {
* setup() is called once at boot. WiFi is not yet connected at this point.
* You can use it to initialize variables, sensors or similar.
*/
void setup()
void setup() override
{
PinManagerPinType pins[] = { { TFT_MOSI, true }, { TFT_MISO, false}, { TFT_SCLK, true }, { TFT_CS, true}, { TFT_DC, true}, { TFT_RST, true }, { TFT_BL, true } };
if (!pinManager.allocateMultiplePins(pins, 7, PinOwner::UM_FourLineDisplay)) { enabled = false; return; }
PinManagerPinType spiPins[] = { { spi_mosi, true }, { spi_miso, false}, { spi_sclk, true } };
if (!PinManager::allocateMultiplePins(spiPins, 3, PinOwner::HW_SPI)) { enabled = false; return; }
PinManagerPinType displayPins[] = { { TFT_CS, true}, { TFT_DC, true}, { TFT_RST, true }, { TFT_BL, true } };
if (!PinManager::allocateMultiplePins(displayPins, sizeof(displayPins)/sizeof(PinManagerPinType), PinOwner::UM_FourLineDisplay)) {
PinManager::deallocateMultiplePins(spiPins, 3, PinOwner::HW_SPI);
enabled = false;
return;
}
tft.init();
tft.setRotation(0); //Rotation here is set up for the text to be readable with the port on the left. Use 1 to flip.
@@ -162,7 +165,7 @@ class St7789DisplayUsermod : public Usermod {
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
void connected() {
void connected() override {
//Serial.println("Connected to WiFi!");
}
@@ -176,7 +179,7 @@ class St7789DisplayUsermod : public Usermod {
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
* Instead, use a timer check as shown here.
*/
void loop() {
void loop() override {
char buff[LINE_BUFFER_SIZE];
// Check if we time interval for redrawing passes.
@@ -307,7 +310,7 @@ class St7789DisplayUsermod : public Usermod {
// Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate).
tft.print("Current: ");
tft.setTextColor(TFT_ORANGE);
tft.print(strip.currentMilliamps);
tft.print(BusManager::currentMilliamps());
tft.print("mA");
}
@@ -316,7 +319,7 @@ class St7789DisplayUsermod : public Usermod {
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
void addToJsonInfo(JsonObject& root)
void addToJsonInfo(JsonObject& root) override
{
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
@@ -330,7 +333,7 @@ class St7789DisplayUsermod : public Usermod {
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void addToJsonState(JsonObject& root)
void addToJsonState(JsonObject& root) override
{
//root["user0"] = userVar0;
}
@@ -340,7 +343,7 @@ class St7789DisplayUsermod : public Usermod {
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject& root)
void readFromJsonState(JsonObject& root) override
{
//userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
@@ -361,13 +364,10 @@ class St7789DisplayUsermod : public Usermod {
*
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
*/
void addToConfig(JsonObject& root)
void addToConfig(JsonObject& root) override
{
JsonObject top = root.createNestedObject("ST7789");
JsonArray pins = top.createNestedArray("pin");
pins.add(TFT_MOSI);
pins.add(TFT_MISO);
pins.add(TFT_SCLK);
pins.add(TFT_CS);
pins.add(TFT_DC);
pins.add(TFT_RST);
@@ -376,6 +376,13 @@ class St7789DisplayUsermod : public Usermod {
}
void appendConfigData() override {
oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
oappend(SET_F("addInfo('ST7789:pin[]',3,'','SPI BL');"));
}
/*
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
@@ -384,7 +391,7 @@ class St7789DisplayUsermod : public Usermod {
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
*/
bool readFromConfig(JsonObject& root)
bool readFromConfig(JsonObject& root) override
{
//JsonObject top = root["top"];
//userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot)
@@ -396,7 +403,7 @@ class St7789DisplayUsermod : public Usermod {
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
uint16_t getId() override
{
return USERMOD_ID_ST7789_DISPLAY;
}

View File

@@ -1,3 +1,7 @@
#ifndef WLED_ENABLE_MQTT
#error "This user mod requires MQTT to be enabled."
#endif
#pragma once
// this is remixed from usermod_v2_SensorsToMqtt.h (sensors_to_mqtt usermod)
@@ -9,14 +13,6 @@
Adafruit_Si7021 si7021;
#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards
uint8_t SCL_PIN = 22;
uint8_t SDA_PIN = 21;
#else //ESP8266 boards
uint8_t SCL_PIN = 5;
uint8_t SDA_PIN = 4;
#endif
class Si7021_MQTT_HA : public Usermod
{
private:
@@ -97,8 +93,8 @@ class Si7021_MQTT_HA : public Usermod
JsonObject device = doc.createNestedObject("device"); // attach the sensor to the same device
device["name"] = String(serverDescription);
device["model"] = "WLED";
device["manufacturer"] = "Aircoookie";
device["model"] = F(WLED_PRODUCT_NAME);
device["manufacturer"] = F(WLED_BRAND);
device["identifiers"] = String("wled-") + String(serverDescription);
device["sw_version"] = VERSION;
@@ -180,7 +176,6 @@ class Si7021_MQTT_HA : public Usermod
{
if (enabled) {
Serial.println("Si7021_MQTT_HA: Starting!");
Wire.begin(SDA_PIN, SCL_PIN);
Serial.println("Si7021_MQTT_HA: Initializing sensors.. ");
_initializeSensor();
}

View File

@@ -3,7 +3,7 @@
* This file allows you to add own functionality to WLED more easily
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h)
* bytes 2400+ are currently ununsed, but might be used for future wled features
* bytes 2400+ are currently unused, but might be used for future wled features
*/
/*
@@ -144,7 +144,7 @@ void userLoop() {
// First row with Wifi name
tft.setCursor(1, 1);
tft.print(knownSsid.substring(0, tftcharwidth > 1 ? tftcharwidth - 1 : 0));
// Print `~` char to indicate that SSID is longer, than our dicplay
// Print `~` char to indicate that SSID is longer than our display
if (knownSsid.length() > tftcharwidth)
tft.print("~");

View File

@@ -1,13 +1,10 @@
; Options
; -------
; USERMOD_DALLASTEMPERATURE - define this to have this user mod included wled00\usermods_list.cpp
; USERMOD_DALLASTEMPERATURE_CELSIUS - define this to report temperatures in degrees celsius, otherwise fahrenheit will be reported
; USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds
; USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds
;
[env:d1_mini_usermod_dallas_temperature_C]
extends = env:d1_mini
build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE -D USERMOD_DALLASTEMPERATURE_CELSIUS
build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE
lib_deps = ${env.lib_deps}
milesburton/DallasTemperature@^3.9.0
OneWire@~2.3.5
paulstoffregen/OneWire@~2.3.8

View File

@@ -7,6 +7,8 @@ May be expanded with support for different sensor types in the future.
If temperature sensor is not detected during boot, this usermod will be disabled.
Maintained by @blazoncek
## Installation
Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`.
@@ -14,9 +16,9 @@ Copy the example `platformio_override.ini` to the root directory. This file sho
### Define Your Options
* `USERMOD_DALLASTEMPERATURE` - enables this user mod wled00/usermods_list.cpp
* `USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT` - umber of milliseconds after boot to take first measurement, defaults to 20000 ms
* `USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL` - number of milliseconds between measurements, defaults to 60000 ms (60s)
All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Farenheit and measurement interval.
All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Fahrenheit and measurement interval.
## Project link
@@ -27,7 +29,6 @@ All parameters can be configured at runtime via the Usermods settings page, incl
If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dallas_temperature_C`.
If you are not using `platformio_override.ini`, you might have to uncomment `OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini
@@ -42,9 +43,8 @@ default_envs = d1_mini
...
lib_deps =
...
#For Dallas sensor uncomment following line
OneWire@~2.3.5
...
#For Dallas sensor uncomment following
paulstoffregen/OneWire @ ~2.3.8
```
## Change Log
@@ -54,5 +54,14 @@ lib_deps =
* Do not report erroneous low temperatures to MQTT
* Disable plugin if temperature sensor not detected
* Report the number of seconds until the first read in the info screen instead of sensor error
2021-04
* Adaptation for runtime configuration.
2023-05
* Rewrite to conform to newer recommendations.
* Recommended @blazoncek fork of OneWire for ESP32 to avoid Sensor error
2024-09
* Update OneWire to version 2.3.8, which includes stickbreaker's and garyd9's ESP32 fixes:
blazoncek's fork is no longer needed

View File

@@ -17,6 +17,8 @@
#define USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL 60000
#endif
static uint16_t mode_temperature();
class UsermodTemperature : public Usermod {
private:
@@ -29,6 +31,7 @@ class UsermodTemperature : public Usermod {
bool degC = true;
// using parasite power on the sensor
bool parasite = false;
int8_t parasitePin = -1;
// how often do we read from sensor?
unsigned long readingInterval = USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL;
// set last reading as "40 sec before boot", so first reading is taken after 20 sec
@@ -47,329 +50,422 @@ class UsermodTemperature : public Usermod {
bool enabled = true;
bool HApublished = false;
int16_t idx = -1; // Domoticz virtual sensor idx
// strings to reduce flash memory usage (used more than twice)
static const char _name[];
static const char _enabled[];
static const char _readInterval[];
static const char _parasite[];
static const char _parasitePin[];
static const char _domoticzIDX[];
static const char _sensor[];
static const char _temperature[];
static const char _Temperature[];
static const char _data_fx[];
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float readDallas() {
byte data[9];
int16_t result; // raw data from sensor
float retVal = -127.0f;
if (oneWire->reset()) { // if reset() fails there are no OneWire devices
oneWire->skip(); // skip ROM
oneWire->write(0xBE); // read (temperature) from EEPROM
oneWire->read_bytes(data, 9); // first 2 bytes contain temperature
#ifdef WLED_DEBUG
if (OneWire::crc8(data,8) != data[8]) {
DEBUG_PRINTLN(F("CRC error reading temperature."));
for (byte i=0; i < 9; i++) DEBUG_PRINTF("0x%02X ", data[i]);
DEBUG_PRINT(F(" => "));
DEBUG_PRINTF("0x%02X\n", OneWire::crc8(data,8));
}
#endif
switch(sensorFound) {
case 0x10: // DS18S20 has 9-bit precision
result = (data[1] << 8) | data[0];
retVal = float(result) * 0.5f;
break;
case 0x22: // DS18B20
case 0x28: // DS1822
case 0x3B: // DS1825
case 0x42: // DS28EA00
result = (data[1]<<4) | (data[0]>>4); // we only need whole part, we will add fraction when returning
if (data[1] & 0x80) result |= 0xF000; // fix negative value
retVal = float(result) + ((data[0] & 0x08) ? 0.5f : 0.0f);
break;
}
}
for (byte i=1; i<9; i++) data[0] &= data[i];
return data[0]==0xFF ? -127.0f : retVal;
}
float readDallas();
void requestTemperatures();
void readTemperature();
bool findSensor();
#ifndef WLED_DISABLE_MQTT
void publishHomeAssistantAutodiscovery();
#endif
void requestTemperatures() {
DEBUG_PRINTLN(F("Requesting temperature."));
oneWire->reset();
oneWire->skip(); // skip ROM
oneWire->write(0x44,parasite); // request new temperature reading (TODO: parasite would need special handling)
lastTemperaturesRequest = millis();
waitingForConversion = true;
}
void readTemperature() {
temperature = readDallas();
lastMeasurement = millis();
waitingForConversion = false;
//DEBUG_PRINTF("Read temperature %2.1f.\n", temperature); // does not work properly on 8266
DEBUG_PRINT(F("Read temperature "));
DEBUG_PRINTLN(temperature);
}
bool findSensor() {
DEBUG_PRINTLN(F("Searching for sensor..."));
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
// find out if we have DS18xxx sensor attached
oneWire->reset_search();
delay(10);
while (oneWire->search(deviceAddress)) {
DEBUG_PRINTLN(F("Found something..."));
if (oneWire->crc8(deviceAddress, 7) == deviceAddress[7]) {
switch (deviceAddress[0]) {
case 0x10: // DS18S20
case 0x22: // DS18B20
case 0x28: // DS1822
case 0x3B: // DS1825
case 0x42: // DS28EA00
DEBUG_PRINTLN(F("Sensor found."));
sensorFound = deviceAddress[0];
DEBUG_PRINTF("0x%02X\n", sensorFound);
return true;
}
}
}
DEBUG_PRINTLN(F("Sensor NOT found."));
return false;
}
void publishHomeAssistantAutodiscovery() {
if (!WLED_MQTT_CONNECTED) return;
char json_str[1024], buf[128];
size_t payload_size;
StaticJsonDocument<1024> json;
sprintf_P(buf, PSTR("%s Temperature"), serverDescription);
json[F("name")] = buf;
strcpy(buf, mqttDeviceTopic);
strcat_P(buf, PSTR("/temperature"));
json[F("state_topic")] = buf;
json[F("device_class")] = F("temperature");
json[F("unique_id")] = escapedMac.c_str();
json[F("unit_of_measurement")] = F("°C");
payload_size = serializeJson(json, json_str);
sprintf_P(buf, PSTR("homeassistant/sensor/%s/config"), escapedMac.c_str());
mqtt->publish(buf, 0, true, json_str, payload_size);
HApublished = true;
}
static UsermodTemperature* _instance; // to overcome nonstatic getTemperatureC() method and avoid UsermodManager::lookup(USERMOD_ID_TEMPERATURE);
public:
void setup() {
int retries = 10;
sensorFound = 0;
temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C
if (enabled) {
// config says we are enabled
DEBUG_PRINTLN(F("Allocating temperature pin..."));
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
if (temperaturePin >= 0 && pinManager.allocatePin(temperaturePin, true, PinOwner::UM_Temperature)) {
oneWire = new OneWire(temperaturePin);
if (oneWire->reset()) {
while (!findSensor() && retries--) {
delay(25); // try to find sensor
}
}
} else {
if (temperaturePin >= 0) {
DEBUG_PRINTLN(F("Temperature pin allocation failed."));
}
temperaturePin = -1; // allocation failed
}
}
lastMeasurement = millis() - readingInterval + 10000;
initDone = true;
}
void loop() {
if (!enabled || !sensorFound || strip.isUpdating()) return;
static uint8_t errorCount = 0;
unsigned long now = millis();
// check to see if we are due for taking a measurement
// lastMeasurement will not be updated until the conversion
// is complete the the reading is finished
if (now - lastMeasurement < readingInterval) return;
// we are due for a measurement, if we are not already waiting
// for a conversion to complete, then make a new request for temps
if (!waitingForConversion) {
requestTemperatures();
return;
}
// we were waiting for a conversion to complete, have we waited log enough?
if (now - lastTemperaturesRequest >= 750 /* 93.75ms per the datasheet but can be up to 750ms */) {
readTemperature();
if (getTemperatureC() < -100.0f) {
if (++errorCount > 10) sensorFound = 0;
lastMeasurement = now - readingInterval + 300; // force new measurement in 300ms
return;
}
errorCount = 0;
if (WLED_MQTT_CONNECTED) {
char subuf[64];
strcpy(subuf, mqttDeviceTopic);
if (temperature > -100.0f) {
// dont publish super low temperature as the graph will get messed up
// the DallasTemperature library returns -127C or -196.6F when problem
// reading the sensor
strcat_P(subuf, PSTR("/temperature"));
mqtt->publish(subuf, 0, false, String(getTemperatureC()).c_str());
strcat_P(subuf, PSTR("_f"));
mqtt->publish(subuf, 0, false, String(getTemperatureF()).c_str());
} else {
// publish something else to indicate status?
}
}
}
}
/**
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
//void connected() {}
/**
* subscribe to MQTT topic if needed
*/
void onMqttConnect(bool sessionPresent) {
//(re)subscribe to required topics
//char subuf[64];
if (mqttDeviceTopic[0] != 0) {
publishHomeAssistantAutodiscovery();
}
}
UsermodTemperature() { _instance = this; }
static UsermodTemperature *getInstance() { return UsermodTemperature::_instance; }
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC() {
return (float)temperature;
inline float getTemperatureC() { return temperature; }
inline float getTemperatureF() { return temperature * 1.8f + 32.0f; }
float getTemperature();
const char *getTemperatureUnit();
uint16_t getId() override { return USERMOD_ID_TEMPERATURE; }
void setup() override;
void loop() override;
//void connected() override;
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent) override;
#endif
//void onUpdateBegin(bool init) override;
//bool handleButton(uint8_t b) override;
//void handleOverlayDraw() override;
void addToJsonInfo(JsonObject& root) override;
//void addToJsonState(JsonObject &root) override;
//void readFromJsonState(JsonObject &root) override;
void addToConfig(JsonObject &root) override;
bool readFromConfig(JsonObject &root) override;
void appendConfigData() override;
};
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float UsermodTemperature::readDallas() {
byte data[9];
int16_t result; // raw data from sensor
float retVal = -127.0f;
if (oneWire->reset()) { // if reset() fails there are no OneWire devices
oneWire->skip(); // skip ROM
oneWire->write(0xBE); // read (temperature) from EEPROM
oneWire->read_bytes(data, 9); // first 2 bytes contain temperature
#ifdef WLED_DEBUG_USERMODS
if (OneWire::crc8(data,8) != data[8]) {
DEBUGUM_PRINTLN(F("CRC error reading temperature."));
for (unsigend i=0; i < 9; i++) DEBUGUM_PRINTF_P(PSTR("0x%02X "), data[i]);
DEBUGUM_PRINTF_P(PSTR(" => 0x%02X\n"), OneWire::crc8(data,8));
}
inline float getTemperatureF() {
return (float)temperature * 1.8f + 32;
#endif
switch(sensorFound) {
case 0x10: // DS18S20 has 9-bit precision
result = (data[1] << 8) | data[0];
retVal = float(result) * 0.5f;
break;
case 0x22: // DS18B20
case 0x28: // DS1822
case 0x3B: // DS1825
case 0x42: // DS28EA00
result = (data[1]<<4) | (data[0]>>4); // we only need whole part, we will add fraction when returning
if (data[1] & 0x80) result |= 0xF000; // fix negative value
retVal = float(result) + ((data[0] & 0x08) ? 0.5f : 0.0f);
break;
}
}
for (unsigned i=1; i<9; i++) data[0] &= data[i];
return data[0]==0xFF ? -127.0f : retVal;
}
/*
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
void addToJsonInfo(JsonObject& root) {
// dont add temperature to info if we are disabled
if (!enabled) return;
void UsermodTemperature::requestTemperatures() {
DEBUGUM_PRINTLN(F("Requesting temperature."));
oneWire->reset();
oneWire->skip(); // skip ROM
oneWire->write(0x44,parasite); // request new temperature reading
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, HIGH); // has to happen within 10us (open MOSFET)
lastTemperaturesRequest = millis();
waitingForConversion = true;
}
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
void UsermodTemperature::readTemperature() {
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
temperature = readDallas();
lastMeasurement = millis();
waitingForConversion = false;
//DEBUGUM_PRINTF_P(PSTR("Read temperature %2.1f.\n"), temperature); // does not work properly on 8266
DEBUGUM_PRINTF_P(PSTR("Read temperature %3.1f\n"), (double)temperature);
}
JsonArray temp = user.createNestedArray(FPSTR(_name));
if (temperature <= -100.0f) {
temp.add(0);
temp.add(F(" Sensor Error!"));
return;
bool UsermodTemperature::findSensor() {
DEBUGUM_PRINTLN(F("Searching for sensor..."));
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
// find out if we have DS18xxx sensor attached
oneWire->reset_search();
delay(10);
while (oneWire->search(deviceAddress)) {
DEBUGUM_PRINTLN(F("Found something..."));
if (oneWire->crc8(deviceAddress, 7) == deviceAddress[7]) {
switch (deviceAddress[0]) {
case 0x10: // DS18S20
case 0x22: // DS18B20
case 0x28: // DS1822
case 0x3B: // DS1825
case 0x42: // DS28EA00
DEBUGUM_PRINTLN(F("Sensor found."));
sensorFound = deviceAddress[0];
DEBUGUM_PRINTF_P(PSTR("0x%02X\n"), sensorFound);
return true;
}
temp.add(degC ? getTemperatureC() : getTemperatureF());
temp.add(degC ? F("°C") : F("°F"));
JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
temp = sensor.createNestedArray(F("temp"));
temp.add(degC ? temperature : (float)temperature * 1.8f + 32);
temp.add(degC ? F("°C") : F("°F"));
}
}
DEBUGUM_PRINTLN(F("Sensor NOT found."));
return false;
}
/**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
//void addToJsonState(JsonObject &root)
//{
//}
#ifndef WLED_DISABLE_MQTT
void UsermodTemperature::publishHomeAssistantAutodiscovery() {
if (!WLED_MQTT_CONNECTED) return;
/**
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
*/
//void readFromJsonState(JsonObject &root) {
// if (!initDone) return; // prevent crash on boot applyPreset()
//}
char json_str[1024], buf[128];
size_t payload_size;
StaticJsonDocument<1024> json;
/**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/
void addToConfig(JsonObject &root) {
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_enabled)] = enabled;
top["pin"] = temperaturePin; // usermodparam
top["degC"] = degC; // usermodparam
top[FPSTR(_readInterval)] = readingInterval / 1000;
top[FPSTR(_parasite)] = parasite;
DEBUG_PRINTLN(F("Temperature config saved."));
}
sprintf_P(buf, PSTR("%s Temperature"), serverDescription);
json[F("name")] = buf;
strcpy(buf, mqttDeviceTopic);
strcat_P(buf, _Temperature);
json[F("state_topic")] = buf;
json[F("device_class")] = FPSTR(_temperature);
json[F("unique_id")] = escapedMac.c_str();
json[F("unit_of_measurement")] = F("°C");
payload_size = serializeJson(json, json_str);
/**
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
*
* The function should return true if configuration was successfully loaded or false if there was no configuration.
*/
bool readFromConfig(JsonObject &root) {
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
int8_t newTemperaturePin = temperaturePin;
DEBUG_PRINT(FPSTR(_name));
sprintf_P(buf, PSTR("homeassistant/sensor/%s/config"), escapedMac.c_str());
mqtt->publish(buf, 0, true, json_str, payload_size);
HApublished = true;
}
#endif
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
enabled = top[FPSTR(_enabled)] | enabled;
newTemperaturePin = top["pin"] | newTemperaturePin;
degC = top["degC"] | degC;
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
parasite = top[FPSTR(_parasite)] | parasite;
if (!initDone) {
// first run: reading from cfg.json
temperaturePin = newTemperaturePin;
DEBUG_PRINTLN(F(" config loaded."));
} else {
DEBUG_PRINTLN(F(" config (re)loaded."));
// changing paramters from settings page
if (newTemperaturePin != temperaturePin) {
DEBUG_PRINTLN(F("Re-init temperature."));
// deallocate pin and release memory
delete oneWire;
pinManager.deallocatePin(temperaturePin, PinOwner::UM_Temperature);
temperaturePin = newTemperaturePin;
// initialise
setup();
void UsermodTemperature::setup() {
int retries = 10;
sensorFound = 0;
temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C
if (enabled) {
// config says we are enabled
DEBUGUM_PRINTLN(F("Allocating temperature pin..."));
// pin retrieved from cfg.json (readFromConfig()) prior to running setup()
if (temperaturePin >= 0 && PinManager::allocatePin(temperaturePin, true, PinOwner::UM_Temperature)) {
oneWire = new OneWire(temperaturePin);
if (oneWire->reset()) {
while (!findSensor() && retries--) {
delay(25); // try to find sensor
}
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[FPSTR(_parasite)].isNull();
if (parasite && PinManager::allocatePin(parasitePin, true, PinOwner::UM_Temperature)) {
pinMode(parasitePin, OUTPUT);
digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
} else {
parasitePin = -1;
}
} else {
if (temperaturePin >= 0) {
DEBUGUM_PRINTLN(F("Temperature pin allocation failed."));
}
temperaturePin = -1; // allocation failed
}
if (sensorFound && !initDone) strip.addEffect(255, &mode_temperature, _data_fx);
}
lastMeasurement = millis() - readingInterval + 10000;
initDone = true;
}
uint16_t getId()
{
return USERMOD_ID_TEMPERATURE;
void UsermodTemperature::loop() {
if (!enabled || !sensorFound || strip.isUpdating()) return;
static uint8_t errorCount = 0;
unsigned long now = millis();
// check to see if we are due for taking a measurement
// lastMeasurement will not be updated until the conversion
// is complete the the reading is finished
if (now - lastMeasurement < readingInterval) return;
// we are due for a measurement, if we are not already waiting
// for a conversion to complete, then make a new request for temps
if (!waitingForConversion) {
requestTemperatures();
return;
}
// we were waiting for a conversion to complete, have we waited log enough?
if (now - lastTemperaturesRequest >= 750 /* 93.75ms per the datasheet but can be up to 750ms */) {
readTemperature();
if (getTemperatureC() < -100.0f) {
if (++errorCount > 10) sensorFound = 0;
lastMeasurement = now - readingInterval + 300; // force new measurement in 300ms
return;
}
};
errorCount = 0;
#ifndef WLED_DISABLE_MQTT
if (WLED_MQTT_CONNECTED) {
char subuf[128];
strcpy(subuf, mqttDeviceTopic);
if (temperature > -100.0f) {
// dont publish super low temperature as the graph will get messed up
// the DallasTemperature library returns -127C or -196.6F when problem
// reading the sensor
strcat_P(subuf, _Temperature);
mqtt->publish(subuf, 0, false, String(getTemperatureC()).c_str());
strcat_P(subuf, PSTR("_f"));
mqtt->publish(subuf, 0, false, String(getTemperatureF()).c_str());
if (idx > 0) {
StaticJsonDocument <128> msg;
msg[F("idx")] = idx;
msg[F("RSSI")] = WiFi.RSSI();
msg[F("nvalue")] = 0;
msg[F("svalue")] = String(getTemperatureC());
serializeJson(msg, subuf, 127);
mqtt->publish("domoticz/in", 0, false, subuf);
}
} else {
// publish something else to indicate status?
}
}
#endif
}
}
/**
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
//void UsermodTemperature::connected() {}
#ifndef WLED_DISABLE_MQTT
/**
* subscribe to MQTT topic if needed
*/
void UsermodTemperature::onMqttConnect(bool sessionPresent) {
//(re)subscribe to required topics
//char subuf[64];
if (mqttDeviceTopic[0] != 0) {
publishHomeAssistantAutodiscovery();
}
}
#endif
/*
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
void UsermodTemperature::addToJsonInfo(JsonObject& root) {
// dont add temperature to info if we are disabled
if (!enabled) return;
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray temp = user.createNestedArray(FPSTR(_name));
if (temperature <= -100.0f) {
temp.add(0);
temp.add(F(" Sensor Error!"));
return;
}
temp.add(getTemperature());
temp.add(getTemperatureUnit());
JsonObject sensor = root[FPSTR(_sensor)];
if (sensor.isNull()) sensor = root.createNestedObject(FPSTR(_sensor));
temp = sensor.createNestedArray(FPSTR(_temperature));
temp.add(getTemperature());
temp.add(getTemperatureUnit());
}
/**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
//void UsermodTemperature::addToJsonState(JsonObject &root)
//{
//}
/**
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
*/
//void UsermodTemperature::readFromJsonState(JsonObject &root) {
// if (!initDone) return; // prevent crash on boot applyPreset()
//}
/**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/
void UsermodTemperature::addToConfig(JsonObject &root) {
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_enabled)] = enabled;
top["pin"] = temperaturePin; // usermodparam
top[F("degC")] = degC; // usermodparam
top[FPSTR(_readInterval)] = readingInterval / 1000;
top[FPSTR(_parasite)] = parasite;
top[FPSTR(_parasitePin)] = parasitePin;
top[FPSTR(_domoticzIDX)] = idx;
DEBUGUM_PRINTLN(F("Temperature config saved."));
}
/**
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
*
* The function should return true if configuration was successfully loaded or false if there was no configuration.
*/
bool UsermodTemperature::readFromConfig(JsonObject &root) {
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
int8_t newTemperaturePin = temperaturePin;
DEBUGUM_PRINT(FPSTR(_name));
JsonObject top = root[FPSTR(_name)];
if (top.isNull()) {
DEBUGUM_PRINTLN(F(": No config found. (Using defaults.)"));
return false;
}
enabled = top[FPSTR(_enabled)] | enabled;
newTemperaturePin = top["pin"] | newTemperaturePin;
degC = top[F("degC")] | degC;
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
parasite = top[FPSTR(_parasite)] | parasite;
parasitePin = top[FPSTR(_parasitePin)] | parasitePin;
idx = top[FPSTR(_domoticzIDX)] | idx;
if (!initDone) {
// first run: reading from cfg.json
temperaturePin = newTemperaturePin;
DEBUGUM_PRINTLN(F(": config loaded."));
} else {
DEBUGUM_PRINTLN(F(": config (re)loaded."));
// changing paramters from settings page
if (newTemperaturePin != temperaturePin) {
DEBUGUM_PRINTLN(F(" Re-init temperature."));
// deallocate pin and release memory
delete oneWire;
PinManager::deallocatePin(temperaturePin, PinOwner::UM_Temperature);
temperaturePin = newTemperaturePin;
PinManager::deallocatePin(parasitePin, PinOwner::UM_Temperature);
// initialise
setup();
}
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
return !top[FPSTR(_domoticzIDX)].isNull();
}
void UsermodTemperature::appendConfigData() {
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
}
float UsermodTemperature::getTemperature() {
return degC ? getTemperatureC() : getTemperatureF();
}
const char *UsermodTemperature::getTemperatureUnit() {
return degC ? "°C" : "°F";
}
UsermodTemperature* UsermodTemperature::_instance = nullptr;
// strings to reduce flash memory usage (used more than twice)
const char UsermodTemperature::_name[] PROGMEM = "Temperature";
const char UsermodTemperature::_enabled[] PROGMEM = "enabled";
const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin";
const char UsermodTemperature::_domoticzIDX[] PROGMEM = "domoticz-idx";
const char UsermodTemperature::_sensor[] PROGMEM = "sensor";
const char UsermodTemperature::_temperature[] PROGMEM = "temperature";
const char UsermodTemperature::_Temperature[] PROGMEM = "/temperature";
const char UsermodTemperature::_data_fx[] PROGMEM = "Temperature@Min,Max;;!;01;pal=54,sx=255,ix=0";
static uint16_t mode_temperature() {
float low = roundf(mapf((float)SEGMENT.speed, 0.f, 255.f, -150.f, 150.f)); // default: 15°C, range: -15°C to 15°C
float high = roundf(mapf((float)SEGMENT.intensity, 0.f, 255.f, 300.f, 600.f)); // default: 30°C, range 30°C to 60°C
float temp = constrain(UsermodTemperature::getInstance()->getTemperatureC()*10.f, low, high); // get a little better resolution (*10)
unsigned i = map(roundf(temp), (unsigned)low, (unsigned)high, 0, 248);
SEGMENT.fill(SEGMENT.color_from_palette(i, false, false, 255));
return FRAMETIME;
}

View File

@@ -1,31 +0,0 @@
#include "wled.h"
/*
* Register your v2 usermods here!
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "usermod_v2_example.h"
#ifdef USERMOD_DALLASTEMPERATURE
#include "../usermods/Temperature/usermod_temperature.h"
#endif
//#include "usermod_v2_empty.h"
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
#ifdef USERMOD_DALLASTEMPERATURE
usermods.add(new UsermodTemperature());
#endif
//usermods.add(new UsermodRenameMe());
}

Some files were not shown because too many files have changed in this diff Show More