Compare commits

...

740 Commits

Author SHA1 Message Date
cschwinne
71886c162b Release of WLED v0.10.0
DMX Single RGW and Single DRGB modes now support an additional white channel
Improved palettes derived from set colors and changed their names
2020-05-03 20:57:53 +02:00
cschwinne
df1f516f6b Added ACST and ACST/ACDT timezones ( closes #881 ) 2020-05-03 01:48:23 +02:00
cschwinne
2e55189d59 New web UI features 2020-05-02 01:59:41 +02:00
srg74
6ade40ce85 Updated Wemos shield usermod (#880)
* Added support for H803FW controller

* Create usermod_bme280.cpp

* Create usermod_bme280.cpp

* Added BME280 sensor

* Update readme.md

* Update usermod_bme280.cpp

* Update platformio.ini

* Update for lightweight sensor
2020-04-30 23:40:14 +02:00
cschwinne
94c5f0d7a8 New API properties
-   Added realtime override option and `lor` JSON property
-   Added `lm` (live mode) and `lip` (live IP) properties to info in JSON API
-   Added reset commands to APIs
-   Added `json/si`, returning state and info, but no FX or Palette lists
-   Added rollover detection to millis(). Can track uptimes longer than 49 days
-   Attempted to fix Wifi issues with Unifi brand APs
2020-04-30 01:52:36 +02:00
Aircoookie
b1028086a3 Merge pull request #870 from pille/cleanup-segment-options
cleanup code to use descriptive segment options
2020-04-25 14:37:26 +02:00
pille
385b3570b2 cleanup code to use descriptive segment options 2020-04-24 23:35:39 +02:00
cschwinne
77edd12030 Added brightness and power for individual segments ( #289 , #290 ) 2020-04-23 23:52:33 +02:00
Aircoookie
217fca31e4 Merge pull request #865 from o0shojo0o/master
Add DIY PCB SHOJO_PCB (analog)
2020-04-23 00:31:05 +02:00
Dennis Hinzpeter
5e1d20fc72 Add DIY PCB SHOJO_PCB analog 2020-04-22 23:09:21 +02:00
cschwinne
db60309ce8 Added Candle Multi effect
Added Palette capability to Pacifica effect
2020-04-22 00:51:00 +02:00
cschwinne
6a5b757a24 TM1814 support (closes #518 ) 2020-04-19 13:25:27 +02:00
Aircoookie
a19098a004 Merge pull request #835 from martament/f-bw-lt11
Added support for BW-LT11
2020-04-16 23:44:41 +02:00
srg74
ec10c29aca Added BME280 sensor (#850)
* Added support for H803FW controller

* Create usermod_bme280.cpp

* Create usermod_bme280.cpp

* Added BME280 sensor

* Update readme.md

* Update usermod_bme280.cpp
2020-04-15 23:52:10 +02:00
cschwinne
f90ab46794 Add rotary encoder brightness usermod 2020-04-15 01:21:07 +02:00
srg74
b8ca97e019 Added support for H803FW controller (#844) 2020-04-14 00:16:06 +02:00
cschwinne
e12757dbb9 Add Art-Net support (#417) 2020-04-13 00:42:27 +02:00
Ament Martin
3e9b44d193 Added support for BW-LT11 2020-04-10 21:33:16 +02:00
Aircoookie
3006d25406 Merge pull request #809 from raresserban/dmx_settings
DMX: Ability to work together with LEDs and set segment and start LED for fixtures
2020-04-10 12:52:22 +02:00
Aircoookie
f2ae9a0711 Merge branch 'master' into dmx_settings 2020-04-10 12:36:02 +02:00
cschwinne
19945e4ccb Fix DMX compilation 2020-04-10 12:30:08 +02:00
Aircoookie
61ab16acd6 Merge pull request #830 from srg74/patch-1
Update readme.md
2020-04-09 17:04:35 +02:00
srg74
3a84292f82 Update readme.md 2020-04-09 09:06:44 -04:00
Aircoookie
1d314294c7 Merge pull request #828 from srg74/master
Update user mode directories
2020-04-08 16:25:28 +02:00
Bukovina
b5b1dbfe85 Fix platformio.ini 2020-04-08 09:30:49 -04:00
Bukovina
5be88dd188 QuinLED mod update 2020-04-08 09:18:26 -04:00
Bukovina
88b67b9541 Usermod changes 2020-04-08 08:40:44 -04:00
Bukovina
a31da3186f UserMod files update 2020-04-08 08:35:32 -04:00
Bukovina
9a7a38e913 Merge branch 'Aircoookie-master' 2020-04-08 07:28:35 -04:00
Bukovina
a0960f5468 Merge branch 'master' of https://github.com/Aircoookie/WLED into Aircoookie-master 2020-04-08 07:20:33 -04:00
Aircoookie
9b87a512cf Merge pull request #827 from Aircoookie/refactor-cpp
Project structure refactor to .cpp/.h
2020-04-07 00:14:57 +02:00
cschwinne
8da985b6d0 Fixed RBG and BGR getPixelColor (#825)
Improved formatting
2020-04-07 00:04:09 +02:00
cschwinne
5cb2a39746 Consolidated global variables in wled.h 2020-04-06 02:25:17 +02:00
cschwinne
6268cadc95 Function definitions in func_declare.h
Significantly reducing number of header files
2020-03-31 02:38:08 +02:00
Aircoookie
470b4b3972 Merge pull request #814 from TravisDean/refactor-remove-ino
Refactor to remove ino usage
2020-03-31 02:33:38 +02:00
Travis Dean
a88ae2ca56 Delete .clang-format 2020-03-30 08:48:01 -04:00
Travis J Dean
9875fbef0a Layout changes. 2020-03-30 08:34:20 -04:00
Travis J Dean
cf29ddc8d0 Typo fix. 2020-03-30 08:03:55 -04:00
Travis J Dean
ad70fcba7f Typo fix. 2020-03-30 08:00:58 -04:00
Travis J Dean
a9a7720a11 Import dmx output library into project. 2020-03-30 07:45:33 -04:00
Travis J Dean
8ff4f50f79 Fix visual studio project files and organize. 2020-03-30 07:24:45 -04:00
Travis J Dean
aea07f42d1 Fix mistaken substitute. 2020-03-30 06:56:51 -04:00
Travis J Dean
8d75c06852 Format changes. 2020-03-30 06:42:21 -04:00
Travis J Dean
ffbedbc1e6 Add clang format to git ignore. 2020-03-30 06:27:36 -04:00
Travis J Dean
a47d48c973 Add clang format. 2020-03-30 05:19:09 -04:00
Travis J Dean
c54092c932 Remove redundant defines. 2020-03-30 05:04:20 -04:00
Travis J Dean
9134c3b4af Merge branch 'master' into refactor-remove-ino 2020-03-30 04:51:56 -04:00
Travis J Dean
7e21955211 wledInit -> setup 2020-03-30 04:43:37 -04:00
Travis J Dean
40ac760285 Move getSignalQuality to json.cpp 2020-03-30 04:41:42 -04:00
Travis J Dean
de63bdac39 Code reorg. 2020-03-30 04:35:52 -04:00
Travis J Dean
408d63825a Function prototype cleanup. 2020-03-30 04:26:41 -04:00
Travis J Dean
3e1eb02f54 Comment cleanup and line reduction. 2020-03-30 04:21:47 -04:00
Travis J Dean
d2f55e1064 Make dmx.h header only. 2020-03-30 03:55:44 -04:00
srg74
c97bead631 Merge pull request #65 from Aircoookie/master
Update
2020-03-28 17:33:57 -04:00
Aircoookie
8264ca4e9e Create stale.yml (to reduce older open issues) 2020-03-28 21:30:32 +01:00
Aircoookie
05bdaa4bc7 Merge pull request #808 from feindsender/P9813
Add P9813 LED driver support
2020-03-28 21:22:08 +01:00
Travis J Dean
cc2de04f6b Avoid name collision. 2020-03-28 09:24:07 -04:00
Travis J Dean
f99f13a090 Avoid name collision. Fix wled instance access in ino. 2020-03-28 08:45:20 -04:00
Travis J Dean
f35ab125ec Rename files to remove wled_ 2020-03-28 08:30:51 -04:00
Travis J Dean
b8342f1c9c actually call the setup function. 2020-03-28 07:32:02 -04:00
Rares Serban
0ce77bbc59 Add ability to set DMX fixtures to a segment and from what LED they should start. 2020-03-28 13:13:39 +02:00
srg74
e39eccb99e Merge pull request #64 from Aircoookie/master
update
2020-03-27 18:28:50 -04:00
feindsender
77ce67d685 Add P9813 LED driver support
Adds support for the P9813 LED driver
2020-03-27 10:03:23 +01:00
cschwinne
ef125ff109 Fixed compilation for Analog LEDs
Fixed sync settings network port fields too small
2020-03-26 19:43:23 +01:00
Travis J Dean
30e3bbd0e8 Renamed min/max macros to fix potential std::min/max conflict (depending on include order). 2020-03-26 05:18:19 -04:00
Travis J Dean
7bf1c35dcf Change interface of BlynkSimpleEsp. 2020-03-26 04:56:19 -04:00
Travis J Dean
c6ea2dff8a Add further includes. 2020-03-26 04:49:35 -04:00
Travis J Dean
f2329476ec Fix linker errors. All global vars declared extern. 2020-03-26 04:12:55 -04:00
cschwinne
c4512b75d9 Fixed live preview not displaying whole light if over 255 LEDs 2020-03-26 01:44:38 +01:00
srg74
92e43abbc4 Merge pull request #63 from Aircoookie/master
Updates
2020-03-25 16:58:17 -04:00
cschwinne
07d6bfa989 Added Pacifica effect (closes #790) 2020-03-25 11:17:45 +01:00
Travis J Dean
ccf5e66f31 Compiles, but does not link. 2020-03-25 05:43:12 -04:00
Travis J Dean
6f5e71164a Further fixing of includes. 2020-03-25 05:14:23 -04:00
Travis J Dean
12131764d1 Prior to refactoring includes and forward definitions. 2020-03-25 04:36:55 -04:00
Travis J Dean
594c0b8550 Transform ino to h/cpp. Class WLED created. 2020-03-25 04:00:55 -04:00
cschwinne
ed729c32d2 Fixed Alexa whites 2020-03-25 00:59:48 +01:00
srg74
ea26ee8d40 Merge pull request #62 from Aircoookie/master
Update
2020-03-22 22:38:23 -04:00
cschwinne
53f09c0630 Moved Cronixie driver from FX library to drawOverlay handler 2020-03-22 17:45:09 +01:00
Aircoookie
2856e02eac Merge pull request #787 from stockklauser/master
Fix a code Issue for non DMX usage and Adaopt Project structure to Visual Studio
2020-03-22 16:21:36 +01:00
Thomas Stockklauser
a4f0c9195e 1. Fix an Issue withtin the DMX Compiler Flags if you dont use it in wled00.ino
2. Fix the Build / working environment for Visual Studio and make a better Folder Structure within the Visual Studio Project
2020-03-22 11:38:29 +01:00
srg74
0e73a0293b Merge pull request #61 from Aircoookie/master
Update
2020-03-20 22:29:33 -04:00
cschwinne
f4f5d6e562 Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-03-21 00:57:58 +01:00
cschwinne
e5c3629e2e Added custom per-LED mapping 2020-03-21 00:57:54 +01:00
Aircoookie
5028471598 Merge pull request #784 from TravisDean/fix-skip-first
Fix initialization bug when toggling skip first.
2020-03-19 19:18:16 +01:00
Travis J Dean
c28027496d Fix initialization bug when toggling skip first. 2020-03-19 00:37:35 -04:00
srg74
c0f5509652 Merge pull request #60 from Aircoookie/master
Add on
2020-03-16 16:27:00 -04:00
Aircoookie
9bc48ececa Merge pull request #774 from hobbyquaker/battery-keypad-controller
add battery-keypad-controller usermod
2020-03-15 22:11:51 +01:00
srg74
1f53e4d4a2 Merge pull request #59 from Aircoookie/master
Various small fixes
2020-03-15 11:06:31 -04:00
hobbyquaker
dbef0e6583 fix lint issues 2020-03-15 12:43:09 +01:00
hobbyquaker
c246e5af35 add battery-keypad-controller usermod 2020-03-15 12:38:49 +01:00
cschwinne
d36796429e Various small fixes
Fixed color of main segment returned in JSON API during transition not being target color
- Fixed arlsLock() being called after pixels set in E1.31, (closes #772)
- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment)
2020-03-14 11:28:42 +01:00
srg74
37a31a9b94 Update platformio.ini 2020-03-13 20:44:05 -04:00
srg74
c2ab3f96a7 gitignore update 2020-03-13 20:42:15 -04:00
srg74
ef36b5377d Merge pull request #58 from Aircoookie/master
Update
2020-03-13 18:44:41 -04:00
Aircoookie
f12237d298 Merge pull request #769 from mike2nl/patch-1
CHANGELOG.md - Make it more readable
2020-03-13 09:51:38 +01:00
Mike
5b312d4c8b Make it better readable
Make it better readable and make use of single line for add/chgange and/or delete
2020-03-13 08:04:55 +01:00
Aircoookie
d21e82b020 Create changelog 2020-03-12 23:26:38 +01:00
srg74
c6e5606b4c Merge pull request #57 from Aircoookie/master
Update
2020-03-10 19:20:40 -04:00
Aircoookie
7b4dc43147 Merge pull request #766 from pille/E1.31-sequencenumber-per-universe
fixes #742
2020-03-10 23:02:38 +01:00
pille
62510ac6a3 add E1.31 packet out-of-sequence config option, wrt #742 2020-03-10 18:28:51 +01:00
pille
bffe2d7bd0 track E1.31 seqcuence numbers for each universe individually, wrt #742 2020-03-10 17:33:23 +01:00
srg74
cbaf1e576d Merge pull request #56 from Aircoookie/master
Usermod: Project Cars rpm indicator and shift lights (#759)
2020-03-06 21:25:30 -05:00
jwingefeld
0d355dbf35 Usermod: Project Cars rpm indicator and shift lights (#759)
* project cars shiftlight usermod

* added readme

* rephrased stuff in readme.md because reasons

Co-authored-by: Jan <jan.wingefeld@gmail.com>
2020-03-06 23:45:45 +01:00
srg74
d851bff762 Merge pull request #54 from Aircoookie/master
Trying to fix failed build (#756)
2020-03-05 17:14:15 -05:00
Aircoookie
453f4b549b Trying to fix failed build (#756) 2020-03-05 09:39:43 +01:00
srg74
8d669b12b6 Truing to fix failed build 2020-03-04 23:15:12 -05:00
srg74
ed3234d949 Update UserMod
Updating UserMod as per request from discourse forum user. He want to use with ESP32 also as QuinLED board support to types - ESP8266 ans ESP32.
Removed .txt file as it create an extra step in setup.
2020-03-04 23:01:00 -05:00
srg74
603a00376f Merge pull request #53 from Aircoookie/master
Add custom32_LEDPIN_16 environment (from #748 )
2020-03-04 20:31:56 -05:00
cschwinne
4f34cfb654 Add custom32_LEDPIN_16 environment (from #748 ) 2020-03-04 11:45:25 +01:00
srg74
fd1e536cdb Merge pull request #52 from Aircoookie/master
Update
2020-03-03 17:47:19 -05:00
cschwinne
0c6a880a74 Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-03-03 17:53:51 +01:00
cschwinne
89fa053310 Add "np" API option to not commit
Re-add IRremote flags to platformio.ini
2020-03-03 17:53:47 +01:00
Def3nder
267887908e New IRremote functions (#746)
* Switch to strip.getPaletteCount()

* fixed color conversion errors

Co-authored-by: Aircoookie <cschwinne@gmail.com>
2020-03-02 13:31:34 +01:00
Def3nder
b86f58befe IR remotes can disable NightLight with "OFF" (#745)
* IR can disable Nightlight with "OFF"
2020-03-02 12:41:14 +01:00
Def3nder
b804101c24 lift NeoPixelBus library to 2.5.7 (#747) 2020-03-02 12:24:10 +01:00
Def3nder
f28502514f Remember lastColor and last Bri for Solid RGBW (#743) 2020-03-01 12:25:44 +01:00
cschwinne
79da716a44 Split esp01_1m env into 1m_full and 1m_ota (closes #740 ) 2020-02-29 19:52:47 +01:00
srg74
f76a440b74 Merge pull request #51 from Aircoookie/master
Update
2020-02-29 13:39:36 -05:00
cschwinne
18dad0c72c Remove defunct presetApplyCol and presetApplyFx 2020-02-29 18:42:55 +01:00
cschwinne
14a5ab6740 Fixed Chase modes 2020-02-29 18:24:51 +01:00
Def3nder
d0d56c4416 Travis.CI builds only for default_envs (#739) 2020-02-29 16:30:15 +01:00
srg74
9dd9a01211 Merge pull request #50 from Aircoookie/master
Update
2020-02-28 16:42:15 -05:00
Def3nder
480e7f5b54 Add all release environments to platformio.ini (#736) 2020-02-28 18:53:38 +01:00
Def3nder
cffee7bfa7 Fix 24-key IR remote (#738) 2020-02-28 16:27:18 +01:00
srg74
5b9eda9c63 Merge pull request #49 from Aircoookie/master
Update
2020-02-27 14:34:55 -05:00
Aircoookie
0a363d5fc0 Merge pull request #732 from Jason2866/patch-1
Reduce CPU load during interrupt handler
2020-02-27 18:56:54 +01:00
Jason2866
9eb646085e Reduce CPU load during interrupt handler
See https://github.com/esp8266/Arduino/pull/7057#issuecomment-591632232
2020-02-27 09:52:48 +01:00
Ser Ko
e3269f6edc Update wled06_usermod.ino 2020-02-26 20:36:27 -05:00
Ser Ko
57d3120b45 Grammar correction 2020-02-26 19:21:57 -05:00
Ser Ko
81da8261a0 Added board heltec_wifi_kit_8 2020-02-26 19:16:33 -05:00
srg74
7e5949b4a9 Merge pull request #46 from Aircoookie/master
Refactor platformio.ini (#721)
2020-02-26 19:01:27 -05:00
Def3nder
a776b8ac31 Refactor platformio.ini (#721)
* Override script updated accordingly

* ldscriipt for 1m0 adjusted

* backup files deleted

* deletion of wled00,ino.cpp

* remove travis build from PIO
2020-02-26 11:17:56 +01:00
srg74
14e19226ea Merge pull request #43 from Aircoookie/master
Update
2020-02-25 16:30:04 -05:00
Aircoookie
5473b3e42e Merge pull request #719 from zewelor/use_new_platformio_ldscript_syntax
Use new platformio ldscript syntax
2020-02-25 09:00:09 +01:00
zewelor
143179cac9 Use new platformio ldscript syntax 2020-02-25 08:42:28 +01:00
srg74
ad2c7ee363 Merge pull request #40 from Aircoookie/master
Update
2020-02-24 21:21:20 -05:00
cschwinne
755448f9f5 Fix LED pin changed 2020-02-25 02:25:17 +01:00
cschwinne
f304a6891f Free more than 2kB of RAM
Store Palettes in PROGMEM
F() select long and rarely used strings
Refactor hue error
2020-02-25 02:19:12 +01:00
srg74
1221661ae3 Added Heltec WiFi-Kit-8 to UserMod (#717) 2020-02-24 22:51:11 +01:00
srg74
a78f17abec Update readme.md 2020-02-24 16:48:01 -05:00
srg74
70bf957a8a Added Heltec WiFi-Kit-8 2020-02-24 16:44:56 -05:00
Ser Ko
e8e04db7b4 Merge branch 'master' of https://github.com/srg74/WLED 2020-02-24 16:39:37 -05:00
Ser Ko
d5def30c59 Update wled06_usermod.ino 2020-02-24 16:36:03 -05:00
srg74
81176bc4e6 Merge pull request #39 from Aircoookie/master
Indents for the #ifdef's in wled00.ino (#716)
2020-02-24 16:32:34 -05:00
Def3nder
730ba12c8d Indents for the #ifdef's in wled00.ino (#716) 2020-02-24 22:09:33 +01:00
srg74
80ad456d48 Merge pull request #38 from Aircoookie/master
Update
2020-02-24 15:23:35 -05:00
cschwinne
2d75526395 Fix brightness transition updating too often 2020-02-24 19:36:25 +01:00
Aircoookie
cd618a43d4 Merge pull request #714 from zewelor/allow_platformio_ini_overrides
Allow platformio ini overrides
2020-02-24 19:11:46 +01:00
Aircoookie
1979236f3a Merge pull request #715 from zewelor/allow_to_override_some_const
Allow to override some costs
2020-02-24 19:10:37 +01:00
cschwinne
3589adcb78 Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-24 19:08:35 +01:00
cschwinne
4a834ecfc8 Fix UTC offset not working 2020-02-24 19:08:29 +01:00
zewelor
3dcc3492e8 Allow to override some costs 2020-02-24 18:48:21 +01:00
Def3nder
2e77dcc660 Correct sun rise (#713) 2020-02-24 17:27:59 +01:00
cschwinne
89f60a0422 Refactor colorUpdated() 2020-02-24 17:25:40 +01:00
zewelor
0455c09e4c Allow platformio ini overrides 2020-02-24 16:42:24 +01:00
cschwinne
7360b882ac DMX settings only when enabled 2020-02-24 12:54:23 +01:00
cschwinne
5ffd29e31a Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-24 12:45:47 +01:00
cschwinne
5d7e892464 Different PIO settings 2020-02-24 12:44:41 +01:00
Def3nder
e8fd5de5b2 HTML API "/url" for the current effect settings (#664) 2020-02-24 12:18:30 +01:00
srg74
a8e7aa99e8 Update wled06_usermod.ino 2020-02-23 22:48:58 -05:00
srg74
9a0db83f83 Added Heltec WiFi-Kit-8 with 0.91" display 2020-02-23 21:03:36 -05:00
srg74
4e85566b88 Merge pull request #37 from Aircoookie/master
Update
2020-02-23 20:53:18 -05:00
jwingefeld
8be72f6f23 DMX Support for WLED (#704)
* initial dmx setup

* adds support for multiple fixtures, addr gaps, start addresses and all that good DMX stuff

* removes init function. do not need.

* adds some comments, removes others. words.

* added menu entry and dummy HTML

* added server request handler

* cloned options page UI for DMX

* only add code when DMX is enabled

* added infobutton to HTML

* DMX settings form

* procedurally generated HTML form. OBACHT: Values still not coming from the EEPROM.

* upped eeprom version to 15

* changed index for set to 255 to 6 because web interface wants it that way

* gets values for XML from actual settings

* changes the default values for dmx to blanks

* reads and writes DMX settings from EEPROM (2550 - 2569)

* fixes addressing bug in DMX EEPROM read

* saves settings from WebUI to memory

* disables DMX by default

* changed a comment in the ENABLE_DMX line

* makes the display of the DMX entry in settings dependant on WLED_DMX_ENABLE

* adds the server listener for the DMX map

* fixes a bug when selecting 255 for a channel at the dmx settings page

* now actually reads the DMX settings back to the HTML UI.

* cleans up a little

* adds a warning message to the HTML UI when setting up defunct DMX settings

* changed DMX EEPROM addressing to close a gap

* basic DMX map

* fixes a few styling flaws and bugs in the DMX map

* changes config variables to uint16_t

Co-authored-by: Aircoookie <cschwinne@gmail.com>
2020-02-23 22:24:51 +01:00
Def3nder
513bc2c0ab Correct SunRise/NightLight with Color Fade (#710) 2020-02-23 22:21:32 +01:00
srg74
036ba77a68 Merge pull request #35 from Aircoookie/master
Release of WLED v0.9.1
2020-02-22 22:06:30 -05:00
cschwinne
392277100c Release of WLED v0.9.1 2020-02-23 02:18:25 +01:00
srg74
a7092ac503 Merge pull request #33 from Aircoookie/master
Update from orig
2020-02-22 17:38:00 -05:00
Aircoookie
027a16a39b Merge pull request #705 from pille/E1.31-fix-OOS
fix out-of-sync detection on E1.31 packets
2020-02-22 19:13:34 +01:00
pille
c66af86d88 fix out-of-sync detection on E1.31 packets 2020-02-22 18:13:21 +01:00
Def3nder
e621fdec0c Remove analog flicker (#678)
* remove analog LED flicker

run SetRgbwPwm from main loop and with GetPixelColor(0) to get all effects using fade_out() working.

* correct unintended bitwise AND to logical AND

* Update analogLastShow

* new Arduino Core WaveForm library included

* new Arduino Core only for 8266

* correct formating + define for MQTT_KEEP_ALIVE

* fix for ESP32

* reduce scope of variable "done"

* call analogWrite only if Color or Bri did change

* Remove duplicate wifi sleep code

Co-authored-by: Aircoookie <cschwinne@gmail.com>
2020-02-22 17:20:34 +01:00
Debashish Sahu
447594b5ea PIO cleanup and ESP8266/32 core bump (#699)
* Try to fix TravisCI

* Bump ESP8266/ESP32 core version

Co-authored-by: Aircoookie <cschwinne@gmail.com>
2020-02-22 16:19:05 +01:00
srg74
a0b208cca0 Added new user mod for Wemos shield (#701) 2020-02-22 16:18:18 +01:00
Def3nder
1a4061fdb5 Refactor callMode (#702) 2020-02-22 16:17:32 +01:00
srg74
fb59f1f0a0 Update wled06_usermod.ino 2020-02-21 16:55:58 -05:00
srg74
b1961033b3 Update readme.md 2020-02-20 22:48:20 -05:00
srg74
863498f762 Update readme.md 2020-02-20 22:43:59 -05:00
srg74
bdc44a4070 Update readme.md 2020-02-20 20:53:17 -05:00
srg74
6451522f89 Update readme.md 2020-02-20 20:50:38 -05:00
srg74
5ca1e9268c Update readme.md 2020-02-20 20:49:33 -05:00
srg74
451a6841c9 Update readme.md 2020-02-20 20:48:25 -05:00
Ser Ko
3e3f46a683 Added new mod 2020-02-20 20:46:00 -05:00
srg74
2b0eaafea6 Merge pull request #29 from Aircoookie/master
Update
2020-02-20 14:40:58 -05:00
cschwinne
c1a8fde9a0 Add wifi sleep toggle (implements #672 ) 2020-02-20 17:08:56 +01:00
srg74
9dbd1b2a1b Updated wled06_usermod.ino (#698) 2020-02-20 11:43:17 +01:00
srg74
0cc1007543 Merge pull request #28 from Aircoookie/master
Update
2020-02-19 19:29:53 -05:00
Ser Ko
8ca86181e4 Updated wled06_usermod.ino
User mode file updated for flip display in case of using on WLED Wemos shield
2020-02-19 19:27:09 -05:00
cschwinne
8759d8f868 Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-20 00:45:14 +01:00
cschwinne
65a32b4166 Added new auto white modes (related to #573 ) 2020-02-20 00:45:09 +01:00
Aircoookie
933a0cddf8 Merge pull request #697 from huggy-d1/patch-2
Update readme.md
2020-02-19 20:54:16 +01:00
huggy-d1
d4c0542c84 Update readme.md
Minor spelling change
2020-02-19 13:24:56 -05:00
cschwinne
05f5aaaeca Refactoring 2020-02-19 15:53:42 +01:00
srg74
036bd07e72 Merge pull request #27 from Aircoookie/master
Update
2020-02-18 19:46:45 -05:00
fishbone-git
9c3e7b9ec0 allow intensity slider to adjust eye spacing (#681) 2020-02-18 20:52:12 +01:00
cschwinne
1fd0383f69 Various improvements
UI Quick color selectors
UI PC mode
Different Heartbeat effect
PoliceAll improvements
Clarified sync settings
2020-02-18 18:52:47 +01:00
Aircoookie
9e62db5237 Update html with PC mode 2020-02-18 14:22:20 +01:00
Aircoookie
3062786bb3 Corrected effect mode count 2020-02-17 18:02:14 +01:00
Aircoookie
b42847c135 Fix compilation 2020-02-17 11:12:39 +01:00
Def3nder
5befcd24b5 Effect "Heartbeat" (#680) 2020-02-17 11:01:05 +01:00
Aircoookie
61f3002568 Merge pull request #683 from fishbone-git/ripple_rainbow
water ripple effect with a dimmed rainbow background
2020-02-17 10:32:30 +01:00
fishbone-git
0b7e0e166c pio workaround for pio4.2.0 (#688) 2020-02-17 10:18:36 +01:00
cschwinne
3b52770a1b Fix segments when reverse 2020-02-16 17:34:28 +01:00
fishbone-git
d0b9f53d8c water ripple effect with a dimmed rainbow background 2020-02-15 20:07:15 +01:00
Aircoookie
92a9d7d26a Attempt to fix travis 2020-02-15 16:42:05 +01:00
Aircoookie
ffd958a1b3 Quick color selectors 2020-02-15 16:18:06 +01:00
Aircoookie
a7e9c7e24b Merge pull request #682 from fishbone-git/multicomet
port multi-comet to use the memory allocation method
2020-02-15 16:02:56 +01:00
fishbone-git
9839cc6386 port multi-comet to use the memory allocation method 2020-02-15 14:42:09 +01:00
srg74
8d66d38fd2 Merge pull request #26 from Aircoookie/master
Simplify Code for Gradient / Loading effect (#671)
2020-02-11 21:43:22 -05:00
Def3nder
a004d1647d Simplify Code for Gradient / Loading effect (#671) 2020-02-11 22:43:15 +01:00
srg74
21fe2c5f8f Merge pull request #24 from Aircoookie/master
Update
2020-02-09 17:36:06 -05:00
cschwinne
867e43637c Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-09 23:22:27 +01:00
srg74
c9025917b2 Merge pull request #23 from Aircoookie/master
Update
2020-02-09 14:24:45 -05:00
Aircoookie
258def854c Merge pull request #665 from pille/DMX-refactoring
DMX refactoring
2020-02-09 19:49:15 +01:00
cschwinne
e8481818c8 Small adjustments to new DMX options 2020-02-09 19:10:29 +01:00
cschwinne
f646e9bc59 Swap order of API parsing to make it possible to override preset brightness 2020-02-09 16:11:38 +01:00
srg74
680923bdd5 Merge pull request #22 from Aircoookie/master
Update
2020-02-09 08:57:15 -05:00
cschwinne
17e43a7ff2 No phy mode for ESP32 2020-02-09 11:04:30 +01:00
Def3nder
71a5cfed4b Intensity slider for "Police" and "Two Dots" (#670)
Enable intensity slider for the Effects based on "police_base"

the intensity slider controls the width of the "dot" from 1 pixel (as now) to 64 pixels.
2020-02-09 10:36:37 +01:00
cschwinne
c055477d3b Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-09 10:35:37 +01:00
cschwinne
ad4acca17a Minor adjustments 2020-02-09 10:35:32 +01:00
Def3nder
37b84300b4 Fix Chase Random effect (#669) 2020-02-09 10:33:26 +01:00
pille
d9a8dac266 expose refactoring to webUI:
add client stats
  add DMX settings (this increases EEPROM layout version)
2020-02-08 20:52:45 +01:00
pille
76f704b060 implement different DMX modes for E1.31:
DISABLED: don't act on packets
  SINGLE_RGB: treat all LEDs the same and controll them using 3 channels: RGB
  SINGLE_DRGB: as above, but has an additional first channel for Dimmer
  EFFECT: not a realtime mode. disables fadeTransition to reduce delay. just exposes parameters as 11 channels to trigger effects locally: Dimmer Effect Speed Intensity Palette PriRed PriGreen PriBlue SecRed SecGreen SecBlue
  MULTIPLE_RGB: legacy mode. address each LED individually with 3 channels: RGB.
  MULTIPLE_DRGB as above, but has an additional first channel for master Dimmer

add client stats (IP + user agent)
add support for DMX address (so you don't need a whole universe per fixture)
skip out-of-order packets
2020-02-08 20:38:28 +01:00
srg74
cde360f7ec Merge pull request #21 from Aircoookie/master
Update
2020-02-05 20:13:49 -05:00
Def3nder
d69a2f1514 Fix Chase Effects at high speeds + "Two Dots" Effect at low speeds (#659) 2020-02-06 01:37:47 +01:00
Def3nder
06a5c1a798 Percent Effect from both ends of the strip (#660)
from 0 to 100 the strip will get color(0) starting at the ESP, from 200 to 100 to strip will do it the other way around.

So, when using this effect for the staircase usermod, a person entering area near the ESP would set an intensity starting with 1 and getting bigger and leaving on the other side would need to further increase the intensity until 200. then the strip has color(1) again.
2020-02-06 01:36:01 +01:00
srg74
ca1f25ecf6 Pin order correction (#662) 2020-02-06 01:33:55 +01:00
Ser Ko
adcd7fb170 Added tested display sizes 2020-02-05 12:25:26 -05:00
Ser Ko
f105436b41 Corrected comment
Since 2 common size of OLED display can be used (0.91" and 0.96") removed comment about display size
2020-02-05 12:23:06 -05:00
Ser Ko
47738c751c Update wled06_usermod.ino
Controller design changed. New version with relay. Dallas sensor pin changed to GPIO 13.
2020-02-05 12:03:24 -05:00
srg74
0b3f2da6ef Merge pull request #20 from Aircoookie/master
Update
2020-02-04 15:59:06 -05:00
Aircoookie
fa7092cc17 Fix discourse badge 2020-02-04 17:46:43 +01:00
Aircoookie
773d6e002c Add discourse to readme 2020-02-04 17:43:46 +01:00
Aircoookie
b78d1baaaf Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-02-01 00:36:07 +01:00
Aircoookie
50ff59239c Segment grouping HTML support 2020-02-01 00:36:00 +01:00
srg74
8f36878dde Merge pull request #19 from Aircoookie/master
Update
2020-01-30 15:32:47 -05:00
Def3nder
a29e98fd41 Correct start of Lighthouse effect at high speeds (#643) 2020-01-29 23:20:32 +01:00
Def3nder
e4d5551f16 Correction for "Percent with speed" (#642)
The speed slider defines the "size" of pixels that will be added or substracted each refresh. If this size is bigger than the last value and you quickly move the intensity slider to zero, then the effect shows 100% all the time until it will be changed.
2020-01-29 23:10:02 +01:00
srg74
e610a1ffe4 Merge pull request #18 from Aircoookie/master
Update
2020-01-28 22:43:03 -05:00
Aircoookie
ac927d188b Merge pull request #640 from fishbone-git/settings
non-required HUE settings
2020-01-29 02:21:56 +01:00
fishbone-git
bbf2f6c7de non-required HUE settings 2020-01-28 20:47:37 +01:00
Aircoookie
398816dbeb Merge pull request #625 from stringandstickytape/IR6_Support_2
Add IR codes for 6-key learning remote https://www.aliexpress.com/ite…
2020-01-28 13:49:41 +01:00
Def3nder
f3b399b31f Fix Police All, Sinelon and Lighthouse (Comet) effects (#634) 2020-01-28 13:48:59 +01:00
Def3nder
2b0a38d25d Percent Effect with speed-slider (#637) 2020-01-28 13:47:18 +01:00
cschwinne
b41dacb6c0 FIx ESP32 compilation 2020-01-28 00:45:29 +01:00
cschwinne
c5f5532303 Bump version ID 2020-01-28 00:03:29 +01:00
cschwinne
09485c995e Merge branch 'master' of https://github.com/Aircoookie/WLED 2020-01-27 00:45:33 +01:00
cschwinne
dc936b63d6 Various fixes 2020-01-27 00:45:30 +01:00
srg74
b5213794a8 Merge pull request #17 from Aircoookie/master
update
2020-01-26 08:51:46 -05:00
Max Hedge
2f8365a790 Fix consecutive break statement. 2020-01-25 16:53:37 +00:00
Max Hedge
47be430bc1 Add IR codes for 6-key learning remote https://www.aliexpress.com/item/4000307837886.html
This cheap remote has the advantage of being more powerful (longer range) than cheap credit-card remotes

"CH" controls brightness, "VOL +" controls effect, "VOL -" controls colour/palette, "MUTE" sets bright plain white.
2020-01-25 16:46:10 +00:00
Aircoookie
918da24c8d Merge pull request #624 from axlan/user-relay
Added usermod for controlling a relay
2020-01-25 10:41:28 +01:00
Jonathan Diamond
0e82f2a02f Added usermod for controlling a relay 2020-01-24 15:39:04 -08:00
srg74
447f15cfa4 Merge pull request #16 from Aircoookie/master
Update from original
2020-01-24 17:24:22 -05:00
srg74
8f80c206e7 Platformio upcoming change (#623) 2020-01-24 23:18:27 +01:00
Def3nder
e1a61985a2 Plasma effect correction (#619) 2020-01-24 23:17:29 +01:00
Def3nder
16ad0c22f0 IRremote correction (preset load) (#618) 2020-01-24 23:15:57 +01:00
srg74
3d0d027216 Update platformio.ini 2020-01-24 16:52:41 -05:00
srg74
b58a17a99e Display size is irrelevant 2020-01-20 15:28:39 -05:00
srg74
adaf2e15cd Merge pull request #15 from Aircoookie/master
Update to usermod Enclosure_with_OLED_temp_ESP07 (#607)
2020-01-20 14:52:21 -05:00
srg74
1723683370 Update to usermod Enclosure_with_OLED_temp_ESP07 (#607) 2020-01-20 18:26:52 +01:00
srg74
9cd0a7982a Merge pull request #14 from Aircoookie/master
Re-add NEC decoder (closes #608)
2020-01-20 11:59:56 -05:00
cschwinne
d2726aae90 Re-add NEC decoder (closes #608) 2020-01-20 11:44:19 +01:00
srg74
607a66b983 Update readme.md 2020-01-19 18:54:48 -05:00
srg74
38b2adcaad Fixed wled06_usermod.ino
And added link to readme.md
2020-01-19 18:53:11 -05:00
srg74
d7879d8853 Merge pull request #13 from Aircoookie/master
Update
2020-01-19 11:59:13 -05:00
Aircoookie
2d5b09a16f Merge pull request #604 from recliq/fx_percent
Added percent display effect.
2020-01-19 16:01:48 +01:00
Aircoookie
a06a722c23 Merge pull request #603 from recliq/ir21_key
added support for 21-key remote
2020-01-19 15:53:31 +01:00
cschwinne
d9d45f86cb Fix PIO 2020-01-19 15:20:40 +01:00
recliq
e49b9cff67 Added percent display effect. 2020-01-19 13:51:49 +01:00
recliq
8c69a4cb7a added support for 21-key remote 2020-01-19 12:53:44 +01:00
srg74
1042ac141a Delete main.yml 2020-01-18 20:27:35 -05:00
srg74
81aab35231 Create main.yml 2020-01-18 20:22:44 -05:00
srg74
1c5742c7d4 Delete ccpp.yml 2020-01-18 20:04:15 -05:00
srg74
4d646e67f3 Create ccpp.yml 2020-01-18 20:03:18 -05:00
srg74
59fbc51283 Merge pull request #12 from Aircoookie/master
Update
2020-01-18 19:42:28 -05:00
cschwinne
125e21900a Added new HTTP API commands (resolves #597) 2020-01-19 01:07:38 +01:00
cschwinne
569efd3e45 Staircase reverse wipe 2020-01-19 00:50:26 +01:00
Def3nder
6c557ec015 Plasma effect (#600) 2020-01-19 00:06:17 +01:00
srg74
63b917eb07 Added usermod for esp-07s based controller (#602) 2020-01-18 23:59:27 +01:00
srg74
71af63dfc7 Update readme.md 2020-01-18 17:45:11 -05:00
srg74
0cae048ada Update readme.md 2020-01-18 17:40:52 -05:00
Ser Ko
71021da261 Update readme.md 2020-01-18 17:36:04 -05:00
Ser Ko
1d897e491a Update readme.md 2020-01-18 17:31:36 -05:00
Ser Ko
57c0b408e5 Update readme.md 2020-01-18 17:26:06 -05:00
Ser Ko
43e0186efe Update readme.md 2020-01-18 16:46:48 -05:00
srg74
8831d74cbc Update readme.md 2020-01-18 16:29:28 -05:00
srg74
9a9d2cb964 Update readme.md 2020-01-18 16:17:45 -05:00
srg74
2fc2a0cbdb Update readme.md 2020-01-18 16:16:51 -05:00
srg74
40c041c9e7 Update readme.md 2020-01-18 16:15:37 -05:00
srg74
b00c1dd055 Update readme.md 2020-01-18 16:14:32 -05:00
srg74
761245049f Update readme.md 2020-01-18 16:10:03 -05:00
srg74
30e142edd3 Update readme.md 2020-01-18 16:09:39 -05:00
srg74
b7d84c002d Add files via upload 2020-01-18 16:08:49 -05:00
srg74
551afe0cd7 Add files via upload 2020-01-18 16:08:14 -05:00
srg74
5d8bfc2930 Create readme.md 2020-01-18 16:07:27 -05:00
srg74
5d947cc8e1 Create readme.md 2020-01-18 16:06:26 -05:00
srg74
7bf92db4c9 Delete Enclosure_with_OLED_temp_ESP07 2020-01-18 16:05:49 -05:00
srg74
593c1d6b05 Create Enclosure_with_OLED_temp_ESP07 2020-01-18 16:01:31 -05:00
srg74
30e326b8b8 Merge pull request #11 from Aircoookie/master
Update
2020-01-15 16:20:06 -05:00
cschwinne
cf60eb52d8 Fix LED settings always displaying WS2815 2020-01-15 00:38:25 +01:00
Aircoookie
8850dac291 Merge pull request #587 from stringandstickytape/master
Add WS2815 brightness limiter power model, using "magic value" of 255mA.
2020-01-14 23:55:07 +01:00
srg74
bed52d0a4a Merge pull request #9 from Aircoookie/master
Sync with orig
2020-01-14 16:23:08 -05:00
cschwinne
10e564eeea Remove start from Drip 2020-01-14 19:12:23 +01:00
Aircoookie
ae47c4c79a Merge pull request #438 from spitsw/groupfinal
Grouping and Spacing
2020-01-14 16:21:21 +01:00
cschwinne
e99e9fed11 Remove unneccessary null checks 2020-01-14 11:46:21 +01:00
Aircoookie
79e9dbb9c6 Merge branch 'master' into groupfinal 2020-01-14 11:12:33 +01:00
cschwinne
081a6888fa Remove G and S options (only segment properties now) 2020-01-14 10:59:57 +01:00
cschwinne
ae6ba79f1e Grouping and Spacing 2020-01-14 10:57:23 +01:00
srg74
d9d2ad4382 Merge pull request #7 from Aircoookie/master
Sync to parent
2020-01-13 15:31:01 -05:00
Max Hedge
31d277ffa2 Don't display "for most effects..." information for WS2815. 2020-01-13 17:30:10 +00:00
Def3nder
7fe5f8907e FX intensity slider to desaturate Color in Colorloop FX (#585) 2020-01-13 18:29:34 +01:00
cschwinne
2e9b59e2e0 Update readme 2020-01-13 18:24:23 +01:00
cschwinne
5188894301 Fix LPD8806 2020-01-13 18:23:06 +01:00
Max Hedge
4c16efbbf7 Ignore white component on WS2815 power calculation 2020-01-13 17:18:21 +00:00
Max Hedge
8055243909 Remove unintended platformio.ini change. 2020-01-13 17:16:39 +00:00
Max Hedge
2eb4383e03 Fix bug in WS2815 power calculation. 2020-01-13 17:14:40 +00:00
Max Hedge
bafd043aae Add WS2815 brightness limiter. Uses "magic value" of 255mA. 2020-01-13 17:09:20 +00:00
srg74
3379e7cc48 Merge pull request #6 from Aircoookie/master
Update to recent
2020-01-12 10:08:50 -05:00
cschwinne
d971fc440f Support WS2801 and LPD8806 (closes #178) 2020-01-12 15:16:45 +01:00
fishbone-git
31658f4eab Drip (water_torture) effect (#583) 2020-01-12 15:04:49 +01:00
srg74
339be2b7a4 Merge pull request #5 from Aircoookie/master
Add staircase wipe usermod
2020-01-10 20:08:23 -05:00
cschwinne
3e716e429f Add staircase wipe usermod 2020-01-11 00:26:43 +01:00
srg74
a8a61665f4 Merge pull request #4 from Aircoookie/master
Include new branch of IRremoteESP8266 to save 21k (#582)
2020-01-10 17:48:45 -05:00
Def3nder
a7a1002509 Include new branch of IRremoteESP8266 to save 21k (#582)
This saves 21024 bytes of program space
2020-01-10 21:12:23 +01:00
srg74
65154e48cb Merge pull request #3 from Aircoookie/master
Update to recent
2020-01-08 17:06:52 -05:00
Aircoookie
32c10e5ae8 Merge pull request #571 from Def3nder/SunRiseFading
SunRise using NightLight Fade
2020-01-08 19:25:05 +01:00
Aircoookie
61ee1c6ff3 Merge pull request #574 from Def3nder/ESP32IRsupport
ESP32 support for IR remotes
2020-01-08 19:13:28 +01:00
Def3nder
6642d96688 ESP32 support for IR remotes
uses library v2.7.2
2020-01-08 18:07:48 +01:00
Def3nder
df8b085f0e SunRise using NightLight Fade
changed WLED08_led.ino to fade from current color to the secondary color. This can be used without effecting the current logic with setting "NF=2" in a macro or through the API.

If a red color tone is chosen as primary and a yellow/white tone as secondary color, 
the actual brightness is set to 5 and the target brightness to 255,
the duration is set to 10 minutes,
this will create a smooth fade from darkest red to a bright warm light (like in a real SunRise)
2020-01-08 12:00:25 +01:00
Aircoookie
7a415ccdfc Merge pull request #569 from Def3nder/IRremotes
More IR remotes (24/40/44-keys) and select them in the settings
2020-01-08 11:01:12 +01:00
Def3nder
2a432dc6ee Corrected OR function in IF statement
from '|'  to  '||'
2020-01-08 10:35:42 +01:00
Unknown
322d1f09de More IR remotes (24/40/44-keys) and select them in the settings
added more IR remotes
2020-01-08 00:46:16 +01:00
Aircoookie
44f4bd6e62 Merge pull request #568 from Def3nder/ESP32solidRGB
ESP32 support for solid (analog) RGB(W) stripes
2020-01-08 00:20:41 +01:00
Unknown
2bb74233cc ESP32 support for solid (analog) RGB(W) stripes uses ledc funtion to drive analog RGB(W) stripes with 3, 4 or 5 channels.
uses ledc funtion to drive analog RGB(W) stripes with 3, 4 or 5 channels.

the define in platformio.ini needs to be "WLED_USE_ANALOG_LEDS"
2020-01-07 23:58:15 +01:00
srg74
19f6fd2295 Merge pull request #2 from Aircoookie/master
Update repository
2020-01-06 21:01:36 -05:00
cschwinne
558811e4f9 Update to Espalexa v2.4.4 2020-01-07 01:02:52 +01:00
Aircoookie
ed560a338e Merge pull request #560 from srg74/master
OLED contrast set to 10
2020-01-06 19:39:39 +01:00
srg74
74741682bf OLED contrast set to 10
Another OLED lifetime saving feature. With set to 10 is bright enough to see all labels, even more readable on cheap OLEDs.
2020-01-06 12:41:03 -05:00
Aircoookie
d32d4e21e9 Merge pull request #550 from srg74/master
ESP-07 module support
2020-01-06 01:30:05 +01:00
cschwinne
78f301d503 Removed verbose option from travis 2020-01-06 01:21:16 +01:00
cschwinne
318ffc821c Re-add accidentally reverted Frametime fixes 2020-01-06 01:06:02 +01:00
cschwinne
ef4ec16860 Add RSSI to info (#434) 2020-01-06 00:43:15 +01:00
Aircoookie
6bc927c535 Merge branch 'master' into groupfinal 2020-01-05 22:30:27 +01:00
Aircoookie
2fe2b3c975 Merge pull request #443 from fishbone-git/master
add bouncing balls effect
2020-01-05 21:38:24 +01:00
cschwinne
e4ad0d3b59 Improved bouncing balls 2020-01-05 21:26:14 +01:00
srg74
750261d205 Turn off display after 5 min.
Better shut off display after few minutes to preserve display life time.
2020-01-05 14:47:31 -05:00
srg74
df1b25f381 Added ESP8266 ESP-07 module with external antenna
Added 2 library dependency for temperature sensor
2020-01-03 23:46:00 -05:00
Aircoookie
4af7ccd84c Merge branch 'master' into master 2020-01-03 23:19:40 +01:00
Aircoookie
4282053f68 Merge pull request #524 from fishbone-git/1d-fireworks
1d fireworks
2020-01-03 23:09:24 +01:00
cschwinne
5c7d993dbe Numerous improvements to 1D FW 2020-01-03 22:56:56 +01:00
cschwinne
cdef7a53a4 Fireworks 1D working 2020-01-03 17:47:06 +01:00
Aircoookie
b1f26d4ebe Merge branch 'master' into 1d-fireworks 2020-01-03 12:58:31 +01:00
cschwinne
9bf534288c Removed pixel locking 2020-01-02 22:10:59 +01:00
cschwinne
3d359229cf Reworked effects to use data instead of locked 2020-01-02 20:41:15 +01:00
cschwinne
8013f8d5b3 Update year 2020-01-02 02:12:10 +01:00
srg74
cf12ab4b74 Merge pull request #1 from Aircoookie/master
Update to recent version
2019-12-31 21:27:27 -05:00
Aircoookie
0f3eecaa8a Merge pull request #540 from srg74/patch-3
Update readme.txt
2020-01-01 02:57:18 +01:00
srg74
22c1f4bb4e Update readme.txt
Minor editing
2019-12-31 19:53:25 -05:00
Aircoookie
43c5fea782 Merge pull request #527 from fishbone-git/starburst
add multi fireworks starburst effect
2020-01-01 01:17:59 +01:00
Aircoookie
41eab27f20 Merge pull request #538 from srg74/patch-1
Update wled06_usermod.ino
2020-01-01 01:14:01 +01:00
Aircoookie
ba354f68d1 Merge pull request #539 from srg74/patch-2
Update platformio.ini
2020-01-01 01:13:38 +01:00
cschwinne
a6c7cc7b41 Merge branch 'starburst' of https://github.com/fishbone-git/WLED into starburst 2020-01-01 01:06:48 +01:00
cschwinne
4dfc1631af Few Cronixie fixes 2020-01-01 01:04:54 +01:00
srg74
58861fa524 Update platformio.ini
Added commented library reference for OLED display
2019-12-31 17:57:15 -05:00
srg74
1c6b1c530f Update wled06_usermod.ino
Corrected pin numbering
2019-12-31 17:52:59 -05:00
cschwinne
21b498fece Memory optimizations 2019-12-31 19:01:37 +01:00
cschwinne
446e2c123f More improvements 2019-12-31 16:37:44 +01:00
fishbone-git
b3a7ee633d Merge branch 'starburst' of https://github.com/fishbone-git/WLED into starburst 2019-12-31 13:47:34 +01:00
fishbone-git
8b6366688a minor updates for cleanup 2019-12-31 13:47:17 +01:00
cschwinne
1671c78260 First working state 2019-12-31 12:35:18 +01:00
Aircoookie
96ca459df8 Merge branch 'master' into starburst 2019-12-31 11:13:40 +01:00
cschwinne
51fb981d24 Add possiblilty for segments to dynamically allocate memory 2019-12-31 11:11:05 +01:00
cschwinne
2ef46195d3 Merge branch 'master' of https://github.com/Aircoookie/WLED 2019-12-30 17:34:22 +01:00
cschwinne
6e35b5ba8b Fix analog write range 2019-12-30 17:34:15 +01:00
Aircoookie
b8ea0bd1ff Merge pull request #516 from fishbone-git/framerate
Last of the FrameTime fixes from me
2019-12-30 01:51:52 +01:00
cschwinne
8ca6ca2c88 TriWipe synced 2019-12-30 01:40:38 +01:00
cschwinne
508804d0d5 Few fixes for tricolor wipe 2019-12-30 01:18:19 +01:00
fishbone-git
eb251050a5 fix exploding firworks controls to match the slider direction to the effect 2019-12-30 00:22:28 +01:00
fishbone-git
67758b4980 rework sinelon, bouncing, popcorn to remove some unnecessary statics 2019-12-30 00:20:05 +01:00
fishbone-git
f187d7258b rework for slightly better visuals 2019-12-30 00:08:49 +01:00
fishbone-git
5efd1f3a91 add comment for source and description 2019-12-30 00:04:56 +01:00
fishbone-git
e3def22b07 add multi fireworks starburst effect 2019-12-28 15:43:55 +01:00
fishbone-git
ce5839ce27 remove debug message 2019-12-27 22:20:34 +01:00
fishbone-git
50082043ef add exploding fireworks 2019-12-27 20:58:06 +01:00
fishbone-git
012045878d theatre rainbow too fast with a double-step 2019-12-24 21:05:20 +01:00
fishbone-git
3083ccddcc rework of new effects, sync to FRAMETIME add options for sinelon 2019-12-24 20:41:03 +01:00
fishbone-git
f39b9041a0 remove test 2019-12-24 15:22:40 +01:00
fishbone-git
37827cdd6c another manual merge 2019-12-24 15:20:38 +01:00
fishbone-git
58f41a1f9b manual merge #2 2019-12-24 15:12:54 +01:00
fishbone-git
7712faca0a manual merge 2019-12-24 15:11:04 +01:00
fishbone-git
805fe1d47e Revert "more effects to FRAMETIME"
This reverts commit f3371c443e.
2019-12-24 15:05:12 +01:00
fishbone-git
0d4d1eff94 Revert "Merge branch 'master' into framerate"
This reverts commit 38cc460358, reversing
changes made to 8600360173.
2019-12-24 14:58:22 +01:00
fishbone-git
38cc460358 Merge branch 'master' into framerate 2019-12-24 14:51:33 +01:00
fishbone-git
8600360173 more effects to FRAMETIME 2019-12-24 14:50:35 +01:00
fishbone-git
f3371c443e more effects to FRAMETIME 2019-12-24 14:46:07 +01:00
fishbone-git
a86f750473 Merge remote-tracking branch 'upstream/master' 2019-12-24 01:09:00 +01:00
Aircoookie
92b532ce9a Merge pull request #510 from fishbone-git/framerate
Sizing for scan and dual_scan
2019-12-24 00:53:46 +01:00
cschwinne
924f97cbe8 Improvements to scan and segment fixes 2019-12-24 00:48:51 +01:00
cschwinne
8817dc6d73 Add tertiary color to presets (#509) 2019-12-24 00:06:23 +01:00
fishbone-git
7324d59e08 Merge branch 'master' of https://github.com/Aircoookie/WLED 2019-12-23 23:24:10 +01:00
fishbone-git
dcd8e9250f Merge branch 'master' of https://github.com/Aircoookie/WLED into framerate 2019-12-23 23:08:25 +01:00
fishbone-git
f07578e0cb add sizing to scan mode 2019-12-23 22:49:29 +01:00
Aircoookie
cabcf8b7b2 Merge pull request #344 from ericyanush/tz-sask
Add support for Saskatchewan Timezone
2019-12-23 21:03:04 +01:00
cschwinne
a90a07f46d Put new timezone to end of list 2019-12-23 20:54:00 +01:00
Aircoookie
9839bab8dc Merge pull request #507 from fishbone-git/framerate
More framerate conversions, etc
2019-12-23 20:47:40 +01:00
Aircoookie
b9dd3de63b Merge branch 'master' into framerate 2019-12-23 20:07:32 +01:00
cschwinne
194aa90aee Noise 4 fix 2019-12-23 19:28:37 +01:00
fishbone-git
9bc72df1b5 meteor with framerate 2019-12-23 19:23:57 +01:00
fishbone-git
b2439ca0af Merge branch 'master' of https://github.com/Aircoookie/WLED into framerate 2019-12-23 19:06:49 +01:00
fishbone-git
70d04d807b cleanup 2019-12-23 18:48:01 +01:00
fishbone-git
2372675c79 combine larson scanners 2019-12-23 18:38:54 +01:00
cschwinne
cb66900575 More effects using FRAMETIME 2019-12-23 13:06:14 +01:00
Aircoookie
de4be44728 Merge pull request #502 from gwaland/oled-work
modify /usermods/ssd1306_i2c_oled_u8g2/ to be slightly more robust.
2019-12-22 23:56:03 +01:00
fishbone-git
21dc037848 Merge branch 'master' of https://github.com/Aircoookie/WLED 2019-12-22 17:55:40 +01:00
fishbone-git
9fe5e69503 Merge branch 'master' of https://github.com/Aircoookie/WLED into framerate 2019-12-22 17:47:28 +01:00
fishbone-git
c0ac381f6f rework effects to frametime 2019-12-22 17:41:32 +01:00
Bobby Walker
5f235c121d correction form ifdef to if defined 2019-12-21 18:59:12 -06:00
Bobby Walker
6b8e9a63f3 define to make knownSsid compatible with esp32 2019-12-21 18:53:37 -06:00
Bobby Walker
3dcda08735 Corrected ip and ssid to be knownIp and knownSsid 2019-12-21 18:50:33 -06:00
Bobby Walker
f92ee8e762 Break out SDA and SCL pins into defines. 2019-12-21 18:49:25 -06:00
cschwinne
94200dd3a4 Fixed effects (#466) 2019-12-21 03:17:54 +01:00
Aircoookie
512c4dd6f1 Merge pull request #487 from Aircoookie/pr/481
Add Analog/Solid RGB(W) strip support
2019-12-20 00:07:12 +01:00
cschwinne
6d43854557 Fix PIO 2019-12-19 23:43:18 +01:00
cschwinne
112ba7ac5c Fix compile for analog 2019-12-19 21:31:14 +01:00
cschwinne
4c58929dd4 Fix compile 2019-12-19 21:08:21 +01:00
Aircoookie
2188509d2c Merge branch 'master' into solidRgbwLedStrips 2019-12-19 20:59:36 +01:00
Def3nder
263ef14822 bracket error 2019-12-18 15:41:13 +01:00
Def3nder
ed24f72cf9 Changes for 4CH and 5CH LED stripes
ESP32 fixes for Solid RGBW (...not implemented for ESP32 yet)

Use 5CH solid RGB stripes

adapt the logic to use CW and WW for different CT-values

change from Opt-out to Opt-In for analog LEDs

Added new boards

Alexa color changes to match white values with 4Ch and 5Ch LED stripes
bracket error


Device definitions
2019-12-18 15:35:32 +01:00
Def3nder
c1197d06fe Changes for 4CH and 5CH LED stripes
ESP32 fixes for Solid RGBW (...not implemented for ESP32 yet)

Use 5CH solid RGB stripes

adapt the logic to use CW and WW for different CT-values

change from Opt-out to Opt-In for analog LEDs

Added new boards

Alexa color changes to match white values with 4Ch and 5Ch LED stripes
2019-12-18 13:35:05 +01:00
cschwinne
bd4d1cdd41 Fix preset cycle 2019-12-18 00:47:24 +01:00
cschwinne
2c70d66d4a Fix TypeError (#453) 2019-12-18 00:41:45 +01:00
fishbone-git
97ecace40e Merge remote-tracking branch 'upstream/master' 2019-12-17 12:07:50 +01:00
cschwinne
6ef988549d Fix compile
facepalm
2019-12-13 14:16:42 +01:00
cschwinne
9088d79390 Add tertiary color to sync (#451) 2019-12-13 14:14:36 +01:00
cschwinne
0c9bcb2445 Update readme 2019-12-13 01:31:48 +01:00
cschwinne
c98c54bd6b Release of WLED v0.9.0-b1
Timebase reset when turned off
Added Aurora paletta
2019-12-13 01:23:07 +01:00
fishbone-git
225e66a522 Merge remote-tracking branch 'upstream/master' 2019-12-12 20:59:31 +01:00
Aircoookie
f1810a9784 Merge pull request #449 from ohminy/patch-1
Create wled06_usermod.ino
2019-12-12 18:10:27 +01:00
ohminy
9526051766 Create wled06_usermod.ino
Using rotary encoder, control effect or brightness
2019-12-12 23:01:13 +09:00
Aircoookie
bd435b175b Merge pull request #445 from spitsw/mstr
Closes Aircoookie/WLED#444
2019-12-12 00:19:44 +01:00
Warren Spits
42ab734256 Closes Aircoookie/WLED#444 2019-12-11 22:08:59 +11:00
cschwinne
77d89e7df3 Fix iOS scrolling
Other small adjustments
Allow for passwords with * as 1st char
2019-12-11 00:59:15 +01:00
fishbone-git
c1dec16c50 add popcorn effect 2019-12-10 20:34:59 +01:00
fishbone-git
86ae11f4c4 add sinelon effect 2019-12-10 20:26:02 +01:00
fishbone-git
7ca1970fff add bouncing balls effect 2019-12-10 20:06:00 +01:00
Warren Spits
b1cbbeb935 Segment reverse fix 2019-12-10 11:34:11 +11:00
Warren Spits
2dce4462a0 Saving and loading of grouping and spacing. 2019-12-09 23:16:16 +11:00
Warren Spits
55e2bc27c6 Converted segments to use lengths.Segment stop is now derived.Clears the skipped pixels.Fixed getPixelColor. 2019-12-08 23:17:42 +11:00
Warren Spits
2c3cad6e61 Pixel grouping support, configurable through JSON API. It probably breaks cronixie. 2019-12-07 23:25:38 +11:00
cschwinne
6122a8371a Added Glitter and Candle effects 2019-12-06 01:44:45 +01:00
cschwinne
4ffeb05120 Fix #418 and #420 2019-12-05 11:07:54 +01:00
cschwinne
310f55abb6 Merge branch 'master' of https://github.com/Aircoookie/WLED 2019-12-05 01:58:12 +01:00
cschwinne
d6c0642a02 Add new UI! 2019-12-05 01:58:03 +01:00
Aircoookie
541556874f Merge pull request #413 from dkneisz/master
Added Arduino Core 2.6.1 and 2.6.2 and made 2.6.2 default
2019-12-05 01:56:06 +01:00
Dave
477d7080b8 Added Arduino Core 2.6.1 and 2.6.2 and made 2.6.2 as default
2.4.2 was default and caused a boot loops on NodeMCU for me. Even erasing and re-flashing didn't solve the problem. With core 2.6.2 it seems to be fine.
2019-12-04 19:12:16 +01:00
cschwinne
173c752d62 Added spots and two dots effects 2019-12-04 12:15:12 +01:00
cschwinne
3b70488828 NTP server settable
Added segment commands to HTTP api
Removed HA autodiscovery
2019-12-04 02:01:47 +01:00
cschwinne
334783f89a Preset 16 working 2019-12-03 14:15:12 +01:00
cschwinne
89a54e31f1 Cleanup and segment improvements 2019-12-02 12:41:35 +01:00
cschwinne
354d18f78e Main segment changes 2019-12-01 01:42:52 +01:00
cschwinne
0e8806eb2b Integrated liveview 2019-11-30 19:17:25 +01:00
cschwinne
731550acb3 Fixed reverse 2019-11-30 11:46:31 +01:00
Aircoookie
be4019b4d3 Merge pull request #400 from ironosity/disable_n_leds_for_all_fx
Adding new setting to disable fixed number of LED
2019-11-30 11:20:53 +01:00
cschwinne
70ffcd9adf Merge branch 'master' of https://github.com/Aircoookie/WLED 2019-11-30 11:17:43 +01:00
cschwinne
bbe511dd15 Attempting to fix disconnect on Adalight (ESP32, #194) 2019-11-30 11:17:37 +01:00
Aircoookie
82d5ac91d7 Merge pull request #402 from 400killer/patch-3
Create wled00.txt
2019-11-30 00:33:18 +01:00
Aircoookie
54de0eab6a Merge pull request #401 from 400killer/patch-2
wled06_usermod.ino
2019-11-30 00:32:46 +01:00
400killer
4d5bb274d1 Create wled00.txt
Definitions needed for reading the Dallas temp sensor used on the QuinLED boards.
2019-11-29 11:58:40 -08:00
400killer
131fae57e5 wled06_usermod.ino
This section is used to read the temperature from the sensor and prints it using the MQTT service started by Aircoookie.
2019-11-29 11:55:26 -08:00
emerrill
37da53c20e fixing some spacing 2019-11-29 12:25:30 -07:00
Aircoookie
6ad57a15cf Merge pull request #399 from 400killer/patch-1
Create readme.txt
2019-11-29 19:02:02 +01:00
emerrill
4729bce16c Merge branch 'master' of github.com:Aircoookie/WLED into disable_n_leds_for_all_fx
 Conflicts:
	wled00/data/settings_leds.htm
2019-11-29 10:56:59 -07:00
emerrill
0b5ac7a139 Adding ability to turn off specified number of LEDs. Added to LED settings.
Also added FX for Tri Color Static, defaults tri to white.
2019-11-29 10:53:01 -07:00
400killer
677e23ad14 Create readme.txt 2019-11-29 08:52:51 -08:00
Aircoookie
6d838e3043 Merge pull request #397 from mrVanboy/ib/usermod-oled
usermods: Add SSD1306 display with u8g2
2019-11-28 22:53:56 +01:00
Ivan Boyarkin
f322abceb8 usermods: Add SSD1306 display with u8g2
This commit adds example of usermod file for displaying basic
infromation SSD1306 I2C OLED displya utilizing u8g2 library.

Related to:
https://github.com/Aircoookie/WLED/issues/389
2019-11-28 22:43:46 +01:00
cschwinne
e754d21598 Raise max universes to 9 2019-11-28 20:13:52 +01:00
Aircoookie
0fdd861ef1 Merge pull request #391 from badbadc0ffee/adalight
rewrite adalight parser
2019-11-28 19:50:40 +01:00
cschwinne
2e5f6a3507 Improved adalight show() handling 2019-11-28 19:25:04 +01:00
Aircoookie
4e57cab0fa Merge pull request #395 from spitsw/gamma
Converted UTF-16 files with UTF-8 and CR/LF to LF.
2019-11-28 09:32:22 +01:00
Warren Spits
9930c8f94d Converted UTF-16 files with UTF-8 and CR/LF to LF. 2019-11-28 08:28:13 +11:00
Florian Moesch
f8e262b87e rewrite adalight parser 2019-11-26 21:47:55 +01:00
cschwinne
896bdaf124 Create usermods folder (#389) 2019-11-26 21:21:54 +01:00
cschwinne
2e4f2639a3 Fix #388 2019-11-26 20:41:15 +01:00
Aircoookie
ce89a92d0d Merge pull request #368 from stockklauser/master
Fix Visual Studio Project Structure and add 3 new Effects
2019-11-25 01:34:34 +01:00
cschwinne
1d9d1f6bbd Simplified police code 2019-11-25 01:20:03 +01:00
cschwinne
767b57fc01 Add "psave" field to state JSON 2019-11-25 00:20:00 +01:00
thomas.stockklauser
9e00177d76 - Fix the Visual Studio Project Structure with the e131 lib change to async
- Add 3 New Effects: Police, Police All, Multi Dynamic
2019-11-22 19:19:48 +01:00
Aircoookie
095429a7df Merge pull request #364 from debsahu/patch-1
fix #361
2019-11-21 15:26:29 +01:00
cschwinne
983efd61fb Only connect with static IP if GW is configured (#362) 2019-11-21 15:20:15 +01:00
Debashish Sahu
e028316308 fix #361 2019-11-21 09:02:12 -05:00
Aircoookie
e1354accb8 Merge pull request #363 from TheZoker/fix-espasyncudp-version
Pin ESPAsyncUDP version to avoid unexpected behavior
2019-11-21 14:47:47 +01:00
Florian Gareis
ea726f928d Pin ESPAsyncUDP version to avoid unexpected behavior 2019-11-21 14:01:45 +01:00
cschwinne
6b419dbfc0 Fix PIO (#92) 2019-11-20 00:47:43 +01:00
Aircoookie
006a9eaf44 Merge pull request #356 from nwestwind/patch-1
Update readme.txt
2019-11-19 12:35:40 +01:00
Noah
76117854c6 Update readme.txt 2019-11-18 20:27:45 -08:00
cschwinne
6eae6db46b Migrate to ESPAsyncE131 2019-11-18 20:43:27 +01:00
cschwinne
3aacb7150d Added live preview json 2019-11-18 12:29:36 +01:00
cschwinne
81298a1034 Fix string overflow 2019-11-13 01:20:14 +01:00
cschwinne
b3d728df91 Add 12V brightness limiter and configurable per-led current (#295) 2019-11-12 19:33:34 +01:00
Eric Yanush
9a091ff11a Add support for Saskatchewan Time (CST no DST) GMT-6 2019-11-11 18:22:58 -06:00
cschwinne
6989b1730e Added mqtt status topic 2019-11-10 22:13:07 +01:00
cschwinne
1595542d59 Replaced literal URLs in readme 2019-11-10 01:12:38 +01:00
cschwinne
fba9992a10 Updated Espalexa (#274) and readme 2019-11-10 00:54:35 +01:00
Aircoookie
867dce2294 Merge pull request #337 from brentbrooks70/master
Fixed wled00.vcxproj, was broken as of 0.86 WS2812FX filename changes
2019-11-09 22:11:27 +01:00
BrentBrooks70
692554a899 Add files via upload
Updated WS2812FX file names to FX
As of 0.86 this was broken for Visual Micro
2019-11-09 14:28:46 -05:00
cschwinne
f3cc616e07 Fix reverse on segments with start > 0 2019-11-08 16:58:23 +01:00
Def3nder
d1c289b709 Add Solid (analog) RGBW strip support
add 4 ESP pins for driving analog/non-addressable RGBW LED strips
2019-11-05 15:52:18 +01:00
cschwinne
e7a0874a57 Improved theater effect 2019-11-03 01:18:02 +01:00
cschwinne
1beb9c4bb8 Added WiFi section to JSON info (#288)
Add tt command to JSON API (#291)
2019-10-29 02:21:23 +01:00
cschwinne
6eef3a9037 Add mac address to mDNS announcement (#305) 2019-10-29 01:30:07 +01:00
cschwinne
ddaaae46a6 Amending missing files in previous commit 2019-10-29 01:19:56 +01:00
cschwinne
4e4773a370 Fix JSON API FX change not sending sync (#283)
Rename duplicate effects (#294)
Add India Standard Time
Fix flash on startup
Fix NTP with lwip2
2019-10-29 01:19:04 +01:00
cschwinne
f4a2ffc5d2 Update platformio.ini 2019-10-26 01:01:16 +02:00
cschwinne
ba1117e10e Release v0.8.6 2019-10-26 00:00:44 +02:00
cschwinne
0cd46f932a Fix 2.4.0 2019-10-25 15:32:09 +02:00
cschwinne
937f404583 Fix ESP32 2019-10-25 11:54:47 +02:00
cschwinne
d13d60d752 New WiFi logic 2019-10-25 00:14:58 +02:00
cschwinne
31e4e7c709 HA discovery wdt reset 2019-10-20 17:38:25 +02:00
cschwinne
0d3a8ce31b Update MQTT library 2019-10-20 12:48:29 +02:00
cschwinne
be185b46a7 Reworked WiFi logic
Remaining issues:
MQTT reconnects too often
WiFI AP doesn't work if searching for STA
2019-10-18 23:47:11 +02:00
cschwinne
90fa5b3b93 Removed onlyAP 2019-10-18 14:06:07 +02:00
cschwinne
733996772b WLED_CONNECTED macro 2019-10-18 13:26:39 +02:00
cschwinne
d4c921ea2e Timebase sync 2019-10-18 12:19:52 +02:00
cschwinne
2852061699 Refactor WS812FX file names 2019-10-07 23:38:21 +02:00
cschwinne
d8859b9f0a Improved running effects 2019-10-07 23:22:56 +02:00
cschwinne
ae1bc96006 More effects use FRAMETIME 2019-10-07 20:17:52 +02:00
cschwinne
f30ffb4413 Improved rainbow effects 2019-10-05 01:56:55 +02:00
cschwinne
273c6467c8 Fix travis (ESP01 too little flash) 2019-10-04 01:38:42 +02:00
cschwinne
846a1d007c Improved fade modes 2019-10-04 01:21:18 +02:00
cschwinne
1dccc8dc78 Improved Color Wipe 2019-10-03 20:57:22 +02:00
cschwinne
e0d67bd057 Improved effects 2019-10-03 16:33:37 +02:00
cschwinne
4b4b93ac04 Added Halloween Eyes effect
Added Twinklecat
2019-10-02 01:17:26 +02:00
Aircoookie
4390aee1e0 Merge pull request #234 from pille/master
fix verison number of current release
2019-09-29 11:20:30 +02:00
pille
4cddb16788 fix verison number of current release 2019-09-28 13:43:57 +02:00
cschwinne
e1179fd8c8 Delete accidentallly included bin 2019-09-26 14:06:50 +02:00
cschwinne
cb77285277 Support APA102 on ESP32 2019-09-26 14:02:58 +02:00
cschwinne
6c9d161950 Fixed transitions and gamma 2019-09-19 21:15:20 +02:00
Aircoookie
40aaac5868 Merge pull request #218 from Aircoookie/captiveportal
Release v0.8.5
2019-09-12 15:30:34 +02:00
cschwinne
e16b69594e Fix PIO 2019-09-12 13:08:07 +02:00
cschwinne
4837bf007a Update welcome page 2019-09-12 12:41:51 +02:00
cschwinne
705fd4dafd Release v0.8.5 2019-09-12 12:40:06 +02:00
cschwinne
a3e28d3c66 First version of captive portal 2019-09-05 22:45:59 +02:00
cschwinne
4a6755c28a Added C9 and Sakura palettes 2019-08-31 01:41:25 +02:00
cschwinne
188fe5dc52 Added TwinkleFOX effect
Added Orangery palette
2019-08-30 15:39:34 +02:00
cschwinne
44a8ae457d Fixed JSON API POST requests
Speed set COOLING for Fire2012 (#208)
2019-08-25 23:52:40 +02:00
cschwinne
92eafcfe1a Fixed crash on opening settings in core 2.5.2 (#168) 2019-08-21 01:18:25 +02:00
Aircoookie
b12b031fdd Merge pull request #202 from timothybrown/mqttauth
MQTT Authentication Support
2019-08-19 23:20:35 +02:00
cschwinne
492ec489a1 Small changes to MQTT auth
Changed mqttPort to uint16 type
Password no longer transmitted to settings page
Chnaged topics and identifiers to last 6 bytes of mac format
Added security warning
2019-08-18 18:14:17 +02:00
Timothy Brown
c57124e876 Added MQTT port field, bumped user, pass and CID to 40 characters 2019-08-17 21:34:47 -04:00
Timothy Brown
95b33c9c34 Tidied up code 2019-08-17 07:26:40 -04:00
Timothy Brown
c6d8b63e54 Added MQTT authentication support 2019-08-17 06:27:06 -04:00
Aircoookie
f0f02c4ea6 Merge pull request #193 from stockklauser/0.8.4_master_extend_VS
Fix Compile Issues with Visual Studio 2017 / Visual Assist Arduino  and Add Visual Studio Project Files
2019-07-24 23:22:01 +02:00
thomas.stockklauser
eb2cb6810a Modify Structure to fix path issues 2019-07-23 18:51:26 +02:00
thomas.stockklauser
b3c090e9ed Add Visual Studio Support and fix a Compile Issue with Visual Assist / Studio 2017 2019-07-23 18:04:26 +02:00
thomas.stockklauser
13366fc9f8 Add Visual Studio Project Structure 2019-07-23 17:59:55 +02:00
thomas.stockklauser
929af7830a Add Visual Studio Project Structure
Fix a compile Issue in wled19_json.ino with Visual Studio / Visual Assist
2019-07-23 17:35:40 +02:00
cschwinne
13062cf0e4 Merge branch 'master' of https://github.com/Aircoookie/WLED.git 2019-06-21 23:14:36 +02:00
cschwinne
b897a8a35f Updated to ArduinoJson v6
Fixed JSON crash on core v2.5.2
2019-06-21 23:12:58 +02:00
cschwinne
117dc5288d Added basic segment support
Updated Espalexa
2019-06-20 14:40:12 +02:00
Aircoookie
4b5a3bd3d5 Revert LEDPIN to 2 2019-05-23 00:33:15 +02:00
cschwinne
b224a67ea7 Refactored WS2812FX variable names 2019-05-22 00:23:09 +02:00
cschwinne
793f919d59 Added MQTT auto reconnect 2019-05-21 18:50:56 +02:00
Aircoookie
315987b2f6 Merge pull request #160 from T-Arens/master
Added support for APA102 LEDs.
2019-05-04 15:54:33 +02:00
Thomas Arens
9b7db548a2 Only disable the button pin if it conflicts with one of the APA102 pins. 2019-05-01 16:52:22 +02:00
Thomas Arens
126b70f781 Added support for APA102 LEDs. Uncomment "#define USE_APA102" in NbpWrapper.h. Connect clock to GPIO 0 and data to GPIO 2. 2019-05-01 03:09:08 +02:00
Aircoookie
0bbff627e2 Merge pull request #152 from YeonV/patch-1
Fixed MQTT color response
2019-04-15 22:37:41 +02:00
Yeon Vinzenz Varapragasam
961d23e2a1 Fixed MQTT color response
Leading zeros are not trimmed on /c topic anymore :)
Before blue: #FF
After blue: #0000FF
2019-04-15 20:43:32 +02:00
cschwinne
b03ff9a48a Updated Espalexa to 2.4.2
Added UDP realtime 255 as keep state until changed
Added "true" and "false" MQTT payloads
2019-04-14 19:31:25 +02:00
cschwinne
3ffb40fafa Fixed HA autodiscovery and MQTT ON 2019-03-27 21:31:59 +01:00
cschwinne
1a3b4ac2ac Fixed meteor FX crashing 2019-03-27 21:06:07 +01:00
cschwinne
794e17442f Release of v0.8.4
Default to LwiP 2 in PIO
Fixed 12hr format time
2019-03-25 23:27:35 +01:00
cschwinne
238d7119e0 Completed HA autodiscovery
Modified platformio.ini
2019-03-24 18:28:36 +01:00
cschwinne
8a929a8348 Added new Homeassistent broadcast logic 2019-03-24 00:49:26 +01:00
cschwinne
cf77153647 Merge branch 'master' of https://github.com/Aircoookie/WLED.git 2019-03-19 12:21:56 +01:00
cschwinne
a2da0b0641 Fixed HTTP API XML response 2019-03-19 12:19:48 +01:00
Aircoookie
73faa13811 Merge pull request #134
Added Homeassistant autodiscovery
2019-03-18 19:56:53 +01:00
cschwinne
1a71872c7b Added flag to enable Homeassistant autodiscovery 2019-03-18 19:54:06 +01:00
Debashish Sahu
62fe7135bd PIO ESP01 fix
- fix core for ESP01, newer cores are too big
2019-03-18 13:30:47 -04:00
Debashish Sahu
078940d29f PIO & TravisCI fix
- fix errors while compiling for PIO and TravisCI
2019-03-18 13:13:04 -04:00
Debashish Sahu
2fafe42c18 HA Light Auto Discovery
- Send HA MQTT Discovery message ~2.4kB based on input by @YeonV from here: https://github.com/Aircoookie/WLED/issues/131
2019-03-18 12:23:39 -04:00
cschwinne
c8a7537157 Added support for SPIFFS
Fixed ESP32
2019-03-16 02:09:37 +01:00
cschwinne
d4bf1cb23d Added button double press macro option
Added toggle (relay) pin
2019-03-13 11:13:03 +01:00
cschwinne
46e4350013 Improved heap usage by 2k 2019-03-11 19:30:49 +01:00
cschwinne
202eb0d854 Fixed /json with ESP core <2.5.0 2019-03-11 17:57:06 +01:00
cschwinne
898702346e Fixed JSON API on bug
Fixed RN=1 not having an effect if default off
2019-03-11 00:20:17 +01:00
cschwinne
b72e6f16ca Small memory improvements 2019-03-09 21:41:23 +01:00
cschwinne
b9c27ed324 Added RD HTTP api call for realtime udp 2019-03-09 14:48:13 +01:00
cschwinne
0166dfe16e Fixed colorwheel 2019-03-07 23:22:52 +01:00
cschwinne
7274541722 Fixed platformio compilation
Added more debug info in serial on boot
2019-03-07 16:36:26 +01:00
cschwinne
709ff7a701 Finished JSON API
Added RV http api call
Fixed CY,PA,PC,PX api calls
Fixed CORS
2019-03-06 21:31:12 +01:00
cschwinne
66c224c954 Added JSON state API 2019-03-06 01:20:38 +01:00
cschwinne
3f9b37aa7f Added /json/state 2019-03-05 10:59:15 +01:00
cschwinne
0377958d8f Updated hue sync to use ArduinoJSON
Fixed brightness when ABL deactivated
2019-03-03 23:27:52 +01:00
cschwinne
cc1cfd70b8 Added ArduinoJSON 2019-03-03 18:05:56 +01:00
cschwinne
bc125ad76c Updated Espalexa to v2.4.0 2019-03-01 17:10:42 +01:00
cschwinne
62a2246448 Included effect and palette lists in LED settings 2019-02-25 22:23:26 +01:00
cschwinne
587cf751d8 Fixed preset loading 2019-02-25 19:14:13 +01:00
cschwinne
600181ed07 Updated platformio.ini 2019-02-22 22:53:39 +01:00
cschwinne
f0e525d2e2 Added relative API calls 2019-02-22 22:53:33 +01:00
cschwinne
f86cdd8cde Added /json/info page 2019-02-21 16:32:15 +01:00
cschwinne
4a4c537a0d Reverted to default LEDPIN 2019-02-21 00:21:35 +01:00
cschwinne
1caaf04dfa Various performance and reliability improvements 2019-02-20 23:44:34 +01:00
cschwinne
b422a80249 Fixed button-caused asyncserver unresponsiveness
Fixed RGBW power calculation
2019-02-20 15:18:04 +01:00
cschwinne
ba19e20833 Added Macro notification option
Removed realtime UI lock
2019-02-19 12:57:50 +01:00
cschwinne
c34ddb2bc3 Initial async hue client 2019-02-18 22:34:21 +01:00
cschwinne
aa315f8472 Switched from PubSubClient to AsyncMqttClient 2019-02-17 19:21:09 +01:00
cschwinne
2af6af2bf0 Added HTTP OTA update via ESPAsyncWebServer 2019-02-17 17:11:10 +01:00
cschwinne
5694ff7c97 Migrated to AsyncWebServer 2019-02-16 00:21:22 +01:00
cschwinne
76f1c689c1 Interim Async Update 2019-02-14 17:25:41 +01:00
cschwinne
a371239172 Fixed mobile UI effect list not loading 2019-02-12 14:50:19 +01:00
cschwinne
4fd904fbcc Merge branch 'master' of https://github.com/Aircoookie/WLED.git 2019-02-12 11:05:00 +01:00
cschwinne
b73a257389 Fixed broadcast IP compilation issue 2019-02-12 11:03:54 +01:00
Aircoookie
9e70d6b3e1 Merge pull request #105 from Aircoookie/development
Release of v0.8.3
2019-02-11 23:53:53 +01:00
cschwinne
9caca37ab1 Release of v0.8.3
Removed initLedsLast
Improved Fireworks
2019-02-11 23:49:04 +01:00
cschwinne
6e76fc0aa7 Added JSON FX + palette lists 2019-02-10 23:05:06 +01:00
cschwinne
6171883758 Split up WS2812FX.cpp in FX and helper files 2019-02-09 16:37:20 +01:00
cschwinne
942b68c948 Added shields.io to readme 2019-02-09 15:41:55 +01:00
cschwinne
9ca7ffa5a3 Refactored white to col[3]
Added Saw effect
2019-02-05 21:53:39 +01:00
cschwinne
d1ce23c5ac Unique mDNS name
Various optimizations
2019-02-05 19:40:24 +01:00
cschwinne
b7b6d0a6bc Improved ripple effect 2019-02-02 23:59:48 +01:00
cschwinne
10c51eea2c Added Ripple and revamped twinkle effects 2019-01-31 23:42:48 +01:00
cschwinne
48d20c02a1 Added timed macro weekday support 2019-01-31 00:09:44 +01:00
cschwinne
c5cc0b3f2b Updated Mobile UI
Fixed Smooth Meteor stuck pixels
Added CORS response
Added secondary color to http API response
2019-01-18 01:20:36 +01:00
cschwinne
6ebef8846c Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2019-01-09 23:03:34 +01:00
cschwinne
5d1993935e Added Alexa Color support 2019-01-09 22:55:18 +01:00
Aircoookie
caab8943cb Merge pull request #90 from cboltz/cboltz-timezone-deps
Use time/time.h from local dependencies
2018-12-20 21:17:42 +01:00
Christian Boltz
f5c05b24fb Use time/time.h from local dependencies
This fixes a compile issue, which can be
a) file not found or
b) (after installing the Time library) redefinition of a variable
2018-12-17 22:07:43 +01:00
Aircoookie
940a0d006d Merge pull request #89 from definitio/master
Fix compiling on a case sensitive filesystems
2018-12-17 15:41:24 +01:00
definitio
8fe67a04d8 Fix compiling on a case sensitive file systems 2018-12-17 18:08:59 +04:00
cschwinne
bec745d095 Improved colortwinkles on longer strips
Added offMode
2018-12-16 20:38:00 +01:00
Aircoookie
223fd35138 Merge pull request #84 from Aircoookie/development
Updated platformio.ini for v0.8.2
2018-12-06 16:32:52 +01:00
cschwinne
d3fc0309c0 Updated platformio.ini for v0.8.2 2018-12-06 16:31:52 +01:00
Aircoookie
830223f6e2 Merge pull request #83 from Aircoookie/development
Fixed incorrect #defines for 0.8.2
2018-12-06 00:43:32 +01:00
cschwinne
eb53c52499 Fixed incorrect #defines for 0.8.2 2018-12-06 00:40:59 +01:00
Aircoookie
96c9e2b4d6 Merge pull request #82 from Aircoookie/development
Updated readme
2018-12-06 00:31:39 +01:00
cschwinne
c34b948bad Updated readme 2018-12-06 00:30:38 +01:00
Aircoookie
9ac609f846 Release of v0.8.2 (merge)
Release of v0.8.2 (PR)
2018-12-06 00:30:05 +01:00
cschwinne
6aa47bfd1b Release of v0.8.2
Improved settings page scaling on mobile devices
Added 2 new effects to web UIs
2018-12-06 00:27:36 +01:00
cschwinne
ff46e6ea86 Added Auto Brightness Limiter and power calculation 2018-12-04 00:58:06 +01:00
cschwinne
5489c74986 Added Smooth meteor and Railway effects 2018-12-02 02:49:05 +01:00
cschwinne
f6f8151150 Added meteor FX to web UI 2018-11-29 21:46:05 +01:00
cschwinne
a20d577f6c WS2812b Color Order changeable in settings
Meteor effect can now use palettes
2018-11-28 12:24:32 +01:00
cschwinne
c4c2494dd1 Improved binary size 2018-11-25 00:00:02 +01:00
cschwinne
c9c294a1d5 Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2018-11-24 11:52:44 +01:00
cschwinne
6359a8a8a2 Improved effect updating internals 2018-11-24 11:52:23 +01:00
Aircoookie
f9b44381bd Merge pull request #77 from viknet365/master
add meteor effect
2018-11-23 00:21:07 +01:00
Aircoookie
eb1ccb600b Delete htmls00.h
0.8.2 will use the new gzip system with different files. HTML changes will be manually added
2018-11-23 00:20:26 +01:00
cschwinne
b2db61aa03 Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2018-11-23 00:16:25 +01:00
cschwinne
ee55a574de Moved About section to Github wiki
Updated readme
2018-11-23 00:11:47 +01:00
cschwinne
0998fd32cd Moved About section to Github wiki 2018-11-23 00:03:44 +01:00
cschwinne
686f2c4aa6 IR codes will now also be printed without debug enabled 2018-11-22 22:43:44 +01:00
cschwinne
cd234673ea Fixed nightlight issues
Added custom infrared method
2018-11-22 00:09:30 +01:00
cschwinne
54d7a81f16 Incomplete commit for Nightlight Fixes
Interim state (Reason: Local Working Copy Data Corruption)
Affected files: (local changes will be re-implemented in next commit)
settings_sync.html (already recovered)
html_settings.h (already recovered)
wled03_set.ino
wled08_led.ino
wled09_button.ino
wled19_ir.ino
2018-11-21 23:28:20 +01:00
viknet365
9d8d2c0aa1 add meteor effect
This reverts commit f1371d6737.
2018-11-20 21:31:07 +01:00
viknet365
17ce6b9507 Revert "Add files via upload"
This reverts commit f1371d6737.
2018-11-20 21:09:06 +01:00
viknet365
296065a976 Revert "add meteor effect"
This reverts commit 0b0f600f97.
2018-11-20 20:59:13 +01:00
viknet365
0b0f600f97 add meteor effect 2018-11-20 20:42:47 +01:00
viknet365
f1371d6737 Add files via upload
add meteor effect
2018-11-20 20:35:04 +01:00
viknet365
03a33790e1 Update WS2812FX.cpp 2018-11-20 20:32:21 +01:00
cschwinne
c0816c80ae Infrared support added 2018-11-18 00:31:45 +01:00
cschwinne
071ebe6ef2 Gzipped UIs, improving speed and flash usage 2018-11-16 19:59:00 +01:00
Aircoookie
2126e42743 Merge pull request #74 from wiesendaniel/feature/pio-port
Added Plattform IO Support
2018-11-16 19:50:19 +01:00
Daniel Wiesendorf
8a2b34adb4 moved ws2812fx sources back 2018-11-16 15:02:09 +01:00
Daniel Wiesendorf
93eb4d21bf Added PIO recommendation when opening in vscode 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
868cedeed2 pio support for esp01 512k 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
5c794f428a added verbose flag to travisci.yml for debugging 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
612d6f85bd Pio support of esp32 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
e5cef6b877 fixed DEBUG constant for travis build 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
f2a63c04a8 fixed travisci build again... 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
5a5064e070 fixed travisci build 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
478fa3132c Minor fixes for PIO support 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
a84859c211 Changed platformio.ini. A few boards are building now 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
67013bd58f Changed platformio.ini. A few boards are building now 2018-11-14 22:07:04 +01:00
Daniel Wiesendorf
b51be31d8a added initial PlatformIO config. still needs work 2018-11-14 22:07:04 +01:00
Aircoookie
a3bef49124 Refactored code to improve readability (merge dev PR)
Refactored code to improve readability
Fixed non-2-char indentations
2018-11-09 17:02:58 +01:00
cschwinne
a5cf553f17 Refactored code to improve readability
Fixed non-2-char indentations
2018-11-09 17:00:36 +01:00
Aircoookie
640188f4e2 Merge pull request #68 from Aircoookie/development
Release of v0.8.0
2018-11-07 20:23:01 +01:00
cschwinne
48265bbe02 Release of WLED 0.8.1
Added Lake effect
2018-11-07 20:22:05 +01:00
cschwinne
6aaf544079 Auto-select pixel driving method based on LEDPIN 2018-11-05 02:24:13 +01:00
cschwinne
9904c10984 Added Colortwinkle effect 74 2018-11-04 20:14:23 +01:00
cschwinne
81c810eba4 Increased max. UDP leds from 341 to 490
MQTT now publishes state on connect
2018-11-01 16:16:38 +01:00
cschwinne
5e6b1e8175 Added defines for more granular feature disable control 2018-11-01 15:36:13 +01:00
cschwinne
48c165b0b4 Added support for E1.31 with more than 170 LEDs 2018-11-01 01:05:35 +01:00
cschwinne
042605701e Added DNRGB UDP protocol 2018-10-27 11:39:00 +02:00
cschwinne
32cf1495d3 Fixed tricolor chase modes
Added a new palette
2018-10-25 20:55:29 +02:00
cschwinne
9577e49231 Added Palette support for most effects
Fixed Analog Clock bugs
Added Tiamat palette
2018-10-24 02:06:07 +02:00
cschwinne
de19839145 Fixed overlay not unlocking on disable 2018-10-18 18:31:25 +02:00
cschwinne
f970780d6c Fixed Clock overlay not working in reverse mode
Removed need for Macros to start with capital letter
2018-10-18 18:06:46 +02:00
Aircoookie
1e69cc75c7 Merge pull request #57 from Aircoookie/development
Release of v0.8.0
2018-10-15 16:33:20 +02:00
cschwinne
377e4fa0a5 Release of v0.8.0 2018-10-15 16:15:51 +02:00
cschwinne
a5d6dc58d3 Fixed E1.31 multicast 2018-10-11 21:38:00 +02:00
cschwinne
a122c17340 Fixed Blynk power button and settings 2018-10-08 17:36:22 +02:00
cschwinne
34ddf104a9 Optimized EEPROM string read/write code
Changed DNS server to improve AP mode stability
2018-10-07 11:56:29 +02:00
cschwinne
f98b0beee5 Added Mobile UI power indicator 2018-10-06 14:53:15 +02:00
cschwinne
75a61f85db Cleaned up readme 2018-10-04 23:16:25 +02:00
cschwinne
c1cdf27507 Release of v0.8.0 to dev branch
Updating master after more testing
2018-10-04 22:41:35 +02:00
cschwinne
43e9743645 Fixed ESP32 version
Fixed Adalight serial Ambilight
2018-10-04 22:38:39 +02:00
cschwinne
c2972786f5 Attempted to improve AP only stability 2018-10-04 18:17:01 +02:00
cschwinne
eeb17b417c Added MQTT
Updated readme for 0.8.0
Fixed custom theme bug
Bumped version codes to 0.8.0
2018-10-04 16:50:12 +02:00
cschwinne
473991638c Fixed realtime mode not working 2018-10-01 21:31:31 +02:00
cschwinne
92b4b69b3f Split Server init code from wled05_init.ino to improve readability
Added MQTT logic
2018-09-30 20:24:57 +02:00
cschwinne
dbd6f134c1 Added CL= and C2= API calls to set HEX or DEC RGB or WRGB color
Started to add MQTT support
Pre server and init split-up
2018-09-28 23:53:51 +02:00
cschwinne
5f59487a88 Added basic Time Activated Macros function
Fixed Cronixie overlay
512K Flash mode (temporarily) unavailable
2018-09-22 22:49:24 +02:00
cschwinne
bb7f673ff9 Re-added support for 512K flash ESPs 2018-09-17 11:15:08 +02:00
cschwinne
4715180a32 Refactored wled00.ino
Attempted to fix AP mode lags
2018-09-15 17:29:01 +02:00
cschwinne
4b31610169 Updated UI with all new palettes
FastLED effects now have default palettes per effect
Fire2012 can now use Palettes
Option for palette blending added
Added new Palettes
2018-09-11 00:20:29 +02:00
cschwinne
2466c5a204 Merge branch 'development' of https://github.com/Aircoookie/WLED.git into development 2018-09-08 20:35:47 +02:00
Aircoookie
0505baff38 Resolve version code merge conflict 2018-09-08 20:34:59 +02:00
cschwinne
c55e3a37ae Added 33 gradient palette presets
Fixed welcome page not showing on fresh install
Fixed device not turning on on fresh install
2018-09-08 20:26:04 +02:00
cschwinne
ce5fec4d5f Added Pride2012 and Colorwaves effects
Adjusted Noise16 effects
Added palette fade transition option
2018-09-08 16:21:44 +02:00
cschwinne
6d4339b034 Added first palette functions
Attempted to fix welcome page
2018-09-06 02:05:56 +02:00
cschwinne
70d0aae07c First commit of 0.8.0 dev cycle
Updated to newer WS2812FX version which supports segments (not supported in WLED yet)
Added new (FastLED) effects
Adjusted FX speed timings
Removed Sweep transition and Custom Chase (seldomly used - hinder development)
Removed solid overlay (no longer needed once segments are added)
Fixed Blynk effect set
2018-09-04 15:51:38 +02:00
Aircoookie
e3b9b341fd Merge pull request #47 from Aircoookie/development
Fixed Blynk FX updates
2018-08-31 22:36:38 +02:00
Aircoookie
95083cf743 Merge pull request #46 from kayrozen/master
Fixed blynk code
2018-08-31 22:35:50 +02:00
Aircoookie
3842c4ac46 Bump version date code for blynk fix 2018-08-31 22:35:23 +02:00
kayrozen
fe178043ee fix blynk 2018-08-31 14:52:02 -04:00
Aircoookie
82d40f60f1 Release of WLED 0.7.1
Merge dev to master
2018-08-11 23:05:11 +02:00
cschwinne
1d4d885276 Release of WLED 0.7.1 to dev branch
Added E1.31 support
Added more realtime options
Attempted to fix welcome page not showing on fresh install
2018-08-11 22:59:37 +02:00
cschwinne
ed3557ffca Fixed Exception 28 loop on fresh install
Removed legacy binaries folder
2018-08-05 19:22:48 +02:00
cschwinne
1c3878fcb0 Added blynk UI updates 2018-07-29 14:03:02 +02:00
cschwinne
b3dcb9fe6c Fixed ESP32 resetting upon opening wifi settings 2018-07-22 21:21:18 +02:00
cschwinne
0462755922 further optimization 2018-07-22 14:55:10 +02:00
cschwinne
415dfd2750 Continued optimizing strings 2018-07-21 23:21:07 +02:00
cschwinne
72f203e4fa Started optimizing code by converting String to char* 2018-07-20 19:35:31 +02:00
cschwinne
4e3c83af94 Added Blynk support
Fixed AutoRGBW not disabling white slider in UI
Fixed possible UDP buffer out of bounds
2018-07-16 11:50:09 +02:00
Aircoookie
65a0f60257 Merge pull request #27 from Aircoookie/development
Development
2018-06-24 01:38:12 +02:00
cschwinne
094bdf02c4 Release of v0.7.0
Substantial optimizations of mobile UI
Added option to save current preset cycle as boot default
Added option not to use first LED in strip
Realtime UI error now includes source IP address
Removed /down and /cleareeprom pages
Fixed bug (turning receiveDirect off would crash on UDP packet)
2018-06-24 01:20:15 +02:00
cschwinne
5d8d12bc89 First commit to development branch
Added AutoRGBW feature
Nightlight turns off if its target brightness is set
2018-05-31 19:26:16 +02:00
cschwinne
89b9fd8a45 Mobile UI by StormPie added 2018-05-22 21:11:19 +02:00
cschwinne
ce1ba3bc2c Added Hyperion support on UDP port 19446 2018-05-18 23:24:47 +02:00
cschwinne
3afb499930 Changed preset cycle API format
Added secondary color transition
Added option to have UI while receiving realtime
Fixed mDNS not working
Fixed Arduino OTA not working when locked but enabled
2018-05-10 19:55:58 +02:00
cschwinne
356ff57005 Added more usermod functions 2018-04-24 12:03:25 +02:00
cschwinne
16ce67057d Updated version in readme
(I always forget this!)
2018-04-15 18:49:47 +02:00
cschwinne
4c9dc739ae Release of v0.6.4
Added Limited support of up to 1200 (ESP8266) or 600 (ESP32) LEDs
Changed &ND API call to activate Nightight without requiring NL
2018-04-15 15:27:54 +02:00
cschwinne
a665607fac Finished Dynamic LED drivers 2018-04-14 18:56:35 +02:00
cschwinne
7f5671f975 Started with wrapper to support dynamic LED counts and pixel features 2018-04-13 00:28:29 +02:00
cschwinne
ee6676cd89 Release of v0.6.3
Added Preset Cycle feature
Added Transition Time API call
Added Adalight serial ambilight protocol
Added DRGB and DRGBW UDP direct-drive protocols
Improved transition flickering
Easter eggs are eaten now
2018-04-11 23:50:35 +02:00
cschwinne
df05754872 Updated readme 2018-04-01 00:15:14 +02:00
cschwinne
72223c7e42 Release of v0.6.2
Added /easter joke subpage
Added Easter (6) effect
Merged Single and Multi Dynamic (7) effects
Added Easter theme
Added North Korea timezone
2018-04-01 00:08:50 +02:00
209 changed files with 35879 additions and 10518 deletions

20
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
# 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

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
.pio
.pioenvs
.piolibdeps
.vscode
!.vscode/extensions.json
/wled00/Release
/wled00/extLibs
/platformio_override.ini
.DS_Store
.gitignore
.clang-format

43
.travis.yml Normal file
View File

@@ -0,0 +1,43 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#
# * Test the Travis config here:
# < https://config.travis-ci.com/explore >
#
language: python
python:
# - "2.7"
- "3.5"
os: linux
cache:
bundler: true
ccache: true
directories:
- "~/.platformio"
- "~/.buildcache"
env:
- PLATFORMIO_CI_SRC=wled00
install:
- pip install -U platformio
- platformio update
script:
# - platformio ci --project-conf=./platformio.ini
- platformio run

BIN
.vs/wled00/v15/.suo Normal file

Binary file not shown.

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

111
CHANGELOG.md Normal file
View File

@@ -0,0 +1,111 @@
## WLED changelog
### WLED version 0.10.0
#### Build 2005030
- DMX Single RGW and Single DRGB modes now support an additional white channel
- Improved palettes derived from set colors and changed their names
### Development versions between 0.9.1 and 0.10.0 release
#### Build 2005020
- Added ACST and ACST/ACDT timezones
#### Build 2005010
- Added module info page to web UI
- Added realtime override functionality to web UI
- Added individial 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
#### Build 2004300
- Added realtime override option and `lor` JSON property
- Added `lm` (live mode) and `lip` (live IP) properties to info in JSON API
- Added reset commands to APIs
- Added `json/si`, returning state and info, but no FX or Palette lists
- Added rollover detection to millis(). Can track uptimes longer than 49 days
- Attempted to fix Wifi issues with Unifi brand APs
#### Build 2004230
- Added brightness and power for individual segments
- Added `on` and `bri` properties to Segment object in JSON API
- Added `C3` an `SB` commands to HTTP get API
- Merged pull request #865 for 5CH_Shojo_PCB environment
#### Build 2004220
- Added Candle Multi effect
- Added Palette capability to Pacifica effect
#### Build 2004190
- Added TM1814 type LED defines
#### Build 2004120
- Added Art-Net support
- Added OTA platform to platformio.ini
#### Build 2004100
- Fixed DMX output compilation
- Added DMX start LED setting
#### Build 2004061
- Fixed RBG and BGR getPixelColor (#825)
- Improved formatting
#### Build 2004060
- Consolidated global variables in wled.h
#### Build 2003300
- Major change of project structure from .ino to .cpp and func_declare.h
#### Build 2003262
- Fixed compilation for Analog LEDs
- Fixed sync settings network port fields too small
#### Build 2003261
- Fixed live preview not displaying whole light if over 255 LEDs
#### Build 2003251
- Added Pacifica effect (tentative, doesn't yet support other colors)
- Added Atlantica palette
- Fixed ESP32 build of Espalexa
#### Build 2003222
- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5)
#### Build 2003221
- Moved Cronixie driver from FX library to drawOverlay handler
#### Build 2003211
- Added custom mapping compile define to FX_fcn.h
- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first
- Added link to youtube videos by Room31 to readme
#### Build 2003141
- Fixed color of main segment returned in JSON API during transition not being target color (closes #765)
- Fixed arlsLock() being called after pixels set in E1.31 (closes #772)
- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment)
#### Build 2003121
- Created changelog.md - make tracking changes to code easier
- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection

View File

@@ -1,22 +0,0 @@
### Where are the new binaries?
From v0.5.0 on forward, the GitHub [releases](https://github.com/Aircoookie/WLED/releases) system will be used for binaries.
### What binary should I choose?
Currently WLED supports the ESP8266 and a very early, experimental version of ESP32 support.
Be sure to choose the correct binary for your platform and LED type.
- Do you have a standard RGB WS2812B NeoPixel strip?
--> Use wled05dev_XXXXXXX_RGB_PLATFORM.bin
- Do you have an RGBW SK6812 strip (half of the LED is white)?
--> Use wled05dev_XXXXXXX_RGBW_PLATFORM.bin
- Do you have a Cronixie clock set by Diamex?
--> Use wled05dev_XXXXXXX_CRONIXIE_PLATFORM.bin
### What about wled03 and wled04?
These are legacy releases only for the ESP8266. They don't include the latest features and may have unfixed bugs - only use them if the new wled05dev test builds don't work for you!

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

39
include/README Normal file
View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

315
platformio.ini Normal file
View File

@@ -0,0 +1,315 @@
; PlatformIO Project Configuration File
; Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = ./wled00
data_dir = ./wled00/data
lib_dir = ./wled00/src
build_cache_dir = ~/.buildcache
extra_configs =
platformio_override.ini
# ------------------------------------------------------------------------------
# ENVIRONMENTS
#
# Please uncomment one of the lines below to select your board(s)
# ------------------------------------------------------------------------------
# Travis CI binaries (comment this out when building for single board)
default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev
# Release binaries
; default_envs = nodemcuv2, esp01, esp01_1m_ota, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4, custom32_LEDPIN_16
# Single binaries (uncomment your board)
; default_envs = nodemcuv2
; default_envs = esp01
; default_envs = esp01_1m_ota
; 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_4CH_H801
; default_envs = esp8285_5CH_H801
; default_envs = d1_mini_5CH_Shojo_PCB
; default_envs = wemos_shield_esp32
[common]
# ------------------------------------------------------------------------------
# PLATFORM:
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
#
# arduino core 2.3.0 = platformIO 1.5.0
# arduino core 2.4.0 = platformIO 1.6.0
# arduino core 2.4.1 = platformIO 1.7.3
# arduino core 2.4.2 = platformIO 1.8.0
# arduino core 2.5.0 = platformIO 2.0.4
# arduino core 2.5.1 = platformIO 2.1.1
# arduino core 2.5.2 = platformIO 2.2.3
# arduino core 2.6.1 = platformIO 2.3.0
# arduino core 2.6.2 = platformIO 2.3.1
# arduino core 2.6.3 = platformIO 2.3.2
# ------------------------------------------------------------------------------
arduino_core_2_3_0 = espressif8266@1.5.0
arduino_core_2_4_0 = espressif8266@1.6.0
arduino_core_2_4_1 = espressif8266@1.7.3
arduino_core_2_4_2 = espressif8266@1.8.0
arduino_core_2_5_0 = espressif8266@2.0.4
arduino_core_2_5_1 = espressif8266@2.1.1
arduino_core_2_5_2 = espressif8266@2.2.3
arduino_core_2_6_1 = espressif8266@2.3.0
arduino_core_2_6_2 = espressif8266@2.3.1
arduino_core_2_6_3 = espressif8266@2.3.3
# Development platforms
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
platform = ${common.arduino_core_2_4_2}
platform_latest = ${common.arduino_core_2_6_3}
# ------------------------------------------------------------------------------
# FLAGS: DEBUG
#
# ------------------------------------------------------------------------------
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
# ------------------------------------------------------------------------------
# FLAGS: ldscript
# ldscript_512k ( 512 KB) = 487 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved
# ldscript_1m0m (1024 KB) = 999 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved
# ldscript_2m1m (2048 KB) = 1019 KB sketch, 4 KB eeprom, 1004 KB spiffs, 16 KB reserved
# ldscript_4m1m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 1002 KB spiffs, 16 KB reserved, 2048 KB empty/ota?
# ldscript_4m3m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 3040 KB spiffs, 16 KB reserved
#
# Available lwIP variants (macros):
# -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH = v1.4 Higher Bandwidth (default)
# -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY = v2 Lower Memory
# -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH = v2 Higher Bandwidth
#
# BearSSL performance:
# When building with -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL, please add `board_build.f_cpu = 160000000` to the environment configuration
#
# BearSSL ciphers:
# When building on core >= 2.5, you can add the build flag -DBEARSSL_SSL_BASIC in order to build BearSSL with a limited set of ciphers:
# TLS_RSA_WITH_AES_128_CBC_SHA256 / AES128-SHA256
# TLS_RSA_WITH_AES_256_CBC_SHA256 / AES256-SHA256
# TLS_RSA_WITH_AES_128_CBC_SHA / AES128-SHA
# TLS_RSA_WITH_AES_256_CBC_SHA / AES256-SHA
# This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m).
# ------------------------------------------------------------------------------
build_flags = -g -w -DMQTT_MAX_PACKET_SIZE=1024 -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
-DSECURE_CLIENT=SECURE_CLIENT_BEARSSL -DBEARSSL_SSL_BASIC
#build_flags for the IRremoteESP8266 library (enabled decoders have to appear here)
-D _IR_ENABLE_DEFAULT_=false
-D DECODE_HASH=true
-D DECODE_NEC=true
-D DECODE_SONY=true
-D DECODE_SAMSUNG=true
-D DECODE_LG=true
build_flags_esp8266 = ${common.build_flags} -DESP8266
build_flags_esp32 = ${common.build_flags} -DARDUINO_ARCH_ESP32
ldscript_512k = eagle.flash.512k.ld ;for older versions change this to eagle.flash.512k0.ld
ldscript_1m0m = eagle.flash.1m.ld ;for older versions change this to eagle.flash.1m0.ld
ldscript_2m1m = eagle.flash.2m1m.ld
ldscript_4m1m = eagle.flash.4m1m.ld
ldscript_4m3m = eagle.flash.4m3m.ld
shared_libdeps_dir = ./wled00/src
# ------------------------------------------------------------------------------
# COMMON SETTINGS:
# ------------------------------------------------------------------------------
[env]
framework = arduino
board_build.flash_mode = dout
monitor_speed = 115200
upload_speed = 115200
lib_extra_dirs =
${common.shared_libdeps_dir}
# ------------------------------------------------------------------------------
# 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
# ------------------------------------------------------------------------------
lib_compat_mode = strict
lib_deps =
FastLED@3.3.2
NeoPixelBus@2.5.7
ESPAsyncTCP@1.2.0
ESPAsyncUDP@697c75a025
AsyncTCP@1.0.3
Esp Async WebServer@1.2.0
IRremoteESP8266@2.7.3
#For use SSD1306 OLED display uncomment following
#U8g2@~2.27.2
#For Dallas sensor uncomment following 2 lines
#OneWire@~2.3.5
#For BME280 sensor uncomment following
#BME280@~3.0.0
lib_ignore =
AsyncTCP
# ------------------------------------------------------------------------------
# WLED BUILDS
# ------------------------------------------------------------------------------
[env:nodemcuv2]
board = nodemcuv2
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:esp01]
board = esp01
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_512k}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED
[env:esp01_1m_ota]
board = esp01_1m
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED
[env:esp01_1m_full]
board = esp01_1m
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA
[env:esp07]
board = esp07
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:d1_mini]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:heltec_wifi_kit_8]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:h803wf]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
[env:esp32dev]
board = esp32dev
platform = espressif32@1.11.2
build_flags = ${common.build_flags_esp32}
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS
[env:esp8285_4CH_H801]
board = esp8285
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801
[env:esp8285_5CH_H801]
board = esp8285
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 -D WLED_ENABLE_5CH_LEDS
[env:d1_mini_5CH_Shojo_PCB]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D WLED_USE_ANALOG_LEDS -D SHOJO_PCB -D WLED_ENABLE_5CH_LEDS
# ------------------------------------------------------------------------------
# DEVELOPMENT BOARDS
# ------------------------------------------------------------------------------
[env:d1_mini_debug]
board = d1_mini
build_type = debug
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} ${common.debug_flags}
[env:d1_mini_ota]
board = d1_mini
upload_protocol = espota
# exchange for your WLED IP
upload_port = "10.10.1.27"
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
# ------------------------------------------------------------------------------
# custom board configurations
# ------------------------------------------------------------------------------
[env:custom_LEDPIN_4]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=4 -D IRPIN=5
[env:custom_LEDPIN_16]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=16
[env:custom_APA102]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D USE_APA102
[env:custom_WS2801]
board = d1_mini
platform = ${common.platform_latest}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D USE_WS2801
[env:custom32_LEDPIN_16]
board = esp32dev
platform = espressif32@1.11.2
build_flags = ${common.build_flags_esp32} -D LEDPIN=16
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
[env:wemos_shield_esp32]
board = esp32dev
platform = espressif32@1.11.2
upload_port = /dev/cu.SLAB_USBtoUART
monitor_port = /dev/cu.SLAB_USBtoUART
upload_speed = 460800
build_flags = ${common.build_flags_esp32} -D LEDPIN=16 -D RLYPIN=19 -D BTNPIN=17
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP

View File

@@ -0,0 +1,36 @@
# Example PlatformIO Project Configuration Override
# ------------------------------------------------------------------------------
# Copy to platformio_override.ini to activate overrides
# ------------------------------------------------------------------------------
# Please visit documentation: https://docs.platformio.org/page/projectconf.html
[env:esp8266_1m_custom]
board = esp01_1m
platform = ${common.arduino_core_2_4_2}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266}
-D WLED_DISABLE_OTA
-D WLED_DISABLE_ALEXA
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE
-D WLED_DISABLE_HUESYNC
-D WLED_DISABLE_INFRARED
; PIN defines - uncomment and change, if needed:
; -D LEDPIN=2
; -D BTNPIN=0
; -D IR_PIN=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
; to drive analog LED strips (aka 5050), uncomment the following
; PWM pins 5,12,13,15 are used with Magic Home LED Controller (default)
; -D WLED_USE_ANALOG_LEDS
; for the H801 controller (PINs 15,13,12,14 (W2 = 04)) uncomment this
; -D WLED_USE_H801
; for the BW-LT11 controller (PINs 12,4,14,5 ) uncomment this
; -D WLED_USE_BWLT11
; and to enable channel 5 for RGBW-CT led strips this
; -D WLED_USE_5CH_LEDS

View File

@@ -1,50 +1,73 @@
![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/master/wled_logo.png)
[![](https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square)](https://github.com/Aircoookie/WLED/releases)
[![](https://img.shields.io/discourse/topics?colorB=blue&label=forum&server=https%3A%2F%2Fwled.discourse.group%2F&style=flat-square)](https://wled.discourse.group)
[![](https://img.shields.io/discord/473448917040758787.svg?colorB=blue&label=discord&style=flat-square)](https://discord.gg/KuqP7NE)
[![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki)
[![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App)
## Welcome to my project WLED!
WLED is a fast and (relatively) secure implementation of an ESP8266 webserver to control NeoPixel (WS2812B) LEDs!
Now also with experimental ESP32 support.
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
### Features: (V0.6.1)
- RGB, HSB, and brightness sliders
- Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP
- WS2812FX library integrated for over 50 special effects!
- Secondary color support lets you use even more effect combinations
- Alexa smart home device server (including dimming)
- Beta syncronization to Philips hue lights
- Support for RGBW strips
- 25 user presets! Save your favorite colors and effects and apply them easily!
- HTTP request API for simple integration
- Macro functions to automatically execute API calls
- Nightlight function (gradually dims down)
- Notifier function (multiple ESPs sync color via UDP broadcast)
- Support for power pushbutton
- Custom Theater Chase
- Full OTA software update capability (HTTP and ArduinoOTA)
- Password protected OTA page for added security (OTA lock)
- NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex
- Realtime UDP Packet Control (WARLS) possible
- Client HTML UI controlled, customizable themes
### Features:
- WS2812FX library integrated for over 100 special effects
- FastLED noise effects and 50 palettes
- Modern UI with color, effect and segment controls
- Segments to set different effects and colors to parts of the LEDs
- Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP
- Support for RGBW strips
- 16 user presets to save and load colors/effects easily, supports cycling through them.
- Macro functions to automatically execute API calls
- Nightlight function (gradually dims down)
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
- Configurable analog clock + support for the Cronixie kit by Diamex
- Configurable Auto Brightness limit for safer operation
### Supported light control interfaces:
- WLED app for Android and iOS
- JSON and HTTP request APIs
- MQTT
- Blynk IoT
- E1.31
- Hyperion
- UDP realtime
- Alexa voice control (including dimming and color)
- Sync to Philips hue lights
- Adalight (PC ambilight via serial)
- Sync color of multiple WLED devices (UDP notifier)
- Infrared remotes (24-key RGB, receiver required)
- Simple timers/schedules (time from NTP, timezones/DST supported)
### Quick start guide and documentation:
See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
DrZzs has made some excellent video guides:
[Introduction, hardware and installation](https://www.youtube.com/watch?v=tXvtxwK3jRk)
[Settings, tips and tricks](https://www.youtube.com/watch?v=6eCE2BpLaUQ)
If you'd rather read, here is a very [detailed step-by-step beginner tutorial](https://tynick.com/blog/11-03-2019/getting-started-with-wled-on-esp8266/) by tynick!
Russian speakers, check out the videos by Room31:
[WLED Firmware Overview: Interface and Settings](https://youtu.be/h7lKsczEI7E)
[ESP8266 based LED controller for WS2812b strip. WLED Firmware + OpenHAB](https://youtu.be/K4ioTt3XvGc)
### Other
Licensed under the MIT license
Uses libraries:
ESP8266/ESP32 Arduino Core
NeoPixelBus by Makuna
[WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (Aircoookie fork)
Time library
Timezone library by JChristensen
Alexa code based on arduino-esp8266-alexa-multiple-wemo-switch by kakopappa
Uses Linearicons by Perxis! (link in settings page)
Licensed under the MIT license
Credits [here](https://github.com/Aircoookie/WLED/wiki/Contributors-&-About)!
Uses Linearicons by Perxis!
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
Check out the WLED [Discourse forum](https://wled.discourse.group)!
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com), but please only do so if you want to talk to me privately.
If WLED really brightens up your every day, you can [![](https://img.shields.io/badge/send%20me%20a%20small%20gift-paypal-blue.svg?style=flat-square)](https://paypal.me/aircoookie)
*Disclaimer:*
If you are sensitive to photoeleptic seizures it is not recommended that you use this software.
In case you still want to try, don't use strobe, lighting or noise modes or high effect speed settings.
As per the MIT license, i assume no liability for any damage to you or any other person or equipment.

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

View File

@@ -0,0 +1,7 @@
# Enclosure and PCB
## IP67 rated enclosure
![Enclosure](controller.jpg)
## PCB
![PCB](pcb.png)

View File

@@ -0,0 +1,68 @@
# Almost universal controller board for outdoor applications
This usermod is using ideas from @mrVanboy and @400killer
Installation of file: Copy and replace file in wled00 directory.
For BME280 sensor use usermod_bme280.cpp. Copy to wled00 and rename to usermod.cpp
## Project repository
- [Original repository](https://github.com/srg74/Controller-for-WLED-firmware) - Main controller repository
## Features
- SSD1306 128x32 and 128x64 I2C OLED display
- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect)
- Auto display shutoff for saving display lifetime
- Dallas temperature sensor
- Reporting temperature to MQTT broker
## Hardware
![Hardware connection](assets/controller.jpg)
## Functionality checked with
- ESP-07S
- PlatformIO
- SSD1306 128x32 I2C OLED display
- DS18B20 (temperature sensor)
- BME280 (temperature, humidity and pressure sensor)
- KY-022 (infrared receiver)
- Push button (N.O. momentary switch)
For Dallas sensor uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
default_envs = esp07
; default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For Dallas sensor uncomment following 2 lines
DallasTemperature@~3.8.0
OneWire@~2.3.5
...
```
For BME280 sensor uncomment `U8g2@~2.27.3`,`BME280@~3.0.0 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
default_envs = esp07
; default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For BME280 sensor uncomment following
BME280@~3.0.0
...
```

View File

@@ -0,0 +1,209 @@
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
#include <DallasTemperature.h> //Dallastemperature sensor
//The SCL and SDA pins are defined here.
//Lolin32 boards use SCL=5 SDA=4
#define U8X8_PIN_SCL 5
#define U8X8_PIN_SDA 4
// Dallas sensor
OneWire oneWire(13);
DallasTemperature sensor(&oneWire);
long temptimer = millis();
long lastMeasure = 0;
#define Celsius // Show temperature mesaurement in Celcius 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"
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"
//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.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);
u8x8.drawString(0, 0, "Loading...");
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
long lastRedraw = 0;
bool displayTurnedOff = false;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
//----> Dallas temperature sensor MQTT publishing
temptimer = millis();
// Timer to publishe new temperature every 60 seconds
if (temptimer - lastMeasure > 60000)
{
lastMeasure = temptimer;
//Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr)
{
sensor.requestTemperatures();
//Gets prefered temperature scale based on selection in definitions section
#ifdef Celsius
float board_temperature = sensor.getTempCByIndex(0);
#else
float board_temperature = sensor.getTempFByIndex(0);
#endif
//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server.
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/temperature");
mqtt->publish(subuf, 0, true, String(board_temperature).c_str());
}
}
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Turn off display after 3 minutes with no change.
if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) {
u8x8.setPowerSave(1);
displayTurnedOff = true;
}
// Check if values which are shown on display changed from the last time.
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
if (displayTurnedOff)
{
u8x8.setPowerSave(0);
displayTurnedOff = false;
}
lastRedraw = millis();
// Update last known values.
#if defined(ESP8266)
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
#else
knownSsid = WiFi.SSID();
#endif
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// 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
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(knownIp);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}

View File

@@ -0,0 +1,266 @@
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
#include <Wire.h>
#include <BME280I2C.h> //BME280 sensor
void UpdateBME280Data();
#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
#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;
// uint8_t RST_PIN = 16; // Uncoment 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
// 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"
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"
//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"
//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
// BME280 sensor timer
long tempTimer = millis();
long lastMeasure = 0;
float SensorPressure(NAN);
float SensorTemperature(NAN);
float SensorHumidity(NAN);
void userSetup() {
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFlipMode(1);
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);
u8x8.drawString(0, 0, "Loading...");
Wire.begin(SDA_PIN,SCL_PIN);
while(!bme.begin())
{
Serial.println("Could not find BME280I2C sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
long lastRedraw = 0;
bool displayTurnedOff = false;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
// BME280 sensor MQTT publishing
tempTimer = millis();
// Timer to publish new sensor data every 60 seconds
if (tempTimer - lastMeasure > 60000)
{
lastMeasure = tempTimer;
// Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr)
{
UpdateBME280Data();
float board_temperature = SensorTemperature;
float board_pressure = SensorPressure;
float board_humidity = SensorHumidity;
// Create string populated with user defined device topic from the UI, and the read temperature, humidity and pressure. Then publish to MQTT server.
String t = String(mqttDeviceTopic);
t += "/temperature";
mqtt->publish(t.c_str(), 0, true, String(board_temperature).c_str());
String p = String(mqttDeviceTopic);
p += "/pressure";
mqtt->publish(p.c_str(), 0, true, String(board_pressure).c_str());
String h = String(mqttDeviceTopic);
h += "/humidity";
mqtt->publish(h.c_str(), 0, true, String(board_humidity).c_str());
}
}
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Turn off display after 3 minutes with no change.
if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) {
u8x8.setPowerSave(1);
displayTurnedOff = true;
}
// Check if values which are shown on display changed from the last time.
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
if (displayTurnedOff)
{
u8x8.setPowerSave(0);
displayTurnedOff = false;
}
lastRedraw = millis();
// Update last known values.
#if defined(ESP8266)
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
#else
knownSsid = WiFi.SSID();
#endif
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// 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
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(knownIp);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}
void UpdateBME280Data() {
float temp(NAN), hum(NAN), pres(NAN);
#ifdef Celsius
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
#else
BME280::TempUnit tempUnit(BME280::TempUnit_Fahrenheit);
#endif
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
SensorTemperature=temp;
SensorHumidity=hum;
SensorPressure=pres;
}

View File

@@ -0,0 +1,34 @@
# QuinLED Dig Uno board
These files allow WLED 0.9.1 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up.
This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI.
Installation of file: Copy and replace file in wled00 directory
## Project link
* [QuinLED-Dig-Uno](https://quinled.info/2018/09/15/quinled-dig-uno/) - Project link
### Platformio requirements
Uncomment `DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
; default_envs = esp07
default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For Dallas sensor uncomment following 2 lines
DallasTemperature@~3.8.0
OneWire@~2.3.5
...
```

View File

@@ -0,0 +1,54 @@
#include <Arduino.h>
#include "wled.h"
//Intiating code for QuinLED Dig-Uno temp sensor
//Uncomment Celsius if that is your prefered temperature scale
#include <DallasTemperature.h> //Dallastemperature sensor
#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards
OneWire oneWire(18);
#else //ESP8266 boards
OneWire oneWire(14);
#endif
DallasTemperature sensor(&oneWire);
long temptimer = millis();
long lastMeasure = 0;
#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit
void userSetup()
{
// Start the DS18B20 sensor
sensor.begin();
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{
}
void userLoop()
{
temptimer = millis();
// Timer to publishe new temperature every 60 seconds
if (temptimer - lastMeasure > 60000) {
lastMeasure = temptimer;
//Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr){
sensor.requestTemperatures();
//Gets prefered temperature scale based on selection in definitions section
#ifdef Celsius
float board_temperature = sensor.getTempCByIndex(0);
#else
float board_temperature = sensors.getTempFByIndex(0);
#endif
//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server.
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/temperature");
mqtt->publish(subuf, 0, true, String(board_temperature).c_str());
return;}
return;}
return;
}

View File

@@ -0,0 +1,71 @@
# Wemos D1 mini and Wemos32 mini shield
- Installation of file: Copy and replace file in wled00 directory
- For BME280 sensor use usermod_bme280.cpp. Copy to wled00 and rename to usermod.cpp
- Added third choice of controller Heltec WiFi-Kit-8. Totally DIY but with OLED display.
## Project repository
- [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository
- [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki)
- [Precompiled WLED firmware](https://github.com/srg74/WLED-wemos-shield/tree/master/resources/Firmware)
## Features
- SSD1306 128x32 or 128x64 I2C OLED display
- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect)
- Auto display shutoff for saving display lifetime
- Dallas temperature sensor
- Reporting temperature to MQTT broker
- Relay for energy saving
## Hardware
![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg)
## Functionality checked with
- Wemos D1 mini original v3.1 and clones
- Wemos32 mini
- PlatformIO
- SSD1306 128x32 I2C OLED display
- DS18B20 (temperature sensor)
- BME280 (temperature, humidity and pressure sensor)
- Push button (N.O. momentary switch)
### Platformio requirements
For Dallas sensor uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
; default_envs = esp07
default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For Dallas sensor uncomment following 2 lines
DallasTemperature@~3.8.0
OneWire@~2.3.5
...
```
For BME280 sensor uncomment `U8g2@~2.27.3`,`BME280@~3.0.0 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
; default_envs = esp07
default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For BME280 sensor uncomment following
BME280@~3.0.0
...
```

View File

@@ -0,0 +1,246 @@
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
#include <OneWire.h> // Dallas temperature sensor
//Dallas sensor quick reading. Credit to - Author: Peter Scargill, August 17th, 2013
int16_t Dallas(int x, byte start)
{
OneWire DallasSensor(x);
byte i;
byte data[2];
int16_t result;
do
{
DallasSensor.reset();
DallasSensor.write(0xCC);
DallasSensor.write(0xBE);
for ( i = 0; i < 2; i++) data[i] = DallasSensor.read();
result=(data[1]<<8)|data[0];
result>>=4; if (data[1]&128) result|=61440;
if (data[0]&8) ++result;
DallasSensor.reset();
DallasSensor.write(0xCC);
DallasSensor.write(0x44,1);
if (start) delay(1000);
} while (start--);
return result;
}
#ifdef ARDUINO_ARCH_ESP32
uint8_t SCL_PIN = 22;
uint8_t SDA_PIN = 21;
uint8_t DALLAS_PIN =23;
#else
uint8_t SCL_PIN = 5;
uint8_t SDA_PIN = 4;
uint8_t DALLAS_PIN =13;
// uint8_t RST_PIN = 16; // Uncoment 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
// Dallas sensor reading timer
long temptimer = millis();
long lastMeasure = 0;
#define Celsius // Show temperature mesaurement in Celcius 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"
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"
//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"
//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
void userSetup() {
//Serial.begin(115200);
Dallas (DALLAS_PIN,1);
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFlipMode(1);
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);
u8x8.drawString(0, 0, "Loading...");
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
long lastRedraw = 0;
bool displayTurnedOff = false;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
//----> Dallas temperature sensor MQTT publishing
temptimer = millis();
// Timer to publishe new temperature every 60 seconds
if (temptimer - lastMeasure > 60000)
{
lastMeasure = temptimer;
//Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr)
{
// Serial.println(Dallas(DALLAS_PIN,0));
//Gets prefered temperature scale based on selection in definitions section
#ifdef Celsius
int16_t board_temperature = Dallas(DALLAS_PIN,0);
#else
int16_t board_temperature = (Dallas(DALLAS_PIN,0)* 1.8 + 32);
#endif
//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server.
String t = String(mqttDeviceTopic);
t += "/temperature";
mqtt->publish(t.c_str(), 0, true, String(board_temperature).c_str());
}
}
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Turn off display after 3 minutes with no change.
if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) {
u8x8.setPowerSave(1);
displayTurnedOff = true;
}
// Check if values which are shown on display changed from the last time.
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
if (displayTurnedOff)
{
u8x8.setPowerSave(0);
displayTurnedOff = false;
}
lastRedraw = millis();
// Update last known values.
#ifdef ARDUINO_ARCH_ESP32
knownSsid = WiFi.SSID();
#else
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
#endif
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// 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
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(knownIp);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}

View File

@@ -0,0 +1,268 @@
#include "wled.h"
#include <Arduino.h>
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
#include <Wire.h>
#include <BME280I2C.h> //BME280 sensor
void UpdateBME280Data();
#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
#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;
// uint8_t RST_PIN = 16; // Uncoment 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
// 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"
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"
//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"
//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
// BME280 sensor timer
long tempTimer = millis();
long lastMeasure = 0;
float SensorPressure(NAN);
float SensorTemperature(NAN);
float SensorHumidity(NAN);
void userSetup() {
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFlipMode(1);
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);
u8x8.drawString(0, 0, "Loading...");
Wire.begin(SDA_PIN,SCL_PIN);
while(!bme.begin())
{
Serial.println("Could not find BME280I2C sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
long lastRedraw = 0;
bool displayTurnedOff = false;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
// BME280 sensor MQTT publishing
tempTimer = millis();
// Timer to publish new sensor data every 60 seconds
if (tempTimer - lastMeasure > 60000)
{
lastMeasure = tempTimer;
// Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr)
{
UpdateBME280Data();
float board_temperature = SensorTemperature;
float board_pressure = SensorPressure;
float board_humidity = SensorHumidity;
// Create string populated with user defined device topic from the UI, and the read temperature, humidity and pressure. Then publish to MQTT server.
String t = String(mqttDeviceTopic);
t += "/temperature";
mqtt->publish(t.c_str(), 0, true, String(board_temperature).c_str());
String p = String(mqttDeviceTopic);
p += "/pressure";
mqtt->publish(p.c_str(), 0, true, String(board_pressure).c_str());
String h = String(mqttDeviceTopic);
h += "/humidity";
mqtt->publish(h.c_str(), 0, true, String(board_humidity).c_str());
}
}
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Turn off display after 3 minutes with no change.
if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) {
u8x8.setPowerSave(1);
displayTurnedOff = true;
}
// Check if values which are shown on display changed from the last time.
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
if (displayTurnedOff)
{
u8x8.setPowerSave(0);
displayTurnedOff = false;
}
lastRedraw = millis();
// Update last known values.
#if defined(ESP8266)
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
#else
knownSsid = WiFi.SSID();
#endif
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// 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
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(knownIp);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}
void UpdateBME280Data() {
float temp(NAN), hum(NAN), pres(NAN);
#ifdef Celsius
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
#else
BME280::TempUnit tempUnit(BME280::TempUnit_Fahrenheit);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
#endif
SensorTemperature=temp;
SensorHumidity=hum;
SensorPressure=pres;
}

View File

@@ -0,0 +1,12 @@
# Battery powered controller with keypad
I'm using this controller for a festival totem. Runs on 3 18650 Cells, can deliver >5A current.
Via keypad one can select 8 presets, change effect, effect speed, effect intensity and palette. Brightness can be
adjusted with a potentiometer.
## Pictures
![bat-key-ctrl-1](assets/bat-key-ctrl-1.jpg)
![bat-key-ctrl-2](assets/bat-key-ctrl-2.jpg)
![bat-key-ctrl-3](assets/bat-key-ctrl-3.jpg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

View File

@@ -0,0 +1,151 @@
/*
* WLED usermod for keypad and brightness-pot.
* 3'2020 https://github.com/hobbyquaker
*/
#include <Keypad.h>
const byte keypad_rows = 4;
const byte keypad_cols = 4;
char keypad_keys[keypad_rows][keypad_cols] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte keypad_colPins[keypad_rows] = {D3, D2, D1, D0};
byte keypad_rowPins[keypad_cols] = {D7, D6, D5, D4};
Keypad myKeypad = Keypad(makeKeymap(keypad_keys), keypad_rowPins, keypad_colPins, keypad_rows, keypad_cols);
void userSetup()
{
}
void userConnected()
{
}
long lastTime = 0;
int delayMs = 20; //we want to do something every 2 seconds
void userLoop()
{
if (millis()-lastTime > delayMs)
{
long analog = analogRead(0);
int new_bri = 1;
if (analog > 900) {
new_bri = 255;
} else if (analog > 30) {
new_bri = dim8_video(map(analog, 31, 900, 16, 255));
}
if (bri != new_bri) {
bri = new_bri;
colorUpdated(1);
}
char myKey = myKeypad.getKey();
if (myKey != NULL) {
switch (myKey) {
case '1':
applyPreset(1);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '2':
applyPreset(2);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '3':
applyPreset(3);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '4':
applyPreset(4);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '5':
applyPreset(5);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '6':
applyPreset(6);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case 'A':
applyPreset(7);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case 'B':
applyPreset(8);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '7':
effectCurrent += 1;
if (effectCurrent >= MODE_COUNT) effectCurrent = 0;
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '*':
effectCurrent -= 1;
if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1);
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '8':
if (effectSpeed < 240) {
effectSpeed += 12;
} else if (effectSpeed < 255) {
effectSpeed += 1;
}
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '0':
if (effectSpeed > 15) {
effectSpeed -= 12;
} else if (effectSpeed > 0) {
effectSpeed -= 1;
}
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '9':
if (effectIntensity < 240) {
effectIntensity += 12;
} else if (effectIntensity < 255) {
effectIntensity += 1;
}
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case '#':
if (effectIntensity > 15) {
effectIntensity -= 12;
} else if (effectIntensity > 0) {
effectIntensity -= 1;
}
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case 'C':
effectPalette += 1;
if (effectPalette >= 50) effectPalette = 0;
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
case 'D':
effectPalette -= 1;
if (effectPalette <= 0) effectPalette = 50;
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
break;
}
}
lastTime = millis();
}
}

View File

@@ -0,0 +1,28 @@
# Blynk controllable relay
This usermod allows controlling a relay state from the user variables. It also allows the user variables to be set over Blynk.
Optionally, the servo can have a reset timer to go back to it's default state after an interval. This interval is set through userVar1.
## Instalation
Replace the WLED06_usermod.ino file in Aircoookies WLED folder with the one here.
## Customizations
Update the following parameters in WLED06_usermod.ino to configure the mod's behavior:
```cpp
//Which pin is the relay connected to
#define RELAY_PIN 5
//Which pin state should the relay default to
#define RELAY_PIN_DEFAULT LOW
//If >0 The controller returns to RELAY_PIN_DEFAULT after this time in milliseconds
#define RELAY_PIN_TIMER_DEFAULT 3000
//Blynk virtual pin for controlling relay
#define BLYNK_USER_VAR0_PIN V9
//Blynk virtual pin for controlling relay timer
#define BLYNK_USER_VAR1_PIN V10
//Number of milliseconds between updating blynk
#define BLYNK_RELAY_UPDATE_INTERVAL 5000
```

View File

@@ -0,0 +1,96 @@
/*
* 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 wled_eeprom.h)
* bytes 2400+ are currently ununsed, but might be used for future wled features
*/
//Use userVar0 (API calls &U0=, uint16_t) to set relay state
#define relayPinState userVar0
//Use userVar1 (API calls &U1=, uint16_t) to set relay timer duration
//Ignored if 0, otherwise number of milliseconds to allow relay to stay in
//non default state.
#define relayTimerInterval userVar1
//Which pin is the relay connected to
#define RELAY_PIN 5
//Which pin state should the relay default to
#define RELAY_PIN_DEFAULT LOW
//If >0 The controller returns to RELAY_PIN_DEFAULT after this time in milliseconds
#define RELAY_PIN_TIMER_DEFAULT 3000
//Blynk virtual pin for controlling relay
#define BLYNK_USER_VAR0_PIN V9
//Blynk virtual pin for controlling relay timer
#define BLYNK_USER_VAR1_PIN V10
//Number of milliseconds between updating blynk
#define BLYNK_RELAY_UPDATE_INTERVAL 5000
//Is the timer for resetting the relay active
bool relayTimerStarted = false;
//millis() time after which relay will be reset
unsigned long relayTimeToDefault = 0;
//millis() time after which relay vars in Blynk will be sent
unsigned long relayBlynkUpdateTime = 0;
//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup()
{
relayPinState = RELAY_PIN_DEFAULT;
relayTimerInterval = RELAY_PIN_TIMER_DEFAULT;
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, relayPinState);
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{
}
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop()
{
//Normalize relayPinState to an accepted value
if (relayPinState != HIGH && relayPinState != LOW) {
relayPinState = RELAY_PIN_DEFAULT;
}
//If relay changes and relayTimerInterval is set, start a timer to change back
if (relayTimerInterval != 0 &&
relayPinState != RELAY_PIN_DEFAULT &&
!relayTimerStarted ) {
relayTimerStarted = true;
relayTimeToDefault = millis() + relayTimerInterval;
}
//If manually changed back to default, cancel timer
if (relayTimerStarted && relayPinState == RELAY_PIN_DEFAULT ) {
relayTimerStarted = false;
}
//If timer completes, set relay back to default
if (relayTimerStarted && millis() > relayTimeToDefault) {
relayPinState = RELAY_PIN_DEFAULT;
relayTimerStarted = false;
}
digitalWrite(RELAY_PIN, relayPinState);
updateRelayBlynk();
}
//Update Blynk with state of userVars at BLYNK_RELAY_UPDATE_INTERVAL
void updateRelayBlynk()
{
if (!WLED_CONNECTED) return;
if (relayBlynkUpdateTime > millis()) return;
Blynk.virtualWrite(BLYNK_USER_VAR0_PIN, userVar0);
Blynk.virtualWrite(BLYNK_USER_VAR1_PIN, userVar1);
relayBlynkUpdateTime = millis() + BLYNK_RELAY_UPDATE_INTERVAL;
}
//Add Blynk callback for setting userVar0
BLYNK_WRITE(BLYNK_USER_VAR0_PIN)
{
userVar0 = param.asInt();
}
//Add Blynk callback for setting userVar1
BLYNK_WRITE(BLYNK_USER_VAR1_PIN)
{
userVar1 = param.asInt();
}

View File

@@ -0,0 +1,23 @@
### Shift Light for Project Cars
Turn your WLED lights into a rev light and shift indicator for Project Cars.
It is pretty straight forward to use.
1. Make sure, your WLED device and your PC/console are on the same network and can talk to each other
2. Go to the gameplay settings menu in PCARS and enable UDP. There are 9 numbers you can choose from. This is the refresh rate. The lower the number, the better. But you might run into problems at faster rates.
| Number | Updates/Second |
| ------ | -------------- |
| 1 | 60 |
| 2 | 50 |
| 3 | 40 |
| 4 | 30 |
| 5 | 20 |
| 6 | 15 |
| 7 | 10 |
| 8 | 05 |
| 9 | 1 |
3. once you enter a race, WLED should automatically shift to PCARS mode. Done.

View File

@@ -0,0 +1,96 @@
/*
* Car rev display and shift indicator for Project Cars
*
* This works via the UDP telemetry function. You'll need to enable it in the settings of the game.
* I've had good results with settings around 5 (20 fps).
*
*/
const uint8_t PCARS_dimcolor = 20;
WiFiUDP UDP;
const unsigned int PCARS_localUdpPort = 5606; // local port to listen on
char PCARS_packet[2048];
char PCARS_tempChar[2]; // Temporary array for u16 conversion
u16 PCARS_RPM;
u16 PCARS_maxRPM;
long PCARS_lastRead = millis() - 2001;
float PCARS_rpmRatio;
void userSetup()
{
UDP.begin(PCARS_localUdpPort);
}
void userConnected()
{
// new wifi, who dis?
}
void userLoop()
{
PCARS_readValues();
if (PCARS_lastRead > millis() - 2000) {
PCARS_buildcolorbars();
}
}
void PCARS_readValues() {
int PCARS_packetSize = UDP.parsePacket();
if (PCARS_packetSize) {
int len = UDP.read(PCARS_packet, PCARS_packetSize);
if (len > 0) {
PCARS_packet[len] = 0;
}
if (len == 1367) { // Telemetry packet. Ignoring everything else.
PCARS_lastRead = millis();
arlsLock(realtimeTimeoutMs, REALTIME_MODE_GENERIC);
// current RPM
memcpy(&PCARS_tempChar, &PCARS_packet[124], 2);
PCARS_RPM = (PCARS_tempChar[1] << 8) + PCARS_tempChar[0];
// max RPM
memcpy(&PCARS_tempChar, &PCARS_packet[126], 2);
PCARS_maxRPM = (PCARS_tempChar[1] << 8) + PCARS_tempChar[0];
if (PCARS_maxRPM) {
PCARS_rpmRatio = constrain((float)PCARS_RPM / (float)PCARS_maxRPM, 0, 1);
} else {
PCARS_rpmRatio = 0.0;
}
}
}
}
void PCARS_buildcolorbars() {
boolean activated = false;
float ledratio = 0;
for (uint16_t i = 0; i < ledCount; i++) {
if (PCARS_rpmRatio < .95 || (millis() % 100 > 70 )) {
ledratio = (float)i / (float)ledCount;
if (ledratio < PCARS_rpmRatio) {
activated = true;
} else {
activated = false;
}
if (ledratio > 0.66) {
setRealtimePixel(i, 0, 0, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0);
} else if (ledratio > 0.33) {
setRealtimePixel(i, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0, 0, 0);
} else {
setRealtimePixel(i, 0, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0, 0);
}
}
else {
setRealtimePixel(i, 0, 0, 0, 0);
}
}
colorUpdated(5);
strip.show();
}

18
usermods/readme.md Normal file
View File

@@ -0,0 +1,18 @@
### Usermods
This folder serves as a repository for usermods (custom `usermod.cpp` files)!
If you have created an usermod that you believe is useful (for example to support a particular sensor, display, feature...), feel free to contribute by opening a pull request!
In order for other people to be able to have fun with your usermod, please keep these points in mind:
- Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`)
- Include your custom `usermod.cpp` file
- If your usermod requires changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod
- Create a pull request!
- If your feature is useful for the majority of WLED users, I will consider adding it to the base code!
While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break.
I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod.
Thank you for your help :)

View File

@@ -0,0 +1,62 @@
#include "wled.h"
/*
* 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
*/
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
/*
** Rotary Encoder Example
** Use the Sparkfun Rotary Encoder to vary brightness of LED
**
** Sample the encoder at 500Hz using the millis() function
*/
int fadeAmount = 5; // how many points to fade the Neopixel with each step
unsigned long currentTime;
unsigned long loopTime;
const int pinA = D6; // DT from encoder
const int pinB = D7; // CLK from encoder
unsigned char Enc_A;
unsigned char Enc_B;
unsigned char Enc_A_prev = 0;
//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
currentTime = millis();
loopTime = currentTime;
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected() {
}
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop() {
currentTime = millis(); // get the current elapsed time
if(currentTime >= (loopTime + 2)) // 2ms since last check of encoder = 500Hz
{
int Enc_A = digitalRead(pinA); // Read encoder pins
int Enc_B = digitalRead(pinB);
if((! Enc_A) && (Enc_A_prev)) { // A has gone from high to low
if(Enc_B == HIGH) { // B is high so clockwise
if(bri + fadeAmount <= 255) bri += fadeAmount; // increase the brightness, dont go over 255
} else if (Enc_B == LOW) { // B is low so counter-clockwise
if(bri - fadeAmount >= 0) bri -= fadeAmount; // decrease the brightness, dont go below 0
}
}
Enc_A_prev = Enc_A; // Store value of A for next time
loopTime = currentTime; // Updates loopTime
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
colorUpdated(6);
}
}

View File

@@ -0,0 +1,45 @@
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
long lastTime = 0;
int delayMs = 10;
const int pinA = D6; //data
const int pinB = D7; //clk
int oldA = LOW;
//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected() {
}
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop() {
if (millis()-lastTime > delayMs) {
int A = digitalRead(pinA);
int B = digitalRead(pinB);
if (oldA == LOW && A == HIGH) {
if (oldB == HIGH) {
// bri += 10;
// if (bri > 250) bri = 10;
effectCurrent += 1;
if (effectCurrent >= MODE_COUNT) effectCurrent = 0;
}
else {
// bri -= 10;
// if (bri < 10) bri = 250;
effectCurrent -= 1;
if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1);
}
oldA = A;
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED);
lastTime = millis();
}
}

View File

@@ -0,0 +1,35 @@
# SSD1306 128x32 OLED via I2C with u8g2
This usermod allows to connect 128x32 Oled display to WLED controlled and show
the next information:
- Current SSID
- IP address if obtained
* in AP mode and turned off lightning AP password is shown
- Current effect
- Current palette
- On/Off icon (sun/moon)
## Hardware
![Hardware connection](assets/hw_connection.png)
## Requirements
Functionality checked with:
- commit 095429a7df4f9e2b34dd464f7bbfd068df6558eb
- Wemos d1 mini
- PlatformIO
- Generic SSD1306 128x32 I2C OLED display from aliexpress
### Platformio
Add `U8g2@~2.27.2` dependency to `lib_deps_external` under `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[common]
...
lib_deps_external =
...
U8g2@~2.27.2
...
```
### Arduino IDE
Install library `U8g2 by oliver` in `Tools | Include Library | Manage libraries` menu.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,175 @@
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
//The SCL and SDA pins are defined here.
//Lolin32 boards use SCL=5 SDA=4
#define U8X8_PIN_SCL 5
#define U8X8_PIN_SDA 4
// 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
U8X8_SSD1306_128X32_UNIVISION_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() {
u8x8.begin();
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);
u8x8.drawString(0, 0, "Loading...");
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
long lastRedraw = 0;
bool displayTurnedOff = false;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Turn off display after 3 minutes with no change.
if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) {
u8x8.setPowerSave(1);
displayTurnedOff = true;
}
// Check if values which are shown on display changed from the last time.
if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
if (displayTurnedOff)
{
u8x8.setPowerSave(0);
displayTurnedOff = false;
}
lastRedraw = millis();
// Update last known values.
#if defined(ESP8266)
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
#else
knownSsid = WiFi.SSID();
#endif
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// 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
if (knownSsid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(knownIp);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}

View File

@@ -0,0 +1,14 @@
### Stairway lighting
Quick usermod to accomplish something similar to [this video](https://www.youtube.com/watch?v=NHkju5ncC4A).
This usermod allows you to add a lightstrip alongside or on the steps of a staircase.
When the `userVar0` variable is set, the LEDs will gradually turn on in a Wipe effect.
Both directions are supported by setting userVar0 to 1 and 2, respectively (HTTP API commands `U0=1` and `U0=2`).
After the Wipe is complete, the light will either stay on (Solid effect) indefinitely or after `userVar1` seconds have elapsed.
If userVar0 is updated (e.g. by triggering a second sensor) the light will slowly fade off.
This could be extended to also run a Wipe effect in reverse order to turn the LEDs back off.
This is just a basic version to accomplish this using HTTP API calls `U0` and `U1` and/or macros.
It should be easy to adapt this code however to interface with motion sensors or other input devices.

View File

@@ -0,0 +1,111 @@
/*
* 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 wled_eeprom.h)
* bytes 2400+ are currently ununsed, but might be used for future wled features
*/
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
byte wipeState = 0; //0: inactive 1: wiping 2: solid
unsigned long timeStaticStart = 0;
uint16_t previousUserVar0 = 0;
//comment this out if you want the turn off effect to be just fading out instead of reverse wipe
#define STAIRCASE_WIPE_OFF
//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup()
{
//setup PIR sensor here, if needed
}
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{
}
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop()
{
//userVar0 (U0 in HTTP API):
//has to be set to 1 if movement is detected on the PIR that is the same side of the staircase as the ESP8266
//has to be set to 2 if movement is detected on the PIR that is the opposite side
//can be set to 0 if no movement is detected. Otherwise LEDs will turn off after a configurable timeout (userVar1 seconds)
if (userVar0 > 0)
{
if ((previousUserVar0 == 1 && userVar0 == 2) || (previousUserVar0 == 2 && userVar0 == 1)) wipeState = 3; //turn off if other PIR triggered
previousUserVar0 = userVar0;
if (wipeState == 0) {
startWipe();
wipeState = 1;
} else if (wipeState == 1) { //wiping
uint32_t cycleTime = 360 + (255 - effectSpeed)*75; //this is how long one wipe takes (minus 25 ms to make sure we switch in time)
if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete
effectCurrent = FX_MODE_STATIC;
timeStaticStart = millis();
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
wipeState = 2;
}
} else if (wipeState == 2) { //static
if (userVar1 > 0) //if U1 is not set, the light will stay on until second PIR or external command is triggered
{
if (millis() - timeStaticStart > userVar1*1000) wipeState = 3;
}
} else if (wipeState == 3) { //switch to wipe off
#ifdef STAIRCASE_WIPE_OFF
effectCurrent = FX_MODE_COLOR_WIPE;
strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
wipeState = 4;
#else
turnOff();
#endif
} else { //wiping off
if (millis() + strip.timebase > (725 + (255 - effectSpeed)*150)) turnOff(); //wipe complete
}
} else {
wipeState = 0; //reset for next time
if (previousUserVar0) {
#ifdef STAIRCASE_WIPE_OFF
userVar0 = previousUserVar0;
wipeState = 3;
#else
turnOff();
#endif
}
previousUserVar0 = 0;
}
}
void startWipe()
{
bri = briLast; //turn on
transitionDelayTemp = 0; //no transition
effectCurrent = FX_MODE_COLOR_WIPE;
resetTimebase(); //make sure wipe starts from beginning
//set wipe direction
WS2812FX::Segment& seg = strip.getSegment(0);
bool doReverse = (userVar0 == 2);
seg.setOption(1, doReverse);
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
}
void turnOff()
{
#ifdef STAIRCASE_WIPE_OFF
transitionDelayTemp = 0; //turn off immediately after wipe completed
#else
transitionDelayTemp = 4000; //fade out slowly
#endif
bri = 0;
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION);
wipeState = 0;
userVar0 = 0;
previousUserVar0 = 0;
}

25
wled00.sln Normal file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2046
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wled00", "wled00\wled00.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9A679C2B-61D3-400B-B96F-06E604E9CED2}
EndGlobalSection
EndGlobal

BIN
wled00/.vs/wled00/v15/.suo Normal file

Binary file not shown.

3324
wled00/FX.cpp Normal file

File diff suppressed because it is too large Load Diff

683
wled00/FX.h Normal file
View File

@@ -0,0 +1,683 @@
/*
WS2812FX.h - Library for WS2812 LED effects.
Harm Aldick - 2016
www.aldick.org
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Harm Aldick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Modified for WLED
*/
#ifndef WS2812FX_h
#define WS2812FX_h
#include "NpbWrapper.h"
#include "const.h"
#define FASTLED_INTERNAL //remove annoying pragma messages
#include "FastLED.h"
#define DEFAULT_BRIGHTNESS (uint8_t)127
#define DEFAULT_MODE (uint8_t)0
#define DEFAULT_SPEED (uint8_t)128
#define DEFAULT_COLOR (uint32_t)0xFFAA00
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
/* Not used in all effects yet */
#define WLED_FPS 42
#define FRAMETIME (1000/WLED_FPS)
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#define MAX_NUM_SEGMENTS 10
/* How much data bytes all segments combined may allocate */
#ifdef ESP8266
#define MAX_SEGMENT_DATA 2048
#else
#define MAX_SEGMENT_DATA 8192
#endif
#define LED_SKIP_AMOUNT 1
#define MIN_SHOW_DELAY 15
#define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index]
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
#define SEGENV _segment_runtimes[_segment_index]
#define SEGLEN _virtualSegmentLength
#define SEGACT SEGMENT.stop
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
// some common colors
#define RED (uint32_t)0xFF0000
#define GREEN (uint32_t)0x00FF00
#define BLUE (uint32_t)0x0000FF
#define WHITE (uint32_t)0xFFFFFF
#define BLACK (uint32_t)0x000000
#define YELLOW (uint32_t)0xFFFF00
#define CYAN (uint32_t)0x00FFFF
#define MAGENTA (uint32_t)0xFF00FF
#define PURPLE (uint32_t)0x400080
#define ORANGE (uint32_t)0xFF3000
#define PINK (uint32_t)0xFF1493
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
// options
// bit 7: segment is in transition mode
// bits 3-6: TBD
// bit 2: segment is on
// bit 1: reverse segment
// bit 0: segment is selected
#define NO_OPTIONS (uint8_t)0x00
#define TRANSITIONAL (uint8_t)0x80
#define SEGMENT_ON (uint8_t)0x04
#define REVERSE (uint8_t)0x02
#define SELECTED (uint8_t)0x01
#define IS_TRANSITIONAL ((SEGMENT.options & TRANSITIONAL) == TRANSITIONAL)
#define IS_SEGMENT_ON ((SEGMENT.options & SEGMENT_ON ) == SEGMENT_ON )
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
#define MODE_COUNT 103
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
#define FX_MODE_BREATH 2
#define FX_MODE_COLOR_WIPE 3
#define FX_MODE_COLOR_WIPE_RANDOM 4
#define FX_MODE_RANDOM_COLOR 5
#define FX_MODE_COLOR_SWEEP 6
#define FX_MODE_DYNAMIC 7
#define FX_MODE_RAINBOW 8
#define FX_MODE_RAINBOW_CYCLE 9
#define FX_MODE_SCAN 10
#define FX_MODE_DUAL_SCAN 11
#define FX_MODE_FADE 12
#define FX_MODE_THEATER_CHASE 13
#define FX_MODE_THEATER_CHASE_RAINBOW 14
#define FX_MODE_RUNNING_LIGHTS 15
#define FX_MODE_SAW 16
#define FX_MODE_TWINKLE 17
#define FX_MODE_DISSOLVE 18
#define FX_MODE_DISSOLVE_RANDOM 19
#define FX_MODE_SPARKLE 20
#define FX_MODE_FLASH_SPARKLE 21
#define FX_MODE_HYPER_SPARKLE 22
#define FX_MODE_STROBE 23
#define FX_MODE_STROBE_RAINBOW 24
#define FX_MODE_MULTI_STROBE 25
#define FX_MODE_BLINK_RAINBOW 26
#define FX_MODE_ANDROID 27
#define FX_MODE_CHASE_COLOR 28
#define FX_MODE_CHASE_RANDOM 29
#define FX_MODE_CHASE_RAINBOW 30
#define FX_MODE_CHASE_FLASH 31
#define FX_MODE_CHASE_FLASH_RANDOM 32
#define FX_MODE_CHASE_RAINBOW_WHITE 33
#define FX_MODE_COLORFUL 34
#define FX_MODE_TRAFFIC_LIGHT 35
#define FX_MODE_COLOR_SWEEP_RANDOM 36
#define FX_MODE_RUNNING_COLOR 37
#define FX_MODE_RUNNING_RED_BLUE 38
#define FX_MODE_RUNNING_RANDOM 39
#define FX_MODE_LARSON_SCANNER 40
#define FX_MODE_COMET 41
#define FX_MODE_FIREWORKS 42
#define FX_MODE_RAIN 43
#define FX_MODE_MERRY_CHRISTMAS 44
#define FX_MODE_FIRE_FLICKER 45
#define FX_MODE_GRADIENT 46
#define FX_MODE_LOADING 47
#define FX_MODE_POLICE 48
#define FX_MODE_POLICE_ALL 49
#define FX_MODE_TWO_DOTS 50
#define FX_MODE_TWO_AREAS 51
#define FX_MODE_CIRCUS_COMBUSTUS 52
#define FX_MODE_HALLOWEEN 53
#define FX_MODE_TRICOLOR_CHASE 54
#define FX_MODE_TRICOLOR_WIPE 55
#define FX_MODE_TRICOLOR_FADE 56
#define FX_MODE_LIGHTNING 57
#define FX_MODE_ICU 58
#define FX_MODE_MULTI_COMET 59
#define FX_MODE_DUAL_LARSON_SCANNER 60
#define FX_MODE_RANDOM_CHASE 61
#define FX_MODE_OSCILLATE 62
#define FX_MODE_PRIDE_2015 63
#define FX_MODE_JUGGLE 64
#define FX_MODE_PALETTE 65
#define FX_MODE_FIRE_2012 66
#define FX_MODE_COLORWAVES 67
#define FX_MODE_BPM 68
#define FX_MODE_FILLNOISE8 69
#define FX_MODE_NOISE16_1 70
#define FX_MODE_NOISE16_2 71
#define FX_MODE_NOISE16_3 72
#define FX_MODE_NOISE16_4 73
#define FX_MODE_COLORTWINKLE 74
#define FX_MODE_LAKE 75
#define FX_MODE_METEOR 76
#define FX_MODE_METEOR_SMOOTH 77
#define FX_MODE_RAILWAY 78
#define FX_MODE_RIPPLE 79
#define FX_MODE_TWINKLEFOX 80
#define FX_MODE_TWINKLECAT 81
#define FX_MODE_HALLOWEEN_EYES 82
#define FX_MODE_STATIC_PATTERN 83
#define FX_MODE_TRI_STATIC_PATTERN 84
#define FX_MODE_SPOTS 85
#define FX_MODE_SPOTS_FADE 86
#define FX_MODE_GLITTER 87
#define FX_MODE_CANDLE 88
#define FX_MODE_STARBURST 89
#define FX_MODE_EXPLODING_FIREWORKS 90
#define FX_MODE_BOUNCINGBALLS 91
#define FX_MODE_SINELON 92
#define FX_MODE_SINELON_DUAL 93
#define FX_MODE_SINELON_RAINBOW 94
#define FX_MODE_POPCORN 95
#define FX_MODE_DRIP 96
#define FX_MODE_PLASMA 97
#define FX_MODE_PERCENT 98
#define FX_MODE_RIPPLE_RAINBOW 99
#define FX_MODE_HEARTBEAT 100
#define FX_MODE_PACIFICA 101
#define FX_MODE_CANDLE_MULTI 102
class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void);
// pre show callback
typedef void (*show_callback) (void);
// segment parameters
public:
typedef struct Segment { // 24 bytes
uint16_t start;
uint16_t stop; //segment invalid if stop == 0
uint8_t speed;
uint8_t intensity;
uint8_t palette;
uint8_t mode;
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
uint8_t grouping, spacing;
uint8_t opacity;
uint32_t colors[NUM_COLORS];
void setOption(uint8_t n, bool val)
{
if (val) {
options |= 0x01 << n;
} else
{
options &= ~(0x01 << n);
}
}
bool getOption(uint8_t n)
{
return ((options >> n) & 0x01);
}
bool isSelected()
{
return getOption(0);
}
bool isActive()
{
return stop > start;
}
uint16_t length()
{
return stop - start;
}
uint16_t groupLength()
{
return grouping + spacing;
}
uint16_t virtualLength()
{
uint16_t groupLen = groupLength();
return (length() + groupLen -1) / groupLen;
}
} segment;
// segment runtime parameters
typedef struct Segment_runtime { // 28 bytes
unsigned long next_time;
uint32_t step;
uint32_t call;
uint16_t aux0;
uint16_t aux1;
byte* data = nullptr;
bool allocateData(uint16_t len){
if (data && _dataLen == len) return true; //already allocated
deallocateData();
if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
data = new (std::nothrow) byte[len];
if (!data) return false; //allocation failed
WS2812FX::_usedSegmentData += len;
_dataLen = len;
memset(data, 0, len);
return true;
}
void deallocateData(){
delete[] data;
data = nullptr;
WS2812FX::_usedSegmentData -= _dataLen;
_dataLen = 0;
}
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
private:
uint16_t _dataLen = 0;
} segment_runtime;
WS2812FX() {
//assign each member of the _mode[] array to its respective function reference
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
_mode[FX_MODE_COLOR_SWEEP] = &WS2812FX::mode_color_sweep;
_mode[FX_MODE_DYNAMIC] = &WS2812FX::mode_dynamic;
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
_mode[FX_MODE_SAW] = &WS2812FX::mode_saw;
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
_mode[FX_MODE_DISSOLVE] = &WS2812FX::mode_dissolve;
_mode[FX_MODE_DISSOLVE_RANDOM] = &WS2812FX::mode_dissolve_random;
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
_mode[FX_MODE_ANDROID] = &WS2812FX::mode_android;
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
_mode[FX_MODE_COLORFUL] = &WS2812FX::mode_colorful;
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
_mode[FX_MODE_RAIN] = &WS2812FX::mode_rain;
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
_mode[FX_MODE_POLICE] = &WS2812FX::mode_police;
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
_mode[FX_MODE_TRICOLOR_WIPE] = &WS2812FX::mode_tricolor_wipe;
_mode[FX_MODE_TRICOLOR_FADE] = &WS2812FX::mode_tricolor_fade;
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
_mode[FX_MODE_LIGHTNING] = &WS2812FX::mode_lightning;
_mode[FX_MODE_ICU] = &WS2812FX::mode_icu;
_mode[FX_MODE_MULTI_COMET] = &WS2812FX::mode_multi_comet;
_mode[FX_MODE_DUAL_LARSON_SCANNER] = &WS2812FX::mode_dual_larson_scanner;
_mode[FX_MODE_RANDOM_CHASE] = &WS2812FX::mode_random_chase;
_mode[FX_MODE_OSCILLATE] = &WS2812FX::mode_oscillate;
_mode[FX_MODE_FIRE_2012] = &WS2812FX::mode_fire_2012;
_mode[FX_MODE_PRIDE_2015] = &WS2812FX::mode_pride_2015;
_mode[FX_MODE_BPM] = &WS2812FX::mode_bpm;
_mode[FX_MODE_JUGGLE] = &WS2812FX::mode_juggle;
_mode[FX_MODE_PALETTE] = &WS2812FX::mode_palette;
_mode[FX_MODE_COLORWAVES] = &WS2812FX::mode_colorwaves;
_mode[FX_MODE_FILLNOISE8] = &WS2812FX::mode_fillnoise8;
_mode[FX_MODE_NOISE16_1] = &WS2812FX::mode_noise16_1;
_mode[FX_MODE_NOISE16_2] = &WS2812FX::mode_noise16_2;
_mode[FX_MODE_NOISE16_3] = &WS2812FX::mode_noise16_3;
_mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4;
_mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle;
_mode[FX_MODE_LAKE] = &WS2812FX::mode_lake;
_mode[FX_MODE_METEOR] = &WS2812FX::mode_meteor;
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern;
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
_mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst;
_mode[FX_MODE_EXPLODING_FIREWORKS] = &WS2812FX::mode_exploding_fireworks;
_mode[FX_MODE_BOUNCINGBALLS] = &WS2812FX::mode_bouncing_balls;
_mode[FX_MODE_SINELON] = &WS2812FX::mode_sinelon;
_mode[FX_MODE_SINELON_DUAL] = &WS2812FX::mode_sinelon_dual;
_mode[FX_MODE_SINELON_RAINBOW] = &WS2812FX::mode_sinelon_rainbow;
_mode[FX_MODE_POPCORN] = &WS2812FX::mode_popcorn;
_mode[FX_MODE_DRIP] = &WS2812FX::mode_drip;
_mode[FX_MODE_PLASMA] = &WS2812FX::mode_plasma;
_mode[FX_MODE_PERCENT] = &WS2812FX::mode_percent;
_mode[FX_MODE_RIPPLE_RAINBOW] = &WS2812FX::mode_ripple_rainbow;
_mode[FX_MODE_HEARTBEAT] = &WS2812FX::mode_heartbeat;
_mode[FX_MODE_PACIFICA] = &WS2812FX::mode_pacifica;
_mode[FX_MODE_CANDLE_MULTI] = &WS2812FX::mode_candle_multi;
_brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black);
targetPalette = CloudColors_p;
ablMilliampsMax = 850;
currentMilliamps = 0;
timebase = 0;
bus = new NeoPixelWrapper();
resetSegments();
}
void
init(bool supportWhite, uint16_t countPixels, bool skipFirst),
service(void),
blur(uint8_t),
fade_out(uint8_t r),
setMode(uint8_t segid, uint8_t m),
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
setColor(uint8_t slot, uint32_t c),
setBrightness(uint8_t b),
setRange(uint16_t i, uint16_t i2, uint32_t col),
setShowCallback(show_callback cb),
setTransitionMode(bool t),
trigger(void),
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0),
resetSegments(),
setPixelColor(uint16_t n, uint32_t c),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void),
setRgbwPwm(void);
bool
reverseMode = false,
gammaCorrectBri = false,
gammaCorrectCol = true,
applyToAllSelected = true,
segmentsAreIdentical(Segment* a, Segment* b),
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
uint8_t
mainSegment = 0,
rgbwMode = RGBW_MODE_DUAL,
paletteFade = 0,
paletteBlend = 0,
colorOrder = 0,
milliampsPerLed = 55,
getBrightness(void),
getMode(void),
getSpeed(void),
getModeCount(void),
getPaletteCount(void),
getMaxSegments(void),
//getFirstSelectedSegment(void),
getMainSegmentId(void),
gamma8(uint8_t),
get_random_wheel_index(uint8_t);
uint16_t
ablMilliampsMax,
currentMilliamps,
triwave16(uint16_t);
uint32_t
timebase,
color_wheel(uint8_t),
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
color_blend(uint32_t,uint32_t,uint8_t),
gamma32(uint32_t),
getLastShow(void),
getPixelColor(uint16_t),
getColor(void);
WS2812FX::Segment&
getSegment(uint8_t n);
WS2812FX::Segment_runtime
getSegmentRuntime(void);
WS2812FX::Segment*
getSegments(void);
// builtin modes
uint16_t
mode_static(void),
mode_blink(void),
mode_blink_rainbow(void),
mode_strobe(void),
mode_strobe_rainbow(void),
mode_color_wipe(void),
mode_color_sweep(void),
mode_color_wipe_random(void),
mode_color_sweep_random(void),
mode_random_color(void),
mode_dynamic(void),
mode_breath(void),
mode_fade(void),
mode_scan(void),
mode_dual_scan(void),
mode_theater_chase(void),
mode_theater_chase_rainbow(void),
mode_rainbow(void),
mode_rainbow_cycle(void),
mode_running_lights(void),
mode_saw(void),
mode_twinkle(void),
mode_dissolve(void),
mode_dissolve_random(void),
mode_sparkle(void),
mode_flash_sparkle(void),
mode_hyper_sparkle(void),
mode_multi_strobe(void),
mode_android(void),
mode_chase_color(void),
mode_chase_random(void),
mode_chase_rainbow(void),
mode_chase_flash(void),
mode_chase_flash_random(void),
mode_chase_rainbow_white(void),
mode_colorful(void),
mode_traffic_light(void),
mode_running_color(void),
mode_running_red_blue(void),
mode_running_random(void),
mode_larson_scanner(void),
mode_comet(void),
mode_fireworks(void),
mode_rain(void),
mode_merry_christmas(void),
mode_halloween(void),
mode_fire_flicker(void),
mode_gradient(void),
mode_loading(void),
mode_police(void),
mode_police_all(void),
mode_two_dots(void),
mode_two_areas(void),
mode_circus_combustus(void),
mode_bicolor_chase(void),
mode_tricolor_chase(void),
mode_tricolor_wipe(void),
mode_tricolor_fade(void),
mode_lightning(void),
mode_icu(void),
mode_multi_comet(void),
mode_dual_larson_scanner(void),
mode_random_chase(void),
mode_oscillate(void),
mode_fire_2012(void),
mode_pride_2015(void),
mode_bpm(void),
mode_juggle(void),
mode_palette(void),
mode_colorwaves(void),
mode_fillnoise8(void),
mode_noise16_1(void),
mode_noise16_2(void),
mode_noise16_3(void),
mode_noise16_4(void),
mode_colortwinkle(void),
mode_lake(void),
mode_meteor(void),
mode_meteor_smooth(void),
mode_railway(void),
mode_ripple(void),
mode_twinklefox(void),
mode_twinklecat(void),
mode_halloween_eyes(void),
mode_static_pattern(void),
mode_tri_static_pattern(void),
mode_spots(void),
mode_spots_fade(void),
mode_glitter(void),
mode_candle(void),
mode_starburst(void),
mode_exploding_fireworks(void),
mode_bouncing_balls(void),
mode_sinelon(void),
mode_sinelon_dual(void),
mode_sinelon_rainbow(void),
mode_popcorn(void),
mode_drip(void),
mode_plasma(void),
mode_percent(void),
mode_ripple_rainbow(void),
mode_heartbeat(void),
mode_pacifica(void),
mode_candle_multi(void);
private:
NeoPixelWrapper *bus;
uint32_t crgb_to_col(CRGB fastled);
CRGB col_to_crgb(uint32_t);
CRGBPalette16 currentPalette;
CRGBPalette16 targetPalette;
uint32_t now;
uint16_t _length, _lengthRaw, _virtualSegmentLength;
uint16_t _rand16seed;
uint8_t _brightness;
static uint16_t _usedSegmentData;
void load_gradient_palette(uint8_t);
void handle_palette(void);
void fill(uint32_t);
bool
_useRgbw = false,
_skipFirstMode,
_triggered;
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
show_callback _callback = nullptr;
// mode helper functions
uint16_t
blink(uint32_t, uint32_t, bool strobe, bool),
candle(bool),
color_wipe(bool, bool),
scan(bool),
theater_chase(uint32_t, uint32_t, bool),
running_base(bool),
larson_scanner(bool),
sinelon_base(bool,bool),
dissolve(uint32_t),
chase(uint32_t, uint32_t, uint32_t, bool),
gradient_base(bool),
ripple_base(bool),
police_base(uint32_t, uint32_t, bool),
running(uint32_t, uint32_t),
tricolor_chase(uint32_t, uint32_t),
twinklefox_base(bool),
spots_base(uint16_t);
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
uint32_t _lastPaletteChange = 0;
uint32_t _lastShow = 0;
#ifdef WLED_USE_ANALOG_LEDS
uint32_t _analogLastShow = 0;
RgbwColor _analogLastColor = 0;
uint8_t _analogLastBri = 0;
#endif
uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99;
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
// start, stop, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
};
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
friend class Segment_runtime;
uint16_t realPixelIndex(uint16_t i);
};
//10 names per line
const char JSON_mode_names[] PROGMEM = R"=====([
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
"Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
"Heartbeat","Pacifica","Candle Multi"
])=====";
const char JSON_palette_names[] PROGMEM = R"=====([
"Default","* Random Cycle","* Color 1","* Colors 1&2","* Color Gradient","* Colors Only","Party","Cloud","Lava","Ocean",
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
"Aurora","Atlantica"
])=====";
#endif

893
wled00/FX_fcn.cpp Normal file
View File

@@ -0,0 +1,893 @@
/*
WS2812FX_fcn.cpp contains all utility functions
Harm Aldick - 2016
www.aldick.org
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Harm Aldick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Modified heavily for WLED
*/
#include "FX.h"
#include "palettes.h"
//enable custom per-LED mapping. This can allow for better effects on matrices or special displays
//#define WLED_CUSTOM_LED_MAPPING
#ifdef WLED_CUSTOM_LED_MAPPING
//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs.
const uint16_t customMappingTable[] = {
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29};
//another example. Switches direction every 5 LEDs.
/*const uint16_t customMappingTable[] = {
0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14,
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};*/
const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example
#endif
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
{
if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return;
RESET_RUNTIME;
_useRgbw = supportWhite;
_length = countPixels;
_skipFirstMode = skipFirst;
uint8_t ty = 1;
if (supportWhite) ty = 2;
_lengthRaw = _length;
if (_skipFirstMode) {
_lengthRaw += LED_SKIP_AMOUNT;
}
bus->Begin((NeoPixelType)ty, _lengthRaw);
_segments[0].start = 0;
_segments[0].stop = _length;
setBrightness(_brightness);
}
void WS2812FX::service() {
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
now = nowUp + timebase;
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
bool doShow = false;
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
{
_segment_index = i;
if (SEGMENT.isActive())
{
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
{
if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check
_virtualSegmentLength = SEGMENT.virtualLength();
doShow = true;
handle_palette();
uint16_t delay = (this->*_mode[SEGMENT.mode])();
SEGENV.next_time = nowUp + delay;
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
}
}
}
_virtualSegmentLength = 0;
if(doShow) {
yield();
show();
}
_triggered = false;
}
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
uint8_t w = (c >> 24);
uint8_t r = (c >> 16);
uint8_t g = (c >> 8);
uint8_t b = c ;
setPixelColor(n, r, g, b, w);
}
uint16_t WS2812FX::realPixelIndex(uint16_t i) {
int16_t iGroup = i * SEGMENT.groupLength();
/* reverse just an individual segment */
int16_t realIndex = iGroup;
if (IS_REVERSE) realIndex = SEGMENT.length() -iGroup -1;
realIndex += SEGMENT.start;
/* Reverse the whole string */
if (reverseMode) realIndex = _length - 1 - realIndex;
return realIndex;
}
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{
//auto calculate white channel value if enabled
if (_useRgbw) {
if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY)))
{
//white value is set to lowest RGB channel
//thank you to @Def3nder!
w = r < g ? (r < b ? r : b) : (g < b ? g : b);
} else if (rgbwMode == RGBW_MODE_AUTO_ACCURATE && w == 0)
{
w = r < g ? (r < b ? r : b) : (g < b ? g : b);
r -= w; g -= w; b -= w;
}
}
RgbwColor col;
switch (colorOrder)
{
case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default
case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811
case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG
case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG
case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR
default: col.G = g; col.R = b; col.B = r; break; //5 = GBR
}
col.W = w;
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
if (SEGLEN) {//from segment
//color_blend(getpixel, col, SEGMENT.opacity); (pseudocode for future blending of segments)
if (IS_SEGMENT_ON)
{
if (SEGMENT.opacity < 255) {
col.R = scale8(col.R, SEGMENT.opacity);
col.G = scale8(col.G, SEGMENT.opacity);
col.B = scale8(col.B, SEGMENT.opacity);
col.W = scale8(col.W, SEGMENT.opacity);
}
} else {
col = BLACK;
}
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
bool reversed = reverseMode ^ IS_REVERSE;
uint16_t realIndex = realPixelIndex(i);
for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
int16_t indexSet = realIndex + (reversed ? -j : j);
int16_t indexSetRev = indexSet;
if (reverseMode) indexSetRev = _length - 1 - indexSet;
#ifdef WLED_CUSTOM_LED_MAPPING
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
#endif
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col);
}
} else { //live data, etc.
if (reverseMode) i = _length - 1 - i;
#ifdef WLED_CUSTOM_LED_MAPPING
if (i < customMappingSize) i = customMappingTable[i];
#endif
bus->SetPixelColor(i + skip, col);
}
if (skip && i == 0) {
for (uint16_t j = 0; j < skip; j++) {
bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0));
}
}
}
//DISCLAIMER
//The following function attemps to calculate the current LED power usage,
//and will limit the brightness to stay below a set amperage threshold.
//It is NOT a measurement and NOT guaranteed to stay within the ablMilliampsMax margin.
//Stay safe with high amperage and have a reasonable safety margin!
//I am NOT to be held liable for burned down garages!
//fine tune power estimation constants for your setup
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
void WS2812FX::show(void) {
if (_callback) _callback();
//power limit calculation
//each LED can draw up 195075 "power units" (approx. 53mA)
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
//so A=2,R=255,G=0,B=0 would use 510 PU per LED (1mA is about 3700 PU)
bool useWackyWS2815PowerModel = false;
byte actualMilliampsPerLed = milliampsPerLed;
if(milliampsPerLed == 255) {
useWackyWS2815PowerModel = true;
actualMilliampsPerLed = 12; // from testing an actual strip
}
if (ablMilliampsMax > 149 && actualMilliampsPerLed > 0) //0 mA per LED and too low numbers turn off calculation
{
uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed;
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget
{
powerBudget -= puPerMilliamp * _length;
} else
{
powerBudget = 0;
}
uint32_t powerSum = 0;
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
{
RgbwColor c = bus->GetPixelColorRgbw(i);
if(useWackyWS2815PowerModel)
{
// ignore white component on WS2815 power calculation
powerSum += (MAX(MAX(c.R,c.G),c.B)) * 3;
}
else
{
powerSum += (c.R + c.G + c.B + c.W);
}
}
if (_useRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
{
powerSum *= 3;
powerSum = powerSum >> 2; //same as /= 4
}
uint32_t powerSum0 = powerSum;
powerSum *= _brightness;
if (powerSum > powerBudget) //scale brightness down to stay in current limit
{
float scale = (float)powerBudget / (float)powerSum;
uint16_t scaleI = scale * 255;
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
uint8_t newBri = scale8(_brightness, scaleB);
bus->SetBrightness(newBri);
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
} else
{
currentMilliamps = powerSum / puPerMilliamp;
bus->SetBrightness(_brightness);
}
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
currentMilliamps += _length; //add standby power back to estimate
} else {
currentMilliamps = 0;
bus->SetBrightness(_brightness);
}
bus->Show();
_lastShow = millis();
}
void WS2812FX::trigger() {
_triggered = true;
}
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
if (segid >= MAX_NUM_SEGMENTS) return;
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
if (_segments[segid].mode != m)
{
_segment_runtimes[segid].reset();
_segments[segid].mode = m;
}
}
uint8_t WS2812FX::getModeCount()
{
return MODE_COUNT;
}
uint8_t WS2812FX::getPaletteCount()
{
return 13 + GRADIENT_PALETTE_COUNT;
}
//TODO transitions
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
uint8_t mainSeg = getMainSegmentId();
Segment& seg = _segments[getMainSegmentId()];
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
bool applied = false;
if (applyToAllSelected) {
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected())
{
_segments[i].speed = s;
_segments[i].intensity = in;
_segments[i].palette = p;
setMode(i, m);
applied = true;
}
}
}
if (!applyToAllSelected || !applied) {
seg.speed = s;
seg.intensity = in;
seg.palette = p;
setMode(mainSegment, m);
}
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
return false;
}
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
}
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
if (slot >= NUM_COLORS) return;
bool applied = false;
if (applyToAllSelected) {
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
}
}
if (!applyToAllSelected || !applied) {
_segments[getMainSegmentId()].colors[slot] = c;
}
}
void WS2812FX::setBrightness(uint8_t b) {
if (_brightness == b) return;
_brightness = (gammaCorrectBri) ? gamma8(b) : b;
_segment_index = 0;
if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon
}
uint8_t WS2812FX::getMode(void) {
return _segments[getMainSegmentId()].mode;
}
uint8_t WS2812FX::getSpeed(void) {
return _segments[getMainSegmentId()].speed;
}
uint8_t WS2812FX::getBrightness(void) {
return _brightness;
}
uint8_t WS2812FX::getMaxSegments(void) {
return MAX_NUM_SEGMENTS;
}
/*uint8_t WS2812FX::getFirstSelectedSegment(void)
{
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isActive() && _segments[i].isSelected()) return i;
}
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active
{
if (_segments[i].isActive()) return i;
}
return 0;
}*/
uint8_t WS2812FX::getMainSegmentId(void) {
if (mainSegment >= MAX_NUM_SEGMENTS) return 0;
return mainSegment;
}
uint32_t WS2812FX::getColor(void) {
return _segments[getMainSegmentId()].colors[0];
}
uint32_t WS2812FX::getPixelColor(uint16_t i)
{
i = realPixelIndex(i);
#ifdef WLED_CUSTOM_LED_MAPPING
if (i < customMappingSize) i = customMappingTable[i];
#endif
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
if (i >= _lengthRaw) return 0;
RgbwColor col = bus->GetPixelColorRgbw(i);
switch (colorOrder)
{
// W G R B
case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default
case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811
case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG
case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG
case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR
case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR
}
return 0;
}
WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
if (id >= MAX_NUM_SEGMENTS) return _segments[0];
return _segments[id];
}
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
return SEGENV;
}
WS2812FX::Segment* WS2812FX::getSegments(void) {
return _segments;
}
uint32_t WS2812FX::getLastShow(void) {
return _lastShow;
}
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
if (n >= MAX_NUM_SEGMENTS) return;
Segment& seg = _segments[n];
//return if neither bounds nor grouping have changed
if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) return;
if (seg.stop) setRange(seg.start, seg.stop -1, 0); //turn old segment range off
if (i2 <= i1) //disable segment
{
seg.stop = 0;
if (n == mainSegment) //if main segment is deleted, set first active as main segment
{
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isActive()) {
mainSegment = i;
return;
}
}
mainSegment = 0; //should not happen (always at least one active segment)
}
return;
}
if (i1 < _length) seg.start = i1;
seg.stop = i2;
if (i2 > _length) seg.stop = _length;
if (grouping) {
seg.grouping = grouping;
seg.spacing = spacing;
}
_segment_runtimes[n].reset();
}
void WS2812FX::resetSegments() {
mainSegment = 0;
memset(_segments, 0, sizeof(_segments));
//memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
_segment_index = 0;
_segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR;
_segments[0].start = 0;
_segments[0].speed = DEFAULT_SPEED;
_segments[0].stop = _length;
_segments[0].grouping = 1;
_segments[0].setOption(SEG_OPTION_SELECTED, 1);
_segments[0].setOption(SEG_OPTION_ON, 1);
_segments[0].opacity = 255;
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
{
_segments[i].colors[0] = color_wheel(i*51);
_segments[i].grouping = 1;
_segments[i].setOption(SEG_OPTION_ON, 1);
_segments[i].opacity = 255;
_segment_runtimes[i].reset();
}
_segment_runtimes[0].reset();
}
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
{
if (i2 >= i)
{
for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col);
} else
{
for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col);
}
}
void WS2812FX::setShowCallback(show_callback cb)
{
_callback = cb;
}
void WS2812FX::setTransitionMode(bool t)
{
_segment_index = getMainSegmentId();
SEGMENT.setOption(SEG_OPTION_TRANSITIONAL, t);
if (!t) return;
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
if (SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) SEGENV.next_time = waitMax;
}
/*
* color blend function
*/
uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) {
if(blend == 0) return color1;
if(blend == 255) return color2;
uint32_t w1 = (color1 >> 24) & 0xff;
uint32_t r1 = (color1 >> 16) & 0xff;
uint32_t g1 = (color1 >> 8) & 0xff;
uint32_t b1 = color1 & 0xff;
uint32_t w2 = (color2 >> 24) & 0xff;
uint32_t r2 = (color2 >> 16) & 0xff;
uint32_t g2 = (color2 >> 8) & 0xff;
uint32_t b2 = color2 & 0xff;
uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) >> 8;
uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) >> 8;
return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3));
}
/*
* Fills segment with color
*/
void WS2812FX::fill(uint32_t c) {
for(uint16_t i = 0; i < SEGLEN; i++) {
setPixelColor(i, c);
}
}
/*
* fade out function, higher rate = quicker fade
*/
void WS2812FX::fade_out(uint8_t rate) {
rate = (255-rate) >> 1;
float mappedRate = float(rate) +1.1;
uint32_t color = SEGCOLOR(1); // target color
int w2 = (color >> 24) & 0xff;
int r2 = (color >> 16) & 0xff;
int g2 = (color >> 8) & 0xff;
int b2 = color & 0xff;
for(uint16_t i = 0; i < SEGLEN; i++) {
color = getPixelColor(i);
int w1 = (color >> 24) & 0xff;
int r1 = (color >> 16) & 0xff;
int g1 = (color >> 8) & 0xff;
int b1 = color & 0xff;
int wdelta = (w2 - w1) / mappedRate;
int rdelta = (r2 - r1) / mappedRate;
int gdelta = (g2 - g1) / mappedRate;
int bdelta = (b2 - b1) / mappedRate;
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
}
}
/*
* blurs segment content, source: FastLED colorutils.cpp
*/
void WS2812FX::blur(uint8_t blur_amount)
{
uint8_t keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black;
for(uint16_t i = 0; i < SEGLEN; i++)
{
CRGB cur = col_to_crgb(getPixelColor(i));
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if(i > 0) {
uint32_t c = getPixelColor(i-1);
uint8_t r = (c >> 16 & 0xFF);
uint8_t g = (c >> 8 & 0xFF);
uint8_t b = (c & 0xFF);
setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
}
setPixelColor(i,cur.red, cur.green, cur.blue);
carryover = part;
}
}
uint16_t WS2812FX::triwave16(uint16_t in)
{
if (in < 0x8000) return in *2;
return 0xFFFF - (in - 0x8000)*2;
}
/*
* Put a value 0 to 255 in to get a color value.
* The colours are a transition r -> g -> b -> back to r
* Inspired by the Adafruit examples.
*/
uint32_t WS2812FX::color_wheel(uint8_t pos) {
if (SEGMENT.palette) return color_from_palette(pos, false, true, 0);
pos = 255 - pos;
if(pos < 85) {
return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3);
} else if(pos < 170) {
pos -= 85;
return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3);
} else {
pos -= 170;
return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0);
}
}
/*
* Returns a new, random wheel index with a minimum distance of 42 from pos.
*/
uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
uint8_t r = 0, x = 0, y = 0, d = 0;
while(d < 42) {
r = random8();
x = abs(pos - r);
y = 255 - x;
d = MIN(x, y);
}
return r;
}
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
{
return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue);
}
CRGB WS2812FX::col_to_crgb(uint32_t color)
{
CRGB fastled_col;
fastled_col.red = (color >> 16 & 0xFF);
fastled_col.green = (color >> 8 & 0xFF);
fastled_col.blue = (color & 0xFF);
return fastled_col;
}
void WS2812FX::load_gradient_palette(uint8_t index)
{
byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1);
byte tcp[72]; //support gradient palettes with up to 18 entries
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72);
targetPalette.loadDynamicGradientPalette(tcp);
}
/*
* FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions
*/
void WS2812FX::handle_palette(void)
{
bool singleSegmentMode = (_segment_index == _segment_index_palette_last);
_segment_index_palette_last = _segment_index;
byte paletteIndex = SEGMENT.palette;
if (SEGMENT.mode == FX_MODE_GLITTER && paletteIndex == 0) paletteIndex = 11;
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
switch (paletteIndex)
{
case 0: {//default palette. Differs depending on effect
switch (SEGMENT.mode)
{
case FX_MODE_FIRE_2012 : load_gradient_palette(22); break;//heat palette
case FX_MODE_COLORWAVES : load_gradient_palette(13); break;//landscape 33
case FX_MODE_FILLNOISE8 : targetPalette = OceanColors_p; break;
case FX_MODE_NOISE16_1 : load_gradient_palette(17); break;//Drywet
case FX_MODE_NOISE16_2 : load_gradient_palette(30); break;//Blue cyan yellow
case FX_MODE_NOISE16_3 : load_gradient_palette(22); break;//heat palette
case FX_MODE_NOISE16_4 : load_gradient_palette(13); break;//landscape 33
//case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break;
default: targetPalette = PartyColors_p; break;//palette, bpm
}
break;}
case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments
if (!singleSegmentMode)
{
targetPalette = PartyColors_p; break; //fallback
}
if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-SEGMENT.intensity))*100)
{
targetPalette = CRGBPalette16(
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 192, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)));
_lastPaletteChange = millis();
} break;}
case 2: {//primary color only
CRGB prim = col_to_crgb(SEGCOLOR(0));
targetPalette = CRGBPalette16(prim); break;}
case 3: {//primary + secondary
CRGB prim = col_to_crgb(SEGCOLOR(0));
CRGB sec = col_to_crgb(SEGCOLOR(1));
targetPalette = CRGBPalette16(prim,prim,sec,sec); break;}
case 4: {//primary + secondary + tertiary
CRGB prim = col_to_crgb(SEGCOLOR(0));
CRGB sec = col_to_crgb(SEGCOLOR(1));
CRGB ter = col_to_crgb(SEGCOLOR(2));
targetPalette = CRGBPalette16(ter,sec,prim); break;}
case 5: {//primary + secondary (+tert if not off), more distinct
CRGB prim = col_to_crgb(SEGCOLOR(0));
CRGB sec = col_to_crgb(SEGCOLOR(1));
if (SEGCOLOR(2)) {
CRGB ter = col_to_crgb(SEGCOLOR(2));
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim);
} else {
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec);
}
break;}
case 6: //Party colors
targetPalette = PartyColors_p; break;
case 7: //Cloud colors
targetPalette = CloudColors_p; break;
case 8: //Lava colors
targetPalette = LavaColors_p; break;
case 9: //Ocean colors
targetPalette = OceanColors_p; break;
case 10: //Forest colors
targetPalette = ForestColors_p; break;
case 11: //Rainbow colors
targetPalette = RainbowColors_p; break;
case 12: //Rainbow stripe colors
targetPalette = RainbowStripeColors_p; break;
default: //progmem palettes
load_gradient_palette(SEGMENT.palette -13);
}
if (singleSegmentMode && paletteFade) //only blend if just one segment uses FastLED mode
{
nblendPaletteTowardPalette(currentPalette, targetPalette, 48);
} else
{
currentPalette = targetPalette;
}
}
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
{
if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default
uint8_t paletteIndex = i;
if (mapping) paletteIndex = (i*255)/(SEGLEN -1);
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGB fastled_col;
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
}
bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
{
//if (a->start != b->start) return false;
//if (a->stop != b->stop) return false;
for (uint8_t i = 0; i < NUM_COLORS; i++)
{
if (a->colors[i] != b->colors[i]) return false;
}
if (a->mode != b->mode) return false;
if (a->speed != b->speed) return false;
if (a->intensity != b->intensity) return false;
if (a->palette != b->palette) return false;
//if (a->getOption(SEG_OPTION_REVERSED) != b->getOption(SEG_OPTION_REVERSED)) return false;
return true;
}
#ifdef WLED_USE_ANALOG_LEDS
void WS2812FX::setRgbwPwm(void) {
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
if (nowUp - _analogLastShow < MIN_SHOW_DELAY) return;
_analogLastShow = nowUp;
RgbwColor color = bus->GetPixelColorRgbw(0);
byte b = getBrightness();
if (color == _analogLastColor && b == _analogLastBri) return;
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
#ifdef WLED_USE_5CH_LEDS
if (color.R == 255 && color.G == 255 && color.B == 255 && color.W == 255) {
bus->SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
} else if (color.R == 127 && color.G == 127 && color.B == 127 && color.W == 255) {
bus->SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255);
} else if (color.R == 0 && color.G == 0 && color.B == 0 && color.W == 255) {
bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else if (color.R == 130 && color.G == 90 && color.B == 0 && color.W == 255) {
bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
} else if (color.R == 255 && color.G == 153 && color.B == 0 && color.W == 255) {
bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else { // not only white colors
bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
}
#else
bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
#endif
_analogLastColor = color;
_analogLastBri = b;
}
#else
void WS2812FX::setRgbwPwm() {}
#endif
//gamma 2.4 lookup table used for color correction
const byte gammaT[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
uint8_t WS2812FX::gamma8(uint8_t b)
{
return gammaT[b];
}
uint32_t WS2812FX::gamma32(uint32_t color)
{
if (!gammaCorrectCol) return color;
uint8_t w = (color >> 24);
uint8_t r = (color >> 16);
uint8_t g = (color >> 8);
uint8_t b = color;
w = gammaT[w];
r = gammaT[r];
g = gammaT[g];
b = gammaT[b];
return ((w << 24) | (r << 16) | (g << 8) | (b));
}
uint16_t WS2812FX::_usedSegmentData = 0;

332
wled00/NpbWrapper.h Normal file
View File

@@ -0,0 +1,332 @@
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
#ifndef NpbWrapper_h
#define NpbWrapper_h
//PIN CONFIGURATION
#ifndef LEDPIN
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
#endif
//#define USE_APA102 // Uncomment for using APA102 LEDs.
//#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer)
//#define USE_LPD8806 // Uncomment for using LPD8806
//#define USE_TM1814 // Uncomment for using TM1814 LEDs (make sure you have NeoPixelBus v2.5.7 or newer)
//#define USE_P9813 // Uncomment for using P9813 LEDs (make sure you have NeoPixelBus v2.5.8 or newer)
//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
//#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white
#ifndef BTNPIN
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#endif
#ifndef IR_PIN
#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#endif
#ifndef RLYPIN
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#endif
#ifndef AUXPIN
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
#endif
#ifndef RLYMDE
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
#endif
//END CONFIGURATION
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
#define CLKPIN 0
#define DATAPIN 2
#if BTNPIN == CLKPIN || BTNPIN == DATAPIN
#undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins.
#endif
#endif
#ifdef WLED_USE_ANALOG_LEDS
//PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
#ifdef WLED_USE_H801
#define RPIN 15 //R pin for analog LED strip
#define GPIN 13 //G pin for analog LED strip
#define BPIN 12 //B pin for analog LED strip
#define WPIN 14 //W pin for analog LED strip
#define W2PIN 04 //W2 pin for analog LED strip
#undef BTNPIN
#undef IR_PIN
#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#elif defined(WLED_USE_BWLT11)
//PWM pins - to use with BW-LT11
#define RPIN 12 //R pin for analog LED strip
#define GPIN 4 //G pin for analog LED strip
#define BPIN 14 //B pin for analog LED strip
#define WPIN 5 //W pin for analog LED strip
#elif defined(SHOJO_PCB)
//PWM pins - to use with Shojo PCB (https://www.bastelbunker.de/esp-rgbww-wifi-led-controller-vbs-edition/)
#define RPIN 14 //R pin for analog LED strip
#define GPIN 4 //G pin for analog LED strip
#define BPIN 5 //B pin for analog LED strip
#define WPIN 15 //W pin for analog LED strip
#define W2PIN 12 //W2 pin for analog LED strip
#else
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
#define RPIN 5 //R pin for analog LED strip
#define GPIN 12 //G pin for analog LED strip
#define BPIN 15 //B pin for analog LED strip
#define WPIN 13 //W pin for analog LED strip
#endif
#undef RLYPIN
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
#endif
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef USE_APA102
#define PIXELMETHOD DotStarMethod
#elif defined(USE_WS2801)
#define PIXELMETHOD NeoWs2801Method
#elif defined(USE_LPD8806)
#define PIXELMETHOD Lpd8806Method
#elif defined(USE_TM1814)
#define PIXELMETHOD NeoTm1814Method
#elif defined(USE_P9813)
#define PIXELMETHOD P9813Method
#else
#define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod
#endif
#else //esp8266
//autoselect the right method depending on strip pin
#ifdef USE_APA102
#define PIXELMETHOD DotStarMethod
#elif defined(USE_WS2801)
#define PIXELMETHOD NeoWs2801Method
#elif defined(USE_LPD8806)
#define PIXELMETHOD Lpd8806Method
#elif defined(USE_TM1814)
#define PIXELMETHOD NeoTm1814Method
#elif defined(USE_P9813)
#define PIXELMETHOD P9813Method
#elif LEDPIN == 2
#define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
#elif LEDPIN == 3
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
#else
#define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod
#pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
#endif
#endif
//you can now change the color order in the web settings
#ifdef USE_APA102
#define PIXELFEATURE3 DotStarBgrFeature
#define PIXELFEATURE4 DotStarLbgrFeature
#elif defined(USE_LPD8806)
#define PIXELFEATURE3 Lpd8806GrbFeature
#define PIXELFEATURE4 Lpd8806GrbFeature
#elif defined(USE_TM1814)
#define PIXELFEATURE3 NeoWrgbTm1814Feature
#define PIXELFEATURE4 NeoWrgbTm1814Feature
#elif defined(USE_P9813)
#define PIXELFEATURE3 P9813BgrFeature
#define PIXELFEATURE4 NeoGrbwFeature
#else
#define PIXELFEATURE3 NeoGrbFeature
#define PIXELFEATURE4 NeoGrbwFeature
#endif
#include <NeoPixelBrightnessBus.h>
enum NeoPixelType
{
NeoPixelType_None = 0,
NeoPixelType_Grb = 1,
NeoPixelType_Grbw = 2,
NeoPixelType_End = 3
};
class NeoPixelWrapper
{
public:
NeoPixelWrapper() :
// initialize each member to null
_pGrb(NULL),
_pGrbw(NULL),
_type(NeoPixelType_None)
{
}
~NeoPixelWrapper()
{
cleanup();
}
void Begin(NeoPixelType type, uint16_t countPixels)
{
cleanup();
_type = type;
switch (_type)
{
case NeoPixelType_Grb:
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
#else
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
#endif
_pGrb->Begin();
break;
case NeoPixelType_Grbw:
#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813)
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
#else
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
#endif
_pGrbw->Begin();
break;
}
#ifdef WLED_USE_ANALOG_LEDS
#ifdef ARDUINO_ARCH_ESP32
ledcSetup(0, 5000, 8);
ledcAttachPin(RPIN, 0);
ledcSetup(1, 5000, 8);
ledcAttachPin(GPIN, 1);
ledcSetup(2, 5000, 8);
ledcAttachPin(BPIN, 2);
if(_type == NeoPixelType_Grbw)
{
ledcSetup(3, 5000, 8);
ledcAttachPin(WPIN, 3);
#ifdef WLED_USE_5CH_LEDS
ledcSetup(4, 5000, 8);
ledcAttachPin(W2PIN, 4);
#endif
}
#else // ESP8266
//init PWM pins
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
if(_type == NeoPixelType_Grbw)
{
pinMode(WPIN, OUTPUT);
#ifdef WLED_USE_5CH_LEDS
pinMode(W2PIN, OUTPUT);
#endif
}
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#endif
#endif
}
#ifdef WLED_USE_ANALOG_LEDS
void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
{
#ifdef ARDUINO_ARCH_ESP32
ledcWrite(0, r);
ledcWrite(1, g);
ledcWrite(2, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: ledcWrite(3, w); ledcWrite(4, w2); break;
#else
case NeoPixelType_Grbw: ledcWrite(3, w); break;
#endif
}
#else // ESP8266
analogWrite(RPIN, r);
analogWrite(GPIN, g);
analogWrite(BPIN, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
#else
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
#endif
}
#endif
}
#endif
void Show()
{
byte b;
switch (_type)
{
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: {
_pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
}
break;
case NeoPixelType_Grbw: {
#ifdef USE_LPD8806
_pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
#else
_pGrbw->SetPixelColor(indexPixel, color);
#endif
}
break;
}
}
void SetBrightness(byte b)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
}
}
// NOTE: Due to feature differences, some support RGBW but the method name
// here needs to be unique, thus GetPixeColorRgbw
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
}
return 0;
}
uint8_t* GetPixels(void)
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->Pixels(); break;
case NeoPixelType_Grbw: return _pGrbw->Pixels(); break;
}
return 0;
}
private:
NeoPixelType _type;
// have a member for every possible type
NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>* _pGrb;
NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>* _pGrbw;
void cleanup()
{
switch (_type) {
case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break;
case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break;
}
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,421 +0,0 @@
//#define RGBW
#define PIN 2 //strip pin. Only change for ESP32
#define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#else
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
#endif
//selects correct feature for RGB/RGBW
#ifdef RGBW
#define PIXELFEATURE NeoGrbwFeature
#else
#define PIXELFEATURE NeoGrbFeature
#endif
/*
WS2812FX.h - Library for WS2812 LED effects.
Harm Aldick - 2016
www.aldick.org
FEATURES
* A lot of blinken modes and counting
* WS2812FX can be used as drop-in replacement for Adafruit Neopixel Library
NOTES
* Uses the Adafruit Neopixel library. Get it here:
https://github.com/adafruit/Adafruit_NeoPixel
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Harm Aldick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Modified to work with WLED - differs from Github WS2812FX
*/
#ifndef WS2812FX_h
#define WS2812FX_h
#include "Arduino.h"
#include <NeoPixelBrightnessBus.h>
#define DEFAULT_BRIGHTNESS 50
#define DEFAULT_MODE 0
#define DEFAULT_SPEED 150
#define DEFAULT_COLOR 0xFFAA00
#define SPEED_MIN 0
#define SPEED_MAX 255
#define BRIGHTNESS_MIN 0
#define BRIGHTNESS_MAX 255
#define MODE_COUNT 58
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
#define FX_MODE_BREATH 2
#define FX_MODE_COLOR_WIPE 3
#define FX_MODE_COLOR_WIPE_RANDOM 4
#define FX_MODE_RANDOM_COLOR 5
#define FX_MODE_SINGLE_DYNAMIC 6
#define FX_MODE_MULTI_DYNAMIC 7
#define FX_MODE_RAINBOW 8
#define FX_MODE_RAINBOW_CYCLE 9
#define FX_MODE_SCAN 10
#define FX_MODE_DUAL_SCAN 11
#define FX_MODE_FADE 12
#define FX_MODE_THEATER_CHASE 13
#define FX_MODE_THEATER_CHASE_RAINBOW 14
#define FX_MODE_RUNNING_LIGHTS 15
#define FX_MODE_TWINKLE 16
#define FX_MODE_TWINKLE_RANDOM 17
#define FX_MODE_TWINKLE_FADE 18
#define FX_MODE_TWINKLE_FADE_RANDOM 19
#define FX_MODE_SPARKLE 20
#define FX_MODE_FLASH_SPARKLE 21
#define FX_MODE_HYPER_SPARKLE 22
#define FX_MODE_STROBE 23
#define FX_MODE_STROBE_RAINBOW 24
#define FX_MODE_MULTI_STROBE 25
#define FX_MODE_BLINK_RAINBOW 26
#define FX_MODE_ANDROID 27
#define FX_MODE_CHASE_COLOR 28
#define FX_MODE_CHASE_RANDOM 29
#define FX_MODE_CHASE_RAINBOW 30
#define FX_MODE_CHASE_FLASH 31
#define FX_MODE_CHASE_FLASH_RANDOM 32
#define FX_MODE_CHASE_RAINBOW_WHITE 33
#define FX_MODE_COLORFUL 34
#define FX_MODE_TRAFFIC_LIGHT 35
#define FX_MODE_COLOR_SWEEP_RANDOM 36
#define FX_MODE_RUNNING_COLOR 37
#define FX_MODE_RUNNING_RED_BLUE 38
#define FX_MODE_RUNNING_RANDOM 39
#define FX_MODE_LARSON_SCANNER 40
#define FX_MODE_COMET 41
#define FX_MODE_FIREWORKS 42
#define FX_MODE_FIREWORKS_RANDOM 43
#define FX_MODE_MERRY_CHRISTMAS 44
#define FX_MODE_FIRE_FLICKER 45
#define FX_MODE_GRADIENT 46
#define FX_MODE_LOADING 47
#define FX_MODE_DUAL_COLOR_WIPE_IN_OUT 48
#define FX_MODE_DUAL_COLOR_WIPE_IN_IN 49
#define FX_MODE_DUAL_COLOR_WIPE_OUT_OUT 50
#define FX_MODE_DUAL_COLOR_WIPE_OUT_IN 51
#define FX_MODE_CIRCUS_COMBUSTUS 52
#define FX_MODE_CUSTOM_CHASE 53
#define FX_MODE_CC_ON_RAINBOW 54
#define FX_MODE_CC_ON_RAINBOW_CYCLE 55
#define FX_MODE_CC_BLINK 56
#define FX_MODE_CC_RANDOM 57
class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
typedef void (WS2812FX::*mode_ptr)(void);
public:
WS2812FX(uint16_t n) : NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD>(n,PIN) {
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
_mode[FX_MODE_SINGLE_DYNAMIC] = &WS2812FX::mode_single_dynamic;
_mode[FX_MODE_MULTI_DYNAMIC] = &WS2812FX::mode_multi_dynamic;
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
_mode[FX_MODE_TWINKLE_RANDOM] = &WS2812FX::mode_twinkle_random;
_mode[FX_MODE_TWINKLE_FADE] = &WS2812FX::mode_twinkle_fade;
_mode[FX_MODE_TWINKLE_FADE_RANDOM] = &WS2812FX::mode_twinkle_fade_random;
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
_mode[FX_MODE_ANDROID] = &WS2812FX::mode_android;
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
_mode[FX_MODE_COLORFUL] = &WS2812FX::mode_colorful;
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random;
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_OUT] = &WS2812FX::mode_dual_color_wipe_in_out;
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_IN] = &WS2812FX::mode_dual_color_wipe_in_in;
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_OUT] = &WS2812FX::mode_dual_color_wipe_out_out;
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_IN] = &WS2812FX::mode_dual_color_wipe_out_in;
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
_mode[FX_MODE_CUSTOM_CHASE] = &WS2812FX::mode_cc_standard;
_mode[FX_MODE_CC_ON_RAINBOW] = &WS2812FX::mode_cc_rainbow;
_mode[FX_MODE_CC_ON_RAINBOW_CYCLE] = &WS2812FX::mode_cc_cycle;
_mode[FX_MODE_CC_BLINK] = &WS2812FX::mode_cc_blink;
_mode[FX_MODE_CC_RANDOM] = &WS2812FX::mode_cc_random;
_mode_index = DEFAULT_MODE;
_speed = DEFAULT_SPEED;
_brightness = DEFAULT_BRIGHTNESS;
_running = false;
_led_count = n;
_mode_last_call_time = 0;
_mode_delay = 0;
_color = DEFAULT_COLOR;
_mode_color = DEFAULT_COLOR;
_color_sec = 0;
_mode_var1 = 0;
_cc_fs = true;
_cc_fe = false;
_cc_is = 0;
_cc_i1 = 0;
_cc_i2 = n-1;
_cc_num1 = 5;
_cc_num2 = 5;
_ccStep = 1;
_counter_mode_call = 0;
_counter_mode_step = 0;
_counter_ccStep = 0;
_fastStandard = false;
_reverseMode = false;
_locked = new bool[n];
_cronixieDigits = new byte[6];
}
void
show(void),
setPixelColor(uint16_t i, byte r, byte g, byte b),
init(void),
service(void),
start(void),
stop(void),
setMode(byte m),
setCustomChase(byte i1, byte i2, byte is, byte np, byte ns, byte stp, bool fs, bool fe),
setCCIndex1(byte i1),
setCCIndex2(byte i2),
setCCStart(byte is),
setCCNum1(byte np),
setCCNum2(byte ns),
setCCStep(byte stp),
setCCFS(bool fs),
setCCFE(bool fe),
setSpeed(byte s),
setIntensity(byte in),
increaseSpeed(byte s),
decreaseSpeed(byte s),
setColor(byte r, byte g, byte b),
setColor(byte r, byte g, byte b, byte w),
setColor(uint32_t c),
setSecondaryColor(byte r, byte g, byte b),
setSecondaryColor(byte r, byte g, byte b, byte w),
setSecondaryColor(uint32_t c),
setBrightness(byte b),
increaseBrightness(byte s),
decreaseBrightness(byte s),
setReverseMode(bool b),
driverModeCronixie(bool b),
setCronixieDigits(byte* d),
setCronixieBacklight(bool b),
setIndividual(int i),
setIndividual(int i, uint32_t col),
setRange(int i, int i2),
setRange(int i, int i2, uint32_t col),
lock(int i),
lockRange(int i, int i2),
lockAll(void),
unlock(int i),
unlockRange(int i, int i2),
unlockAll(void),
setFastUpdateMode(bool b),
trigger(void),
setLedCount(uint16_t i),
setFade(int sp);
bool
isRunning(void),
isLocked(int i);
byte
get_random_wheel_index(byte),
getMode(void),
getSpeed(void),
getIntensity(void),
getBrightness(void),
getModeCount(void);
uint32_t
color_wheel(byte),
getColor(void);
double
getPowerEstimate(byte leds, uint32_t c, byte b),
getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b);
private:
void
begin(void),
clear(void),
setPixelColor(uint16_t i, uint32_t c),
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
dofade(void),
strip_off(void),
strip_off_respectLock(void),
mode_static(void),
mode_blink(void),
mode_color_wipe(void),
mode_color_wipe_random(void),
mode_random_color(void),
mode_single_dynamic(void),
mode_multi_dynamic(void),
mode_breath(void),
mode_fade(void),
mode_scan(void),
mode_dual_scan(void),
mode_theater_chase(void),
mode_theater_chase_rainbow(void),
mode_rainbow(void),
mode_rainbow_cycle(void),
mode_running_lights(void),
mode_twinkle(void),
mode_twinkle_random(void),
mode_twinkle_fade(void),
mode_twinkle_fade_random(void),
mode_sparkle(void),
mode_flash_sparkle(void),
mode_hyper_sparkle(void),
mode_strobe(void),
mode_strobe_rainbow(void),
mode_multi_strobe(void),
mode_blink_rainbow(void),
mode_android(void),
mode_chase_color(void),
mode_chase_random(void),
mode_chase_rainbow(void),
mode_chase_flash(void),
mode_chase_flash_random(void),
mode_chase_rainbow_white(void),
mode_colorful(void),
mode_traffic_light(void),
mode_color_sweep_random(void),
mode_running_color(void),
mode_running_red_blue(void),
mode_running_random(void),
mode_larson_scanner(void),
mode_comet(void),
mode_fireworks(void),
mode_fireworks_random(void),
mode_merry_christmas(void),
mode_fire_flicker(void),
mode_gradient(void),
mode_loading(void),
mode_dual_color_wipe_in_out(void),
mode_dual_color_wipe_in_in(void),
mode_dual_color_wipe_out_out(void),
mode_dual_color_wipe_out_in(void),
mode_circus_combustus(void),
mode_cc_core(void),
mode_cc_standard(void),
mode_cc_rainbow(void),
mode_cc_cycle(void),
mode_cc_blink(void),
mode_cc_random(void);
bool
_triggered,
_fastStandard,
_reverseMode,
_cronixieMode,
_cronixieBacklightEnabled,
_cc_fs,
_cc_fe,
_running;
bool*
_locked;
byte
minval(byte v, byte w),
maxval(byte v, byte w),
_mode_index,
_speed,
_intensity,
_cc_i1,
_cc_i2,
_cc_is,
_cc_num1,
_cc_num2,
_ccStep,
_brightness;
byte*
_cronixieDigits;
uint16_t
_led_count;
uint32_t
getPixelColor(uint16_t i),
_color,
_color_sec,
_counter_mode_call,
_counter_mode_step,
_counter_ccStep,
_mode_var1,
_mode_color,
_mode_delay;
double
_cronixieSecMultiplier;
unsigned long
_mode_last_call_time;
mode_ptr
_mode[MODE_COUNT];
};
#endif

View File

@@ -0,0 +1,124 @@
/*
Editor: https://www.visualmicro.com/
This file is for intellisense purpose only.
Visual micro (and the arduino ide) ignore this code during compilation. This code is automatically maintained by visualmicro, manual changes to this file will be overwritten
The contents of the _vm sub folder can be deleted prior to publishing a project
All non-arduino files created by visual micro and all visual studio project or solution files can be freely deleted and are not required to compile a sketch (do not delete your own code!).
Note: debugger breakpoints are stored in '.sln' or '.asln' files, knowledge of last uploaded breakpoints is stored in the upload.vmps.xml file. Both files are required to continue a previous debug session without needing to compile and upload again
Hardware: ESP32 Dev Module, Platform=esp32, Package=esp32
*/
#if defined(_VMICRO_INTELLISENSE)
#ifndef _VSARDUINO_H_
#define _VSARDUINO_H_
#define __ESP32_esp32__
#define __ESP32_ESP32__
#define ESP_PLATFORM
#define HAVE_CONFIG_H
#define GCC_NOT_5_2_0 0
#define WITH_POSIX
#define F_CPU 240000000L
#define ARDUINO 108011
#define ARDUINO_ESP32_DEV
#define ARDUINO_ARCH_ESP32
#define ESP32
#define CORE_DEBUG_LEVEL 0
#define __cplusplus 201103L
#define _Pragma(x)
#undef __cplusplus
#define __cplusplus 201103L
#define __STDC__
#define __ARM__
#define __arm__
#define __inline__
#define __asm__(...)
#define __extension__
#define __ATTR_PURE__
#define __ATTR_CONST__
#define __volatile__
#define __ASM
#define __INLINE
#define __attribute__(noinline)
//#define _STD_BEGIN
//#define EMIT
#define WARNING
#define _Lockit
#define __CLR_OR_THIS_CALL
#define C4005
#define _NEW
typedef bool _Bool;
typedef int _read;
typedef int _seek;
typedef int _write;
typedef int _close;
typedef int __cleanup;
//#define inline
#define __builtin_clz
#define __builtin_clzl
#define __builtin_clzll
#define __builtin_labs
#define __builtin_va_list
typedef int __gnuc_va_list;
#define __ATOMIC_ACQ_REL
#define __CHAR_BIT__
#define _EXFUN()
typedef unsigned char byte;
extern "C" void __cxa_pure_virtual() {;}
typedef long __INTPTR_TYPE__ ;
typedef long __UINTPTR_TYPE__ ;
typedef long __SIZE_TYPE__ ;
typedef long __PTRDIFF_TYPE__;
typedef long pthread_t;
typedef long pthread_key_t;
typedef long pthread_once_t;
typedef long pthread_mutex_t;
typedef long pthread_mutex_t;
typedef long pthread_cond_t;
#include "arduino.h"
#include <pins_arduino.h>
#define interrupts() sei()
#define noInterrupts() cli()
#define ESP_LOGI(tag, ...)
#include "wled00.ino"
#include "wled01_eeprom.ino"
#include "wled02_xml.ino"
#include "wled03_set.ino"
#include "wled04_file.ino"
#include "wled05_init.ino"
#include "wled06_usermod.ino"
#include "wled07_notify.ino"
#include "wled08_led.ino"
#include "wled09_button.ino"
#include "wled10_ntp.ino"
#include "wled11_ol.ino"
#include "wled12_alexa.ino"
#include "wled13_cronixie.ino"
#include "wled14_colors.ino"
#include "wled15_hue.ino"
#include "wled16_blynk.ino"
#include "wled17_mqtt.ino"
#include "wled18_server.ino"
#include "wled19_json.ino"
#include "wled20_ir.ino"
#endif
#endif

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

97
wled00/alexa.cpp Normal file
View File

@@ -0,0 +1,97 @@
#include "wled.h"
/*
* Alexa Voice On/Off/Brightness/Color Control. Emulates a Philips Hue bridge to Alexa.
*
* This was put together from these two excellent projects:
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
* https://github.com/probonopd/ESP8266HueEmulator
*/
#include "src/dependencies/espalexa/EspalexaDevice.h"
#ifndef WLED_DISABLE_ALEXA
void onAlexaChange(EspalexaDevice* dev);
void alexaInit()
{
if (alexaEnabled && WLED_CONNECTED)
{
if (espalexaDevice == nullptr) //only init once
{
espalexaDevice = new EspalexaDevice(alexaInvocationName, onAlexaChange, EspalexaDeviceType::extendedcolor);
espalexa.addDevice(espalexaDevice);
espalexa.begin(&server);
} else {
espalexaDevice->setName(alexaInvocationName);
}
}
}
void handleAlexa()
{
if (!alexaEnabled || !WLED_CONNECTED) return;
espalexa.loop();
}
void onAlexaChange(EspalexaDevice* dev)
{
EspalexaDeviceProperty m = espalexaDevice->getLastChangedProperty();
if (m == EspalexaDeviceProperty::on)
{
if (!macroAlexaOn)
{
if (bri == 0)
{
bri = briLast;
colorUpdated(NOTIFIER_CALL_MODE_ALEXA);
}
} else applyMacro(macroAlexaOn);
} else if (m == EspalexaDeviceProperty::off)
{
if (!macroAlexaOff)
{
if (bri > 0)
{
briLast = bri;
bri = 0;
colorUpdated(NOTIFIER_CALL_MODE_ALEXA);
}
} else applyMacro(macroAlexaOff);
} else if (m == EspalexaDeviceProperty::bri)
{
bri = espalexaDevice->getValue();
colorUpdated(NOTIFIER_CALL_MODE_ALEXA);
} else //color
{
if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white
{
uint16_t ct = espalexaDevice->getCt();
if (useRGBW)
{
switch (ct) { //these values empirically look good on RGBW
case 199: col[0]=255; col[1]=255; col[2]=255; col[3]=255; break;
case 234: col[0]=127; col[1]=127; col[2]=127; col[3]=255; break;
case 284: col[0]= 0; col[1]= 0; col[2]= 0; col[3]=255; break;
case 350: col[0]=130; col[1]= 90; col[2]= 0; col[3]=255; break;
case 383: col[0]=255; col[1]=153; col[2]= 0; col[3]=255; break;
}
} else {
colorCTtoRGB(ct, col);
}
} else {
uint32_t color = espalexaDevice->getRGB();
col[0] = ((color >> 16) & 0xFF);
col[1] = ((color >> 8) & 0xFF);
col[2] = ( color & 0xFF);
}
colorUpdated(NOTIFIER_CALL_MODE_ALEXA);
}
}
#else
void alexaInit(){}
void handleAlexa(){}
#endif

97
wled00/blynk.cpp Normal file
View File

@@ -0,0 +1,97 @@
#include "wled.h"
#include "src/dependencies/blynk/Blynk/BlynkHandlers.h"
/*
* Remote light control with the free Blynk app
*/
uint16_t blHue = 0;
byte blSat = 255;
void initBlynk(const char* auth)
{
#ifndef WLED_DISABLE_BLYNK
if (!WLED_CONNECTED) return;
blynkEnabled = (auth[0] != 0);
if (blynkEnabled) Blynk.config(auth);
#endif
}
void handleBlynk()
{
#ifndef WLED_DISABLE_BLYNK
if (WLED_CONNECTED && blynkEnabled)
Blynk.run();
#endif
}
void updateBlynk()
{
#ifndef WLED_DISABLE_BLYNK
if (!WLED_CONNECTED) return;
Blynk.virtualWrite(V0, bri);
//we need a RGB -> HSB convert here
Blynk.virtualWrite(V3, bri? 1:0);
Blynk.virtualWrite(V4, effectCurrent);
Blynk.virtualWrite(V5, effectSpeed);
Blynk.virtualWrite(V6, effectIntensity);
Blynk.virtualWrite(V7, nightlightActive);
Blynk.virtualWrite(V8, notifyDirect);
#endif
}
#ifndef WLED_DISABLE_BLYNK
BLYNK_WRITE(V0)
{
bri = param.asInt();//bri
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V1)
{
blHue = param.asInt();//hue
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V2)
{
blSat = param.asInt();//sat
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V3)
{
bool on = (param.asInt()>0);
if (!on != !bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BLYNK);}
}
BLYNK_WRITE(V4)
{
effectCurrent = param.asInt()-1;//fx
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V5)
{
effectSpeed = param.asInt();//sx
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V6)
{
effectIntensity = param.asInt();//ix
colorUpdated(NOTIFIER_CALL_MODE_BLYNK);
}
BLYNK_WRITE(V7)
{
nightlightActive = (param.asInt()>0);
}
BLYNK_WRITE(V8)
{
notifyDirect = (param.asInt()>0); //send notifications
}
#endif

121
wled00/button.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "wled.h"
/*
* Physical IO
*/
void shortPressAction()
{
if (!macroButton)
{
toggleOnOff();
colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
} else {
applyMacro(macroButton);
}
}
void handleButton()
{
#ifdef BTNPIN
if (!buttonEnabled) return;
if (digitalRead(BTNPIN) == LOW) //pressed
{
if (!buttonPressedBefore) buttonPressedTime = millis();
buttonPressedBefore = true;
if (millis() - buttonPressedTime > 600) //long press
{
if (!buttonLongPressed)
{
if (macroLongPress) {applyMacro(macroLongPress);}
else _setRandomColor(false,true);
buttonLongPressed = true;
}
}
}
else if (digitalRead(BTNPIN) == HIGH && buttonPressedBefore) //released
{
long dur = millis() - buttonPressedTime;
if (dur < 50) {buttonPressedBefore = false; return;} //too short "press", debounce
bool doublePress = buttonWaitTime;
buttonWaitTime = 0;
if (dur > 6000) //long press
{
WLED::instance().initAP(true);
}
else if (!buttonLongPressed) { //short press
if (macroDoublePress)
{
if (doublePress) applyMacro(macroDoublePress);
else buttonWaitTime = millis();
} else shortPressAction();
}
buttonPressedBefore = false;
buttonLongPressed = false;
}
if (buttonWaitTime && millis() - buttonWaitTime > 450 && !buttonPressedBefore)
{
buttonWaitTime = 0;
shortPressAction();
}
#endif
}
void handleIO()
{
handleButton();
//set relay when LEDs turn on
if (strip.getBrightness())
{
lastOnTime = millis();
if (offMode)
{
#if RLYPIN >= 0
digitalWrite(RLYPIN, RLYMDE);
#endif
offMode = false;
}
} else if (millis() - lastOnTime > 600)
{
#if RLYPIN >= 0
if (!offMode) digitalWrite(RLYPIN, !RLYMDE);
#endif
offMode = true;
}
#if AUXPIN >= 0
//output
if (auxActive || auxActiveBefore)
{
if (!auxActiveBefore)
{
auxActiveBefore = true;
switch (auxTriggeredState)
{
case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
}
auxStartTime = millis();
}
if ((millis() - auxStartTime > auxTime*1000 && auxTime != 255) || !auxActive)
{
auxActive = false;
auxActiveBefore = false;
switch (auxDefaultState)
{
case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
}
}
}
#endif
}

196
wled00/colors.cpp Normal file
View File

@@ -0,0 +1,196 @@
#include "wled.h"
/*
* Color conversion methods
*/
void colorFromUint32(uint32_t in, bool secondary)
{
if (secondary) {
colSec[3] = in >> 24 & 0xFF;
colSec[0] = in >> 16 & 0xFF;
colSec[1] = in >> 8 & 0xFF;
colSec[2] = in & 0xFF;
} else {
col[3] = in >> 24 & 0xFF;
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
}
//load a color without affecting the white channel
void colorFromUint24(uint32_t in, bool secondary)
{
if (secondary) {
colSec[0] = in >> 16 & 0xFF;
colSec[1] = in >> 8 & 0xFF;
colSec[2] = in & 0xFF;
} else {
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
}
//relatively change white brightness, minumum A=5
void relativeChangeWhite(int8_t amount, byte lowerBoundary)
{
int16_t new_val = (int16_t) col[3] + amount;
if (new_val > 0xFF) new_val = 0xFF;
else if (new_val < lowerBoundary) new_val = lowerBoundary;
col[3] = new_val;
}
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
{
float h = ((float)hue)/65535.0;
float s = ((float)sat)/255.0;
byte i = floor(h*6);
float f = h * 6-i;
float p = 255 * (1-s);
float q = 255 * (1-f*s);
float t = 255 * (1-(1-f)*s);
switch (i%6) {
case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break;
case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break;
case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break;
case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break;
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
}
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
}
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
{
//this is only an approximation using WS2812B with gamma correction enabled
if (mired > 475) {
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
} else if (mired > 425) {
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
} else if (mired > 375) {
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
} else if (mired > 325) {
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
} else if (mired > 275) {
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
} else if (mired > 225) {
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
} else if (mired > 175) {
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
} else {
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
}
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
}
#ifndef WLED_DISABLE_HUESYNC
void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float z = 1.0f - x - y;
float X = (1.0f / y) * x;
float Z = (1.0f / y) * z;
float r = (int)255*(X * 1.656492f - 0.354851f - Z * 0.255038f);
float g = (int)255*(-X * 0.707196f + 1.655397f + Z * 0.036152f);
float b = (int)255*(X * 0.051713f - 0.121364f + Z * 1.011530f);
if (r > b && r > g && r > 1.0f) {
// red is too big
g = g / r;
b = b / r;
r = 1.0f;
} else if (g > b && g > r && g > 1.0f) {
// green is too big
r = r / g;
b = b / g;
g = 1.0f;
} else if (b > r && b > g && b > 1.0f) {
// blue is too big
r = r / b;
g = g / b;
b = 1.0f;
}
// Apply gamma correction
r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * pow(g, (1.0f / 2.4f)) - 0.055f;
b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
if (r > b && r > g) {
// red is biggest
if (r > 1.0f) {
g = g / r;
b = b / r;
r = 1.0f;
}
} else if (g > b && g > r) {
// green is biggest
if (g > 1.0f) {
r = r / g;
b = b / g;
g = 1.0f;
}
} else if (b > r && b > g) {
// blue is biggest
if (b > 1.0f) {
r = r / b;
g = g / b;
b = 1.0f;
}
}
rgb[0] = 255.0*r;
rgb[1] = 255.0*g;
rgb[2] = 255.0*b;
if (useRGBW) colorRGBtoRGBW(col);
}
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float X = rgb[0] * 0.664511f + rgb[1] * 0.154324f + rgb[2] * 0.162028f;
float Y = rgb[0] * 0.283881f + rgb[1] * 0.668433f + rgb[2] * 0.047685f;
float Z = rgb[0] * 0.000088f + rgb[1] * 0.072310f + rgb[2] * 0.986039f;
xy[0] = X / (X + Y + Z);
xy[1] = Y / (X + Y + Z);
}
#endif // WLED_DISABLE_HUESYNC
void colorFromDecOrHexString(byte* rgb, char* in)
{
if (in[0] == 0) return;
char first = in[0];
uint32_t c = 0;
if (first == '#' || first == 'h' || first == 'H') //is HEX encoded
{
c = strtoul(in +1, NULL, 16);
} else
{
c = strtoul(in, NULL, 10);
}
rgb[3] = (c >> 24) & 0xFF;
rgb[0] = (c >> 16) & 0xFF;
rgb[1] = (c >> 8) & 0xFF;
rgb[2] = c & 0xFF;
}
float minf (float v, float w)
{
if (w > v) return v;
return w;
}
float maxf (float v, float w)
{
if (w > v) return w;
return v;
}
void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY)
{
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
if (high < 0.1f) return;
float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255)
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
}

107
wled00/const.h Normal file
View File

@@ -0,0 +1,107 @@
#ifndef WLED_CONST_H
#define WLED_CONST_H
/*
* Readability defines and their associated numerical values + compile-time constants
*/
//Defaults
#define DEFAULT_CLIENT_SSID "Your_Network"
#define DEFAULT_AP_PASS "wled1234"
#define DEFAULT_OTA_PASS "wledota"
//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost)
#define AP_BEHAVIOR_ALWAYS 2 //Always open
#define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec
//Notifier callMode
#define NOTIFIER_CALL_MODE_INIT 0 //no updates on init, can be used to disable updates
#define NOTIFIER_CALL_MODE_DIRECT_CHANGE 1
#define NOTIFIER_CALL_MODE_BUTTON 2
#define NOTIFIER_CALL_MODE_NOTIFICATION 3
#define NOTIFIER_CALL_MODE_NIGHTLIGHT 4
#define NOTIFIER_CALL_MODE_NO_NOTIFY 5
#define NOTIFIER_CALL_MODE_FX_CHANGED 6 //no longer used
#define NOTIFIER_CALL_MODE_HUE 7
#define NOTIFIER_CALL_MODE_PRESET_CYCLE 8
#define NOTIFIER_CALL_MODE_BLYNK 9
#define NOTIFIER_CALL_MODE_ALEXA 10
//RGB to RGBW conversion mode
#define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider
#define RGBW_MODE_AUTO_BRIGHTER 1 //New algorithm. Adds as much white as the darkest RGBW channel
#define RGBW_MODE_AUTO_ACCURATE 2 //New algorithm. Adds as much white as the darkest RGBW channel and subtracts this amount from each RGB channel
#define RGBW_MODE_DUAL 3 //Manual slider + auto calculation. Automatically calculates only if manual slider is set to off (0)
#define RGBW_MODE_LEGACY 4 //Old floating algorithm. Too slow for realtime and palette support
//realtime modes
#define REALTIME_MODE_INACTIVE 0
#define REALTIME_MODE_GENERIC 1
#define REALTIME_MODE_UDP 2
#define REALTIME_MODE_HYPERION 3
#define REALTIME_MODE_E131 4
#define REALTIME_MODE_ADALIGHT 5
#define REALTIME_MODE_ARTNET 6
//realtime override modes
#define REALTIME_OVERRIDE_NONE 0
#define REALTIME_OVERRIDE_ONCE 1
#define REALTIME_OVERRIDE_ALWAYS 2
//E1.31 DMX modes
#define DMX_MODE_DISABLED 0 //not used
#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels)
#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels)
#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels)
#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels)
#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels)
//Light capability byte (unused)
#define TYPE_NONE 0 //light is not configured
#define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light
#define TYPE_WS2812_RGB 2
#define TYPE_SK6812_RGBW 3
#define TYPE_WS2812_WWA 4 //amber + warm + cold white
#define TYPE_WS2801 5
#define TYPE_ANALOG_1CH 6 //single channel PWM. Uses value of brightest RGBW channel
#define TYPE_ANALOG_2CH 7 //analog WW + CW
#define TYPE_ANALOG_3CH 8 //analog RGB
#define TYPE_ANALOG_4CH 9 //analog RGBW
#define TYPE_ANALOG_5CH 10 //analog RGB + WW + CW
#define TYPE_APA102 11
#define TYPE_LPD8806 12
//Hue error codes
#define HUE_ERROR_INACTIVE 0
#define HUE_ERROR_UNAUTHORIZED 1
#define HUE_ERROR_LIGHTID 3
#define HUE_ERROR_PUSHLINK 101
#define HUE_ERROR_JSON_PARSING 250
#define HUE_ERROR_TIMEOUT 251
#define HUE_ERROR_ACTIVE 255
//Segment option byte bits
#define SEG_OPTION_SELECTED 0
#define SEG_OPTION_REVERSED 1
#define SEG_OPTION_ON 2
#define SEG_OPTION_TRANSITIONAL 7
//EEPROM size
#define EEPSIZE 2560 //Maximum is 4096
#define NTP_PACKET_SIZE 48
// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue
#define MAX_LEDS 1500
#define MAX_LEDS_DMA 500
// string temp buffer (now stored in stack locally)
#define OMAX 2048
#define E131_MAX_UNIVERSE_COUNT 9
#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit
#endif

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

100
wled00/data/jsontest.htm Normal file
View File

@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<head>
<title>JSON client</title>
<style>
:root {
--bCol:#333;--cCol:#222;--dCol:#666;--tCol:#fff;
}
body {
font-family: Verdana, sans-serif;
text-align: center;
background: var(--cCol);
color: var(--tCol);
margin: 20px;
background-attachment: fixed;
}
button {
background: var(--cCol);
color: var(--tCol);
border: 0.3ch solid var(--cCol);
display: inline-block;
font-size: 20px;
margin: 8px;
margin-top: 12px;
}
input {
background: var(--cCol);
color: var(--tCol);
border: 0.5ch solid var(--cCol);
width: 100%;
}
h1{
margin: 0px;
font-size: 20px;
}
h2{
font-size: 16px;
margin-top: 20px;
}
form{
background: var(--bCol);
width: 500px;
padding: 20px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
display: inline-block;
}
textarea{
background: var(--cCol);
color: var(--tCol);
padding-top: 10px;
width: 100%;
font-family: monaco,monospace;
font-size: 12px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
</style>
</head>
<body>
<form name="cf">
<h1>JSON API test tool</h1>
<h2>URL:</h2>
<input name="cu" type="text" size="60" value="http://192.168.4.1/json">
<div id="buttons">
<button type="button" onclick="rq('GET')">GET</button>
<button type="button" onclick="rq('POST')">POST</button>
</div>
<h2>Body:</h2>
<textarea name="bd" rows="8" cols="100"></textarea>
<h2>Response:</h2>
<textarea name="rsp" rows="25" cols="100"></textarea>
</form>
</body>
</html>
<script>
function rq(cm)
{
var h = new XMLHttpRequest();
h.open(cm, document.cf.cu.value, true);
h.onreadystatechange = function()
{
if(h.readyState == 4)
{
if(h.status==200)
{
document.cf.rsp.value="Bad JSON: "+h.responseText
document.cf.rsp.value=JSON.stringify(JSON.parse(h.responseText), null, '\t');
}
else
{
document.cf.rsp.value="Error "+h.status+"\r\n\n"+h.responseText;
}
}
}
h.send(document.cf.bd.value);
}
</script>

64
wled00/data/liveview.htm Normal file
View File

@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta charset="utf-8">
<meta name="theme-color" content="#222222">
<title>WLED Live Preview</title>
<style>
body {
margin: 0;
}
#canv {
background: black;
filter: brightness(175%);
width: 100%;
height: 100%;
position: absolute;
}
</style>
</head>
<body>
<div id="canv" />
<script>
update();
var tmout = null;
function update()
{
if (document.hidden) {
clearTimeout(tmout);
tmout = setTimeout(update, 250);
return;
}
fetch('/json/live')
.then(res => {
if (!res.ok) {
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
}
return res.json();
})
.then(json => {
var str = "linear-gradient(90deg,";
var len = json.leds.length;
for (i = 0; i < len; i++) {
var leddata = json.leds[i];
if (leddata.length > 6) leddata = leddata.substring(2);
str += "#" + leddata;
if (i < len -1) str += ","
}
str += ")";
document.getElementById("canv").style.background = str;
clearTimeout(tmout);
tmout = setTimeout(update, 40);
})
.catch(function (error) {
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
})
}
</script>
</body>
</html>

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html><head>
<meta content='width=device-width' name='viewport'>
<title>WLED Message</title>
<script>
function B() {
@@ -9,7 +10,7 @@
window.location = "/settings";
}
function RP() {
top.location.href=top.location.href;
top.location.href="/";
}
</script>
<style>
@@ -22,7 +23,7 @@
--tCol: #328CC1;
--cFn: Verdana;
}
button {
.bt {
background: var(--bCol);
color: var(--tCol);
border: 0.3ch solid var(--bCol);
@@ -33,6 +34,9 @@
margin: 8px;
margin-top: 12px;
}
input[type=file] {
font-size: 16px;
}
body {
font-family: var(--cFn), sans-serif;
text-align: center;
@@ -46,6 +50,7 @@
</head>
<body>
<h2>Sample message.</h2>
Sample detail.
</body>
</html>

View File

@@ -19,6 +19,9 @@
margin: 0;
background-attachment: fixed;
}
html {
--h:11.55vh;
}
button {
background: var(--bCol);
color: var(--tCol);
@@ -27,13 +30,23 @@
display: inline-block;
filter: drop-shadow( -5px -5px 5px var(--sCol) );
font-size: 8vmin;
height:13.86vh;
height:var(--h);
width: 95%;
margin-top: 2.4vh;
}
</style>
<script>
function BB()
{
if (window.frameElement) {
document.getElementById("b").style.display = "none";
document.documentElement.style.setProperty('--h',"13.86vh");
}
}
</script>
</head>
<body>
<body onload="BB()">
<form action="/"><button type=submit id="b">Back</button></form>
<form action="/settings/wifi"><button type="submit">WiFi Setup</button></form>
<form action="/settings/leds"><button type="submit">LED Preferences</button></form>
<form action="/settings/ui"><button type="submit">User Interface</button></form>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

4
wled00/data/update.htm Normal file
View File

@@ -0,0 +1,4 @@
<!DOCTYPE html>
<html><head><meta content='width=device-width' name='viewport'><title>WLED Message</title><script>function B(){window.history.back()}</script>
<style>:root{--aCol:#D9B310;--bCol:#0B3C5D;--cCol:#1D2731;--dCol:#328CC1;--sCol:#000;--tCol:#328CC1;--cFn:Verdana;}.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%}</style></head>
<body><h2>WLED Software Update</h2>Installed version: 0.8.5-dev<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>

View File

@@ -1,28 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content='width=device-width' name='viewport'>
<meta name="theme-color" content="#333333">
<title>WLED Setup</title>
<style>
:root {
--aCol: #D9B310;
--bCol: #0B3C5D;
--cCol: #1D2731;
--dCol: #328CC1;
--sCol: #000;
}
body {
font-family: Verdana, Helvetica, sans-serif;
text-align: center;
background: linear-gradient(var(--bCol),black);
height: 100%;
background-color: #333;
margin: 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: var(--dCol);
color: #fff;
}
button {
outline: none;
cursor: pointer;
padding: 8px;
margin: 10px;
width: 230px;
text-transform: uppercase;
font-family: helvetica;
font-size: 19px;
background-color: #222;
color: white;
border: 0px solid white;
border-radius: 5px;
}
svg {
fill: var(--dCol);
fill: #fff;
}
</style>
</head>
@@ -35,10 +43,12 @@
<svg><use xlink:href="#lnr-smile"></use></svg>
<h1>Welcome to WLED!</h1>
<h3>Thank you for installing my application!</h3>
Take a quick look at the <a href="https://github.com/Aircoookie/WLED/wiki" target="_blank">wiki</a>!<br>
If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br>
<b>Next steps:</b><br><br>
Connect the module to your local WiFi <a href="/settings/wifi">here</a>!<br><br>
<i>Just trying this out in AP mode?</i> <a href="/sliders">Here are the controls.</a><br>
Connect the module to your local WiFi here!<br>
<button onclick="window.location.href='/settings/wifi'">WiFi settings</button><br>
<i>Just trying this out in AP mode?</i><br>
<button onclick="window.location.href='/sliders'">To the controls!</button>
</body>
</html>

67
wled00/dmx.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include "wled.h"
/*
* Support for DMX via MAX485.
* Change the output pin in src/dependencies/ESPDMX.cpp if needed.
* Library from:
* https://github.com/Rickgg/ESP-Dmx
*/
#ifdef WLED_ENABLE_DMX
#include "src/dependencies/dmx/ESPDMX.h"
DMXESPSerial dmx;
void handleDMX()
{
// TODO: calculate brightness manually if no shutter channel is set
uint8_t brightness = strip.getBrightness();
for (int i = DMXStartLED; i < ledCount; i++) { // uses the amount of LEDs as fixture count
uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462
byte w = in >> 24 & 0xFF;
byte r = in >> 16 & 0xFF;
byte g = in >> 8 & 0xFF;
byte b = in & 0xFF;
int DMXFixtureStart = DMXStart + (DMXGap * (i - DMXStartLED));
for (int j = 0; j < DMXChannels; j++) {
int DMXAddr = DMXFixtureStart + j;
switch (DMXFixtureMap[j]) {
case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off.
dmx.write(DMXAddr, 0);
break;
case 1: // Red
dmx.write(DMXAddr, r);
break;
case 2: // Green
dmx.write(DMXAddr, g);
break;
case 3: // Blue
dmx.write(DMXAddr, b);
break;
case 4: // White
dmx.write(DMXAddr, w);
break;
case 5: // Shutter channel. Controls the brightness.
dmx.write(DMXAddr, brightness);
break;
case 6: // Sets this channel to 255. Like 0, but more wholesome.
dmx.write(DMXAddr, 255);
break;
}
}
}
dmx.update(); // update the DMX bus
}
void initDMX() {
dmx.init(512); // initialize with bus length
}
#else
void handleDMX() {}
void initDMX() {}
#endif

167
wled00/e131.cpp Normal file
View File

@@ -0,0 +1,167 @@
#include "wled.h"
/*
* E1.31 handler
*/
void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
//E1.31 protocol support
uint16_t uni = 0, dmxChannels = 0;
uint8_t* e131_data = nullptr;
uint8_t seq = 0, mde = REALTIME_MODE_E131;
if (isArtnet)
{
uni = p->art_universe;
dmxChannels = htons(p->art_length);
e131_data = p->art_data;
seq = p->art_sequence_number;
mde = REALTIME_MODE_ARTNET;
} else {
uni = htons(p->universe);
dmxChannels = htons(p->property_value_count) -1;
e131_data = p->property_values;
seq = p->sequence_number;
}
// only listen for universes we're handling & allocated memory
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
uint8_t previousUniverses = uni - e131Universe;
uint16_t possibleLEDsInCurrentUniverse;
if (e131SkipOutOfSequence)
if (seq < e131LastSequenceNumber[uni-e131Universe] && seq > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
DEBUG_PRINT("skipping E1.31 frame (last seq=");
DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]);
DEBUG_PRINT(", current seq=");
DEBUG_PRINT(seq);
DEBUG_PRINT(", universe=");
DEBUG_PRINT(uni);
DEBUG_PRINTLN(")");
return;
}
e131LastSequenceNumber[uni-e131Universe] = seq;
// update status info
realtimeIP = clientIP;
byte wChannel = 0;
switch (DMXMode) {
case DMX_MODE_DISABLED:
return; // nothing to do
break;
case DMX_MODE_SINGLE_RGB:
if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 3) return;
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
wChannel = (dmxChannels-DMXAddress+1 > 3) ? e131_data[DMXAddress+3] : 0;
for (uint16_t i = 0; i < ledCount; i++)
setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], wChannel);
break;
case DMX_MODE_SINGLE_DRGB:
if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 4) return;
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
wChannel = (dmxChannels-DMXAddress+1 > 4) ? e131_data[DMXAddress+4] : 0;
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0];
bri = e131_data[DMXAddress+0];
strip.setBrightness(bri);
}
for (uint16_t i = 0; i < ledCount; i++)
setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], wChannel);
break;
case DMX_MODE_EFFECT:
if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 11) return;
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0];
bri = e131_data[DMXAddress+0];
}
if (e131_data[DMXAddress+1] < MODE_COUNT)
effectCurrent = e131_data[DMXAddress+ 1];
effectSpeed = e131_data[DMXAddress+ 2]; // flickers
effectIntensity = e131_data[DMXAddress+ 3];
effectPalette = e131_data[DMXAddress+ 4];
col[0] = e131_data[DMXAddress+ 5];
col[1] = e131_data[DMXAddress+ 6];
col[2] = e131_data[DMXAddress+ 7];
colSec[0] = e131_data[DMXAddress+ 8];
colSec[1] = e131_data[DMXAddress+ 9];
colSec[2] = e131_data[DMXAddress+10];
if (dmxChannels-DMXAddress+1 > 11)
{
col[3] = e131_data[DMXAddress+11]; //white
colSec[3] = e131_data[DMXAddress+12];
}
transitionDelayTemp = 0; // act fast
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP
return; // don't activate realtime live mode
break;
case DMX_MODE_MULTIPLE_RGB:
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
if (previousUniverses == 0) {
// first universe of this fixture
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
for (uint16_t i = 0; i < ledCount; i++) {
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
setRealtimePixel(i, e131_data[DMXAddress+i*3+0], e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], 0);
}
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
// additional universe(s) of this fixture
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
possibleLEDsInCurrentUniverse = dmxChannels / 3;
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
uint8_t j = i - numberOfLEDsInPreviousUniverses;
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
}
}
break;
case DMX_MODE_MULTIPLE_DRGB:
realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
if (previousUniverses == 0) {
// first universe of this fixture
if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0];
bri = e131_data[DMXAddress+0];
strip.setBrightness(bri);
}
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3;
for (uint16_t i = 0; i < ledCount; i++) {
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
setRealtimePixel(i, e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], e131_data[DMXAddress+i*3+3], 0);
}
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
// additional universe(s) of this fixture
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
possibleLEDsInCurrentUniverse = dmxChannels / 3;
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
uint8_t j = i - numberOfLEDsInPreviousUniverses;
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0);
}
}
break;
default:
DEBUG_PRINTLN("unknown E1.31 DMX mode");
return; // nothing to do
break;
}
e131NewData = true;
}

184
wled00/fcn_declare.h Normal file
View File

@@ -0,0 +1,184 @@
#ifndef WLED_FCN_DECLARE_H
#define WLED_FCN_DECLARE_H
#include <Arduino.h>
#include "src/dependencies/espalexa/EspalexaDevice.h"
#include "src/dependencies/e131/ESPAsyncE131.h"
/*
* All globally accessible functions are declared here
*/
//alexa.cpp
void onAlexaChange(EspalexaDevice* dev);
void alexaInit();
void handleAlexa();
void onAlexaChange(EspalexaDevice* dev);
//blynk.cpp
void initBlynk(const char* auth);
void handleBlynk();
void updateBlynk();
//button.cpp
void shortPressAction();
void handleButton();
void handleIO();
//colors.cpp
void colorFromUint32(uint32_t in, bool secondary = false);
void colorFromUint24(uint32_t in, bool secondary = false);
void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0);
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb
void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb
void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO
void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO
void colorFromDecOrHexString(byte* rgb, char* in);
void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY)
//dmx.cpp
void initDMX();
void handleDMX();
//e131.cpp
void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet);
//file.cpp
bool handleFileRead(AsyncWebServerRequest*, String path);
//hue.cpp
void handleHue();
void reconnectHue();
void onHueError(void* arg, AsyncClient* client, int8_t error);
void onHueConnect(void* arg, AsyncClient* client);
void sendHuePoll();
void onHueData(void* arg, AsyncClient* client, void *data, size_t len);
//ir.cpp
bool decodeIRCustom(uint32_t code);
void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF);
void changeEffectSpeed(int8_t amount);
void changeEffectIntensity(int8_t amount);
void decodeIR(uint32_t code);
void decodeIR24(uint32_t code);
void decodeIR24OLD(uint32_t code);
void decodeIR24CT(uint32_t code);
void decodeIR40(uint32_t code);
void decodeIR44(uint32_t code);
void decodeIR21(uint32_t code);
void decodeIR6(uint32_t code);
void initIR();
void handleIR();
//json.cpp
#include "ESPAsyncWebServer.h"
#include "src/dependencies/json/ArduinoJson-v6.h"
#include "src/dependencies/json/AsyncJson-v6.h"
#include "FX.h"
// TODO: AsynicWebServerRequest conflict?
void deserializeSegment(JsonObject elem, byte it);
bool deserializeState(JsonObject root);
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id);
void serializeState(JsonObject root);
void serializeInfo(JsonObject root);
void serveJson(AsyncWebServerRequest* request);
void serveLiveLeds(AsyncWebServerRequest* request);
//led.cpp
void setValuesFromMainSeg();
void resetTimebase();
void toggleOnOff();
void setAllLeds();
void setLedsStandard(bool justColors = false);
bool colorChanged();
void colorUpdated(int callMode);
void updateInterfaces(uint8_t callMode);
void handleTransitions();
void handleNightlight();
//mqtt.cpp
bool initMqtt();
void publishMqtt();
//ntp.cpp
void handleNetworkTime();
void sendNTPPacket();
bool checkNTPResponse();
void updateLocalTime();
void getTimeString(char* out);
bool checkCountdown();
void setCountdown();
byte weekdayMondayFirst();
void checkTimers();
//overlay.cpp
void initCronixie();
void handleOverlays();
void handleOverlayDraw();
void _overlayAnalogCountdown();
void _overlayAnalogClock();
byte getSameCodeLength(char code, int index, char const cronixieDisplay[]);
void setCronixie();
void _overlayCronixie();
void _drawOverlayCronixie();
//set.cpp
void _setRandomColor(bool _sec,bool fromButton=false);
bool isAsterisksOnly(const char* str, byte maxLen);
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage);
bool handleSet(AsyncWebServerRequest *request, const String& req);
int getNumVal(const String* req, uint16_t pos);
bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255);
//udp.cpp
void notify(byte callMode, bool followUp=false);
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
//usermod.cpp
void userSetup();
void userConnected();
void userLoop();
//wled_eeprom.cpp
void commit();
void clearEEPROM();
void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len);
void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len);
void saveSettingsToEEPROM();
void loadSettingsFromEEPROM(bool first);
void savedToPresets();
bool applyPreset(byte index, bool loadBri = true);
void savePreset(byte index, bool persist = true);
void loadMacro(byte index, char* m);
void applyMacro(byte index);
void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings
//wled_serial.cpp
void handleSerial();
//wled_server.cpp
bool isIp(String str);
bool captivePortal(AsyncWebServerRequest *request);
void initServer();
void serveIndexOrWelcome(AsyncWebServerRequest *request);
void serveIndex(AsyncWebServerRequest* request);
String msgProcessor(const String& var);
void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255);
String settingsProcessor(const String& var);
String dmxProcessor(const String& var);
void serveSettings(AsyncWebServerRequest* request);
//xml.cpp
char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr);
char* URL_response(AsyncWebServerRequest *request);
void sappend(char stype, const char* key, int val);
void sappends(char stype, const char* key, char* val);
void getSettingsJS(byte subPage, char* dest);
#endif

55
wled00/file.cpp Normal file
View File

@@ -0,0 +1,55 @@
#include "wled.h"
/*
* Utility for SPIFFS filesystem
*/
//filesystem
#ifndef WLED_DISABLE_FILESYSTEM
#include <FS.h>
#ifdef ARDUINO_ARCH_ESP32
#include "SPIFFS.h"
#endif
#include "SPIFFSEditor.h"
#endif
#if !defined WLED_DISABLE_FILESYSTEM && defined WLED_ENABLE_FS_SERVING
//Un-comment any file types you need
String getContentType(AsyncWebServerRequest* request, String filename){
if(request->hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
// else if(filename.endsWith(".css")) return "text/css";
// else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".json")) return "application/json";
else if(filename.endsWith(".png")) return "image/png";
// else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
// else if(filename.endsWith(".xml")) return "text/xml";
// else if(filename.endsWith(".pdf")) return "application/x-pdf";
// else if(filename.endsWith(".zip")) return "application/x-zip";
// else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
bool handleFileRead(AsyncWebServerRequest* request, String path){
DEBUG_PRINTLN("FileRead: " + path);
if(path.endsWith("/")) path += "index.htm";
String contentType = getContentType(request, path);
String pathWithGz = path + ".gz";
if(SPIFFS.exists(pathWithGz)){
request->send(SPIFFS, pathWithGz, contentType);
return true;
}
if(SPIFFS.exists(path)) {
request->send(SPIFFS, path, contentType);
return true;
}
return false;
}
#else
bool handleFileRead(AsyncWebServerRequest*, String path){return false;}
#endif

133
wled00/html_other.h Normal file
View File

@@ -0,0 +1,133 @@
/*
* Various web pages
*/
//USER HTML HERE (/u subpage)
const char PAGE_usermod[] PROGMEM = R"=====(<!DOCTYPE html>
<html><body>No usermod custom web page set.</body></html>)=====";
//server message
const char PAGE_msg[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta content='width=device-width' name='viewport'>
<title>WLED Message</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
<body><h2>%MSG%</body></html>)=====";
//DMX channel map
const char PAGE_dmxmap[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta content='width=device-width' name='viewport'>
<title>DMX Map</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}function FM() {%DMXVARS%
var dmxlabels = ["SET 0","RED","GREEN","BLUE","WHITE","SHUTTER","SET 255", "DISABLED"];
var dmxchans = [];
for (i=0;i<512;i++) {
dmxchans.push(7); // set all to DISABLED
}
for (i=0;i<LC;i++) {
FS = CS + (CG * i);
for (j=0;j<CN;j++) {
DA=FS+j;
dmxchans[DA-1] = CH[j];
}
}
DMXMap = "";
for (i=0;i<512;i++) {
isstart = "";
if ((i+1) % 10 == 0) {
isstart="S"
}
DMXMap += "<div class=\"anytype " + isstart + " type" + dmxchans[i] + "\">" + String(i+1) + "<br />" + dmxlabels[dmxchans[i]] + "</div>";
}
document.getElementById("map").innerHTML = DMXMap;
}</script>
<style>.anytype{border: 1px solid white; margin: 1px; float: left; width: 100px; height: 100px;}.S { margin: 0px; border: 2px solid white;} .type7{color: #888; border: 1px dotted grey;}.type6{color: #FFF;}.type4{color: #FFF; font-weight: bold; }.type3{color: #00F; font-weight: bold; }.type2{color: #0F0; font-weight: bold; }.type1{color: #F00; font-weight: bold; } .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
<body onload="FM();"><div id="map">...</div></body></html>)=====";
//firmware update page
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}</style></head>
<body><h2>WLED Software Update</h2>Installed version: 0.10.0<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
//new user welcome page
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><meta content='width=device-width' name=viewport><meta name=theme-color content=#333333><title>WLED Setup</title> <style>body{font-family:Verdana,Helvetica,sans-serif;text-align:center;background-color:#333;margin:0;color:#fff}button{outline:0;cursor:pointer}.btn{padding:8px;margin:10px;width:230px;text-transform:uppercase;font-family:helvetica;font-size:19px;background-color:#222;color:white;border:0 solid white;border-radius:5px}svg{fill:#fff}</style></head>
<body> <svg style=position:absolute;width:0;height:0;overflow:hidden version=1.1 xmlns=http://www.w3.org/2000/svg> <defs> <symbol id=lnr-smile viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol> </defs></svg> <br><br>
<svg><use xlink:href=#lnr-smile></use></svg><h1>Welcome to WLED!</h1><h3>Thank you for installing my application!</h3> If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br> <b>Next steps:</b><br><br> Connect the module to your local WiFi here!<br> <button class=btn onclick="window.location.href='/settings/wifi'">WiFi settings</button><br> <i>Just trying this out in AP mode?</i><br> <button class=btn onclick="window.location.href='/sliders'">To the controls!</button></body></html>)=====";
//liveview
const char PAGE_liveview[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head>
<meta name=viewport content="width=device-width, initial-scale=1, minimum-scale=1">
<meta charset=utf-8>
<meta name=theme-color content=#222222>
<title>WLED Live Preview</title>
<style>
body {margin: 0;}
#canv {background: black;filter: brightness(175%);width: 100%;height: 100%;position: absolute;}
</style></head>
<body>
<div id="canv" />
<script>
update();
var tmout = null;
function update()
{
if (document.hidden) {
clearTimeout(tmout);
tmout = setTimeout(update, 250);
return;
}
fetch('/json/live')
.then(res => {
if (!res.ok) {
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
}
return res.json();
})
.then(json => {
var str = "linear-gradient(90deg,";
var len = json.leds.length;
for (i = 0; i < len; i++) {
var leddata = json.leds[i];
if (leddata.length > 6) leddata = leddata.substring(2);
str += "#" + leddata;
if (i < len -1) str += ","
}
str += ")";
document.getElementById("canv").style.background = str;
clearTimeout(tmout);
tmout = setTimeout(update, 40);
})
.catch(function (error) {
clearTimeout(tmout);
tmout = setTimeout(update, 2500);
})
}
</script>
</body></html>)=====";
/*
* favicon
*/
const uint8_t favicon[] PROGMEM = {
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x00,
0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x89, 0x50,
0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48,
0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06,
0x00, 0x00, 0x00, 0x1F, 0xF3, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x4D, 0x49,
0x44, 0x41, 0x54, 0x38, 0x8D, 0x63, 0xFC, 0xFF, 0xFF, 0x3F, 0x03, 0xB1,
0x80, 0xD1, 0x9E, 0x01, 0x43, 0x31, 0x13, 0xD1, 0xBA, 0x71, 0x00, 0x8A,
0x0D, 0x60, 0x21, 0xA4, 0x00, 0xD9, 0xD9, 0xFF, 0x0F, 0x32, 0x30, 0x52,
0xDD, 0x05, 0xB4, 0xF1, 0x02, 0xB6, 0xD0, 0xA6, 0x99, 0x0B, 0x68, 0x1F,
0x0B, 0xD8, 0x42, 0x9E, 0xAA, 0x2E, 0xA0, 0xD8, 0x00, 0x46, 0x06, 0x3B,
0xCC, 0xCC, 0x40, 0xC8, 0xD9, 0x54, 0x75, 0x01, 0xE5, 0x5E, 0x20, 0x25,
0x3B, 0x63, 0x03, 0x00, 0x3E, 0xB7, 0x11, 0x5A, 0x8D, 0x1C, 0x07, 0xB4,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
};

484
wled00/html_settings.h Normal file
View File

@@ -0,0 +1,484 @@
/*
* Settings html
*/
//common CSS of settings pages
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}.d5{width:4.5em !important;}</style>)=====";
//settings menu
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><title>WLED Settings</title><style>body{text-align:center;background:#222;height:100%%;margin:0}html{--h:11.55vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:.3ch solid #333;display:inline-block;font-size:8vmin;height:var(--h);width:95%%;margin-top:2.4vh}</style>
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head>
<body onload=BB()>
<form action=/><button type=submit id=b>Back</button></form>
<form action=/settings/wifi><button type=submit>WiFi Setup</button></form>
<form action=/settings/leds><button type=submit>LED Preferences</button></form>
<form action=/settings/ui><button type=submit>User Interface</button></form>%DMXMENU%
<form action=/settings/sync><button type=submit>Sync Interfaces</button></form>
<form action=/settings/time><button type=submit>Time & Macros</button></form>
<form action=/settings/sec><button type=submit>Security & Updates</button></form>
</body></html>)=====";
//wifi settings
const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d=document;
%CSS%%SCSS%</head><body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
<h2>WiFi setup</h2>
<h3>Connect to existing network</h3>
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
Static IP (leave at 0.0.0.0 for DHCP):<br>
<input name="I0" type="number" min="0" max="255" required> .
<input name="I1" type="number" min="0" max="255" required> .
<input name="I2" type="number" min="0" max="255" required> .
<input name="I3" type="number" min="0" max="255" required><br>
Static gateway:<br>
<input name="G0" type="number" min="0" max="255" required> .
<input name="G1" type="number" min="0" max="255" required> .
<input name="G2" type="number" min="0" max="255" required> .
<input name="G3" type="number" min="0" max="255" required><br>
Static subnet mask:<br>
<input name="S0" type="number" min="0" max="255" required> .
<input name="S1" type="number" min="0" max="255" required> .
<input name="S2" type="number" min="0" max="255" required> .
<input name="S3" type="number" min="0" max="255" required><br>
mDNS address (leave empty for no mDNS):<br/>
http:// <input name="CM" maxlength="32"> .local<br>
Client IP: <span class="sip"> Not connected </span><br>
<h3>Configure Access Point</h3>
AP name (SSID):<br><input name="AS" maxlength="32"><br>
Hide AP name: <input type="checkbox" name="AH"><br>
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"><br>
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
AP opens:
<select name="AB">
<option value="0">No connection after boot</option>
<option value="1">Disconnected</option>
<option value="2">Always</option>
<option value="3">Never (not recommended)</option></select><br>
AP IP: <span class="sip"> Not active </span><br>
<h3>Experimental</h3>
Disable WiFi sleep: <input type="checkbox" name="WS"><br>
<i>Can help with connectivity issues.<br>
Do not enable if WiFi is working correctly, increases power consumption.</i>
<hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
</form>
</body>
</html>)=====";
//LED settings
const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head>
<meta charset=utf-8>
<meta name=viewport content="width=500">
<title>LED Settings</title>
<script>var d=document,laprev=55;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings")}function B(){window.open("/settings","_self")}function S(){GetV();setABL()}
function enABL(){var a=d.getElementById("able").checked;d.Sf.LA.value=(a)?laprev:0;d.getElementById("abl").style.display=(a)?"inline":"none";d.getElementById("psu2").style.display=(a)?"inline":"none";if(d.Sf.LA.value>0){setABL()}}function enLA(){var a=d.Sf.LAsel.value;d.Sf.LA.value=a;d.getElementById("LAdis").style.display=(a==50)?"inline":"none";UI()}function setABL(){d.getElementById("able").checked=true;d.Sf.LAsel.value=50;switch(parseInt(d.Sf.LA.value)){case 0:d.getElementById("able").checked=false;enABL();break;case 30:d.Sf.LAsel.value=30;break;case 35:d.Sf.LAsel.value=35;break;case 55:d.Sf.LAsel.value=55;break;case 255:d.Sf.LAsel.value=255;break;default:d.getElementById("LAdis").style.display="inline"}UI()}function UI(){var b=d.querySelectorAll(".wc"),a=b.length;for(i=0;i<a;i++){b[i].style.display=(d.getElementById("rgbw").checked)?"inline":"none"}d.getElementById("ledwarning").style.display=(d.Sf.LC.value>1000)?"inline":"none";d.getElementById("ampwarning").style.display=(d.Sf.MA.value>7200)?"inline":"none";if(d.Sf.LA.value==255){laprev=12} else if(d.Sf.LA.value>0){laprev=d.Sf.LA.value}var j=Math.ceil((100+d.Sf.LC.value*laprev)/500)/2;j=(j>5)?Math.ceil(j):j;var g="";var e=(d.Sf.LAsel.value==30);var i=(d.Sf.LAsel.value==255);if(j<1.02&&!e&&!i){g="ESP 5V pin with 1A USB supply"}else{g+=e?"12V ":i?"WS2815 12V ":"5V ";g+=j;g+="A supply connected to LEDs"}var h=Math.ceil((100+d.Sf.LC.value*laprev)/1500)/2;h=(h>5)?Math.ceil(h):h;var c="(for most effects, ~";c+=h;c+="A is enough)<br>";d.getElementById("psu").innerHTML=g;d.getElementById("psu2").innerHTML=i?"":c}function GetV(){var d=document;
%CSS%%SCSS%</head><body onload=S()>
<form id=form_s name=Sf method=post>
<div class=helpB><button type=button onclick=H()>?</button></div>
<button type=button onclick=B()>Back</button><button type=submit>Save</button><hr>
<h2>LED setup</h2>
LED count: <input name=LC type=number min=1 max=1500 oninput=UI() required><br>
<div id=ledwarning style=color:orange;display:none>
&#9888; You might run into stability or lag issues.<br>
Use less than 1000 LEDs per ESP for the best experience!<br>
</div>
<i>Recommended power supply for brightest white:</i><br>
<b><span id=psu>?</span></b><br>
<span id=psu2><br></span>
<br>
Enable automatic brightness limiter: <input type=checkbox name=ABen onchange=enABL() id=able><br>
<div id=abl>
Maximum Current: <input name=MA type=number min=250 max=65000 oninput=UI() required> mA<br>
<div id=ampwarning style=color:orange;display:none>
&#9888; Your power supply provides high current.<br>
To improve the safety of your setup,<br>
please use thick cables,<br>
multiple power injection points and a fuse!<br>
</div>
<i>Automatically limits brightness to stay close to the limit.<br>
Keep at &lt;1A if powering LEDs directly from the ESP 5V pin!<br>
If you are using an external power supply, enter its rating.<br>
(Current estimated usage: <span class=pow>unknown</span>)</i><br><br>
LED voltage (Max. current for a single LED):<br>
<select name=LAsel onchange=enLA()>
<option value=55 selected>5V default (55mA)</option>
<option value=35>5V efficient (35mA)</option>
<option value=30>12V (30mA)</option>
<option value=255>WS2815 (12mA)</option>
<option value=50>Custom</option>
</select><br>
<span id=LAdis style=display:none>Custom max. current per LED: <input name=LA type=number min=0 max=255 id=la oninput=UI() required> mA<br></span>
<i>Keep at default if you are unsure about your type of LEDs.</i><br>
</div>
<br>
LEDs are 4-channel type (RGBW): <input type=checkbox name=EW onchange=UI() id=rgbw><br>
<span class=wc>
Auto-calculate white channel from RGB:<br>
<select name=AW>
<option value=0>None</option>
<option value=1>Brighter</option>
<option value=2>Accurate</option>
<option value=3>Dual</option>
<option value=4>Legacy</option>
</select>
<br></span>
Color order:
<select name=CO>
<option value=0>GRB</option>
<option value=1>RGB</option>
<option value=2>BRG</option>
<option value=3>RBG</option>
<option value=4>BGR</option>
<option value=5>GBR</option>
</select>
<h3>Defaults</h3>
Turn LEDs on after power up/reset: <input type=checkbox name=BO><br>
Default brightness: <input name=CA type=number min=0 max=255 required> (0-255)<br><br>
Apply preset <input name=BP type=number min=0 max=16 required> at boot (0 uses defaults)
<br>- <i>or</i> -<br>
Set current preset cycle setting as boot default: <input type=checkbox name=PC><br><br>
Use Gamma correction for color: <input type=checkbox name=GC> (strongly recommended)<br>
Use Gamma correction for brightness: <input type=checkbox name=GB> (not recommended)<br><br>
Brightness factor: <input name=BF type=number min=1 max=255 required> %
<h3>Transitions</h3>
Crossfade: <input type=checkbox name=TF><br>
Transition Time: <input name=TD maxlength=5 size=2> ms<br>
Enable Palette transitions: <input type=checkbox name=PF>
<h3>Timed light</h3>
Default Duration: <input name=TL type=number min=1 max=255 required> min<br>
Default Target brightness: <input name=TB type=number min=0 max=255 required><br>
Fade down: <input type=checkbox name=TW><br>
<h3>Advanced</h3>
Palette blending:
<select name=PB>
<option value=0>Linear (wrap if moving)</option>
<option value=1>Linear (always wrap)</option>
<option value=2>Linear (never wrap)</option>
<option value=3>None (not recommended)</option>
</select><br>
Reverse LED order (rotate 180): <input type=checkbox name=RV><br>
Skip first LED: <input type=checkbox name=SL><hr>
<button type=button onclick=B()>Back</button><button type=submit>Save</button>
</form></body></html>)=====";
#ifdef WLED_ENABLE_DMX
//DMX Output settings
const char PAGE_settings_dmx[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>DMX Settings</title><script>
function GCH(num) {
d=document;
d.getElementById('dmxchannels').innerHTML += "";
for (i=0;i<num;i++) {
d.getElementById('dmxchannels').innerHTML += "<span id=CH" + (i+1) + "s >Channel " + (i+1) + ": <select name=CH" + (i+1) + " id=\"CH" + (i+1) + "\"><option value=0>Set to 0</option><option value=1>Red</option><option value=2>Green</option><option value=3>Blue</option><option value=4>White</option><option value=5>Shutter (Brightness)</option><option value=6>Set to 255</option></select></span><br />\n";
}
}
function mMap(){
d=document;
numCh=document.Sf.CN.value;
numGap=document.Sf.CG.value;
if (parseInt(numCh)>parseInt(numGap)) {
d.getElementById("gapwarning").style.display="block";
} else {
d.getElementById("gapwarning").style.display="none";
}
for (i=0;i<15;i++) {
if (i>=numCh) {
d.getElementById("CH"+(i+1) + "s").style.opacity = "0.5";
d.getElementById("CH"+(i+1)).disabled = true;
} else {
d.getElementById("CH"+(i+1) + "s").style.opacity = "1";
d.getElementById("CH"+(i+1)).disabled = false;
}
}
}
function S(){GCH(15);GetV();mMap();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX");}function B(){window.history.back();}function GetV(){var d=document;
%CSS%%SCSS%</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Imma firin ma lazer (if it has DMX support)</h2><!-- TODO: Change to something less-meme-related //-->
<i>Number of fixtures is taken from LED config page</i><br>
Channels per fixture (15 max): <input type="number" min="1" max="15" name="CN" maxlength="2" onchange="mMap();"><br />
Start channel: <input type="number" min="1" max="512" name="CS" maxlength="2"><br />
Spacing between start channels: <input type="number" min="1" max="512" name="CG" maxlength="2" onchange="mMap();"> [ <a href="javascript:alert('if set to 10, first fixture will start at 10,\nsecond will start at 20 etc.\nRegardless of the channel count.\nMakes memorizing channel numbers easier.');">info</a> ]<br>
<div id="gapwarning" style="color: orange; display: none;">WARNING: Channel gap is lower than channels per fixture.<br />This will cause overlap.</div>
<button type="button" onclick="location.href='/dmxmap';">DMX Map</button><br>
DMX fixtures start LED: <input type="number" min="0" max="1500" name="SL">
<h3>channel functions</h3>
<div id="dmxchannels"></div>
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>)=====";
#else
const char PAGE_settings_dmx[] PROGMEM = R"=====()=====";
#endif
//User Interface settings
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>UI Settings</title><script>
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d=document;
%CSS%%SCSS%</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Web Setup</h2>
Server description: <input name="DS" maxlength="32"><br>
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br><br>
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>)=====";
//sync settings
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name=viewport content="width=500"><meta charset=utf-8><title>Sync Settings</title>
<script>var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings")}function B(){window.open("/settings","_self")}function adj(){if(d.Sf.DI.value==6454){if(d.Sf.DA.value==1){d.Sf.DA.value=0}if(d.Sf.EU.value==1){d.Sf.EU.value=0}}else{if(d.Sf.DI.value==5568){if(d.Sf.DA.value==0){d.Sf.DA.value=1}if(d.Sf.EU.value==0){d.Sf.EU.value=1}}}}function SP(){var a=d.Sf.DI.value;d.getElementById("xp").style.display=(a>0)?"none":"block";if(a>0){d.Sf.EP.value=a}}function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568:d.Sf.DI.value=5568;break;case 6454:d.Sf.DI.value=6454;break}SP()}function S(){GetV();SetVal()};function GetV(){
%CSS%%SCSS%</head>
<body onload=S()>
<form id=form_s name=Sf method=post>
<div class=helpB><button type=button onclick=H()>?</button></div>
<button type=button onclick=B()>Back</button><button type=submit>Save</button><hr>
<h2>Sync setup</h2>
<h3>Button setup</h3>
On/Off button enabled: <input type=checkbox name=BT><br>
Infrared remote:
<select name=IR>
<option value=0>Disabled</option>
<option value=1>24-key RGB</option>
<option value=2>24-key with CT</option>
<option value=3>40-key blue</option>
<option value=4>44-key RGB</option>
<option value=5>21-key RGB</option>
<option value=6>6-key black</option>
</select><br>
<a href=https://github.com/Aircoookie/WLED/wiki/Infrared-Control target=_blank>IR info</a>
<h3>WLED Broadcast</h3>
UDP Port: <input name=UP type=number min=1 max=65535 class=d5 required><br>
Receive <input type=checkbox name=RB>Brightness, <input type=checkbox name=RC>Color, and <input type=checkbox name=RX>Effects<br>
Send notifications on direct change: <input type=checkbox name=SD><br>
Send notifications on button press: <input type=checkbox name=SB><br>
Send Alexa notifications: <input type=checkbox name=SA><br>
Send Philips Hue change notifications: <input type=checkbox name=SH><br>
Send Macro notifications: <input type=checkbox name=SM><br>
Send notifications twice: <input type=checkbox name=S2>
<h3>Realtime</h3>
Receive UDP realtime: <input type=checkbox name=RD><br><br>
<i>Network DMX input</i><br>
Type:
<select name=DI onchange=SP();adj()>
<option value=5568>E1.31 (sACN)</option>
<option value=6454>Art-Net</option>
<option value=0 selected>Custom port</option>
</select><br>
<div id=xp>Port: <input name=EP type=number min=1 max=65535 value=5568 class=d5 required><br></div>
Multicast: <input type=checkbox name=EM><br>
Start universe: <input name=EU type=number min=0 max=63999 required><br>
<i>Reboot required.</i> Check out <a href=https://github.com/ahodges9/LedFx target=_blank>LedFx</a>!<br>
Skip out-of-sequence packets: <input type=checkbox name=ES><br>
DMX start address: <input name=DA type=number min=0 max=510 required><br>
DMX mode:
<select name=DM>
<option value=0>Disabled</option>
<option value=1>Single RGB</option>
<option value=2>Single DRGB</option>
<option value=3>Effect</option>
<option value=4>Multi RGB</option>
<option value=5>Multi DRGB</option>
</select><br>
<a href=https://github.com/Aircoookie/WLED/wiki/E1.31-DMX target=_blank>E1.31 info</a><br>
Timeout: <input name=ET type=number min=1 max=65000 required> ms<br>
Force max brightness: <input type=checkbox name=FB><br>
Disable realtime gamma correction: <input type=checkbox name=RG><br>
Realtime LED offset: <input name=WO type=number min=-255 max=255 required>
<h3>Alexa Voice Assistant</h3>
Emulate Alexa device: <input type=checkbox name=AL><br>
Alexa invocation name: <input name=AI maxlength=32>
<h3>Blynk</h3>
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
This may impact the responsiveness of the ESP8266.</b><br>
For best results, only use one of these services at a time.<br>
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
Device Auth token: <input name=BK maxlength=33><br>
<i>Clear the token field to disable. </i><a href=https://github.com/Aircoookie/WLED/wiki/Blynk target=_blank>Setup info</a>
<h3>MQTT</h3>
Enable MQTT: <input type=checkbox name=MQ><br>
Broker: <input name=MS maxlength=32>
Port: <input name=MQPORT type=number min=1 max=65535 class=d5><br>
<b>The MQTT credentials are sent over an unsecured connection.<br>
Never use the MQTT password for another service!</b><br>
Username: <input name=MQUSER maxlength=40><br>
Password: <input type=password input name=MQPASS maxlength=40><br>
Client ID: <input name=MQCID maxlength=40><br>
Device Topic: <input name=MD maxlength=32><br>
Group Topic: <input name=MG maxlength=32><br>
<i>Reboot required to apply changes. </i><a href=https://github.com/Aircoookie/WLED/wiki/MQTT target=_blank>MQTT info</a>
<h3>Philips Hue</h3>
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
Poll Hue light <input name=HL type=number min=1 max=99> every <input name=HI type=number min=100 max=65000> ms: <input type=checkbox name=HP><br>
Then, receive <input type=checkbox name=HO> On/Off, <input type=checkbox name=HB> Brightness, and <input type=checkbox name=HC> Color<br>
Hue Bridge IP:<br>
<input name=H0 type=number min=0 max=255> .
<input name=H1 type=number min=0 max=255> .
<input name=H2 type=number min=0 max=255> .
<input name=H3 type=number min=0 max=255><br>
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
(when first connecting)<br>
Hue status: <span class=sip> Disabled in this build </span><hr>
<button type=button onclick=B()>Back</button><button type=submit>Save</button>
</form>
</body></html>)=====";
//time and macro settings
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Time Settings</title>
<script>var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){BTa();GetV();Cs();FC();}function gId(s){return d.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}
function BTa(){var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Macro</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for (i=0;i<8;i++){ih+="<tr><td><input name=\"W"+i+"\" id=\"W"+i+"\" type=\"number\" style=\"display:none\"><input id=\"W"+i+"0\" type=\"checkbox\"></td><td><input name=\"H"+i+"\" type=\"number\" min=\"0\" max=\"24\"></td><td><input name=\"N"+i+"\" type=\"number\" min=\"0\" max=\"59\"></td><td><input name=\"T"+i+"\" type=\"number\" min=\"0\" max=\"16\"></td>";for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>";}gId("TMT").innerHTML=ih;}
function FC(){for(j=0;j<8;j++){for(i=0;i<8;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1;}}
function Wd(){a=[0,0,0,0,0,0,0,0];for(i=0;i<8;i++){m=1;for(j=0;j<8;j++){a[i]+=gId("W"+i+j).checked*m;m*=2;}gId("W"+i).value=a[i];}}function GetV(){
%CSS%%SCSS%</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post" onsubmit="Wd()">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Time setup</h2>
Get time from NTP server: <input type="checkbox" name="NT"><br>
<input name="NS" maxlength="32"><br>
Use 24h format: <input type="checkbox" name="CF"><br>
Time zone:
<select name="TZ">
<option value="0" selected>GMT(UTC)</option>
<option value="1">GMT/BST</option>
<option value="2">CET/CEST</option>
<option value="3">EET/EEST</option>
<option value="4">US-EST/EDT</option>
<option value="5">US-CST/CDT</option>
<option value="6">US-MST/MDT</option>
<option value="7">US-AZ</option>
<option value="8">US-PST/PDT</option>
<option value="9">CST(AWST)</option>
<option value="10">JST(KST)</option>
<option value="11">AEST/AEDT</option>
<option value="12">NZST/NZDT</option>
<option value="13">North Korea</option>
<option value="14">IST (India)</option>
<option value="15">CA-Saskatchewan</option>
<option value="16">ACST</option>
<option value="17">ACST/ACDT</option>
</select><br>
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
Current local time is <span class="times">unknown</span>.
<h3>Clock</h3>
Clock Overlay:
<select name="OL" onchange="Cs()">
<option value="0" id="cn" selected>None</option>
<option value="1" id="ca">Analog Clock</option>
<option value="2" disabled>-</option>
<option value="3" id="cc">Cronixie Clock</option>
</select><br>
<div id="coc">
First LED: <input name="O1" type="number" min="0" max="255" required> Last LED: <input name="O2" type="number" min="0" max="255" required><br>
<div id="cac">
12h LED: <input name="OM" type="number" min="0" max="255" required><br>
Show 5min marks: <input type="checkbox" name="O5"><br></div>
Seconds (as trail): <input type="checkbox" name="OS"><br>
</div>
<div id="ccc">
Cronixie Display: <input name="CX" maxlength="6"><br>
Cronixie Backlight: <input type="checkbox" name="CB"><br>
</div>
Countdown Mode: <input type="checkbox" name="CE"><br>
Countdown Goal:<br>
Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
<h3>Advanced Macros</h3>
Define API macros here:<br>
1: <input name="M1" maxlength="64"><br>
2: <input name="M2" maxlength="64"><br>
3: <input name="M3" maxlength="64"><br>
4: <input name="M4" maxlength="64"><br>
5: <input name="M5" maxlength="64"><br>
6: <input name="M6" maxlength="64"><br>
7: <input name="M7" maxlength="64"><br>
8: <input name="M8" maxlength="64"><br>
9: <input name="M9" maxlength="64"><br>
10: <input name="M10" maxlength="64"><br>
11: <input name="M11" maxlength="64"><br>
12: <input name="M12" maxlength="64"><br>
13: <input name="M13" maxlength="64"><br>
14: <input name="M14" maxlength="64"><br>
15: <input name="M15" maxlength="64"><br>
16: <input name="M16" maxlength="64"><br><br>
<i>Use 0 for the default action instead of a macro</i><br>
Boot macro: <input name="MB" type="number" min="0" max="16" required><br>
Alexa On/Off macros: <input name="A0" type="number" min="0" max="16" required> <input name="A1" type="number" min="0" max="16" required><br>
Button short press macro: <input name="MP" type="number" min="0" max="16" required><br>
Long press: <input name="ML" type="number" min="0" max="16" required> Double press: <input name="MD" type="number" min="0" max="16" required><br>
Countdown-Over macro: <input name="MC" type="number" min="0" max="16" required><br>
Timed-Light-Over macro: <input name="MN" type="number" min="0" max="16" required><br>
Time-Controlled macros:<br>
<div style="display: inline-block">
<table id="TMT">
</table></div><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>)=====";
//security settings and about
const char PAGE_settings_sec[] PROGMEM = R"=====(<!DOCTYPE html>
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
<title>Misc Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d=document;
%CSS%%SCSS%</head>
<body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
<h2>Security & Update setup</h2>
Lock wireless (OTA) software update: <input type="checkbox" name="NO"><br>
Passphrase: <input type="password" name="OP" maxlength="32"><br>
To enable OTA, for security reasons you need to also enter the correct password!<br>
The password should be changed when OTA is enabled.<br>
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
Factory reset: <input type="checkbox" name="RS"><br>
All EEPROM content (settings) will be erased.<br><br>
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
<h3>Software Update</h3>
<button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.10.0<br><br>
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br>
(c) 2016-2020 Christian Schwinne <br>
<i>Licensed under the MIT license</i><br><br>
Server message: <span class="sip"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form>
</body>
</html>)=====";

1697
wled00/html_ui.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,353 +0,0 @@
/*
* Settings html
*/
const char PAGE_settingsCss[] PROGMEM = R"=====(
body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:3em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}</style>
)=====";
const char PAGE_settings0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>WLED Settings</title>
)=====";
const char PAGE_settings1[] PROGMEM = R"=====(
body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:13.86vh;width:95%;margin-top:2.4vh}</style>
</head>
<body>
<form action=/settings/wifi><button type=submit>WiFi Setup</button></form>
<form action=/settings/leds><button type=submit>LED Preferences</button></form>
<form action=/settings/ui><button type=submit>User Interface</button></form>
<form action=/settings/sync><button type=submit>Sync Interfaces</button></form>
<form action=/settings/time><button type=submit>Time & Macros</button></form>
<form action=/settings/sec><button type=submit>Security & Updates</button></form>
</body>
</html>
)=====";
const char PAGE_settings_wifi0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document;
)=====";
const char PAGE_settings_wifi1[] PROGMEM = R"=====(
</head>
<body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
<h2>WiFi setup</h2>
<h3>Connect to existing network</h3>
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
Static IP (leave at 0.0.0.0 for DHCP):<br>
<input name="I0" type="number" min="0" max="255" required> .
<input name="I1" type="number" min="0" max="255" required> .
<input name="I2" type="number" min="0" max="255" required> .
<input name="I3" type="number" min="0" max="255" required><br>
Static gateway:<br>
<input name="G0" type="number" min="0" max="255" required> .
<input name="G1" type="number" min="0" max="255" required> .
<input name="G2" type="number" min="0" max="255" required> .
<input name="G3" type="number" min="0" max="255" required><br>
Static subnet mask:<br>
<input name="S0" type="number" min="0" max="255" required> .
<input name="S1" type="number" min="0" max="255" required> .
<input name="S2" type="number" min="0" max="255" required> .
<input name="S3" type="number" min="0" max="255" required><br>
mDNS address (leave empty for no mDNS):<br/>
http:// <input name="CM" maxlength="32"> .local<br>
Try connecting before opening AP for: <input name="AT" type="number" min="0" max="255" required> s <br>
Client IP: <span class="sip"> Not connected </span><br>
<h3>Configure Access Point</h3>
AP SSID (leave empty for no AP):<br> <input name="AS" maxlength="32"><br>
Hide AP name: <input type="checkbox" name="AH"><br>
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"> <br>
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
AP IP: <span class="sip"> Not active </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form>
</body>
</html>
)=====";
const char PAGE_settings_leds0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function GetV(){var d = document;
)=====";
const char PAGE_settings_leds1[] PROGMEM = R"=====(
</head>
<body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>LED setup</h2>
LED count (max. 255): <input name="LC" type="number" min="1" max="255" required><br>
<i>The default boot color is always saved in preset slot 0.</i><br>
Alternatively, apply preset <input name="BP" type="number" min="0" max="25" required> at boot<br>
Default RGB color:
<input name="CR" type="number" min="0" max="255" required>
<input name="CG" type="number" min="0" max="255" required>
<input name="CB" type="number" min="0" max="255" required><br>
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br>
Default white value (only RGBW, -1 to disable): <input name="CW" type="number" min="-1" max="255" required><br>
Default effect ID: <input name="FX" type="number" min="0" max="57" required> <br>
Default effect speed: <input name="SX" type="number" min="0" max="255" required> <br>
Default effect intensity: <input name="IX" type="number" min="0" max="255" required> <br>
Default secondary RGB(W):<br>
<input name="SR" type="number" min="0" max="255" required>
<input name="SG" type="number" min="0" max="255" required>
<input name="SB" type="number" min="0" max="255" required>
<input name="SW" type="number" min="0" max="255" required><br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br>
Turn on after power up/reset: <input type="checkbox" name="BO"><br>
Use Gamma correction for brightness: <input type="checkbox" name="GB"><br>
Use Gamma correction for color: <input type="checkbox" name="GC"><br>
Brightness factor: <input name="BF" type="number" min="0" max="255" required> %
<h3>Transitions</h3>
Fade: <input type="checkbox" name="TF"><br>
Sweep: <input type="checkbox" name="TS"> Invert direction: <input type="checkbox" name="TI"><br>
Transition Delay: <input name="TD" maxlength="5" size="2"> ms
<h3>Timed light</h3>
Default Duration: <input name="TL" type="number" min="1" max="255" required> min<br>
Default Target brightness: <input name="TB" type="number" min="0" max="255" required><br>
Fade down: <input type="checkbox" name="TW"><br>
<h3>Advanced</h3>
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>
)=====";
const char PAGE_settings_ui0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>UI Settings</title><script>
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document;
)=====";
const char PAGE_settings_ui1[] PROGMEM = R"=====(
</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Web Setup</h2>
Server description: <input name="DS" maxlength="32"><br>
Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br>
Color Theme:
<select name="TH" onchange="Ct()">
<option value="0" selected>Night</option>
<option value="1">Modern</option>
<option value="2">Bright</option>
<option value="3">Wine</option>
<option value="4">Electric</option>
<option value="5">Mint</option>
<option value="6">Amber</option>
<option value="7">Club</option>
<option value="8">Air</option>
<option value="9">Nixie</option>
<option value="10">Terminal</option>
<option value="11">C64</option>
<option value="12">Placeholder</option>
<option value="13">Placeholder</option>
<option value="14">The End</option>
<option value="15" id="co">Custom</option>
</select><br>
<div id="cth">
Please specify your custom hex colors (e.g. FF0000 for red)<br>
Custom accent color: <input maxlength=9 name="C0"><br>
Custom background: <input maxlength=9 name="C1"><br>
Custom panel color: <input maxlength=9 name="C2"><br>
Custom icon color: <input maxlength=9 name="C3"><br>
Custom shadow: <input maxlength=9 name="C4"><br>
Custom text color: <input maxlength=9 name="C5"><br></div>
Use font: <input maxlength=32 name="CF"><br>
Make sure the font you use is installed on your system!<br>
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>
)=====";
const char PAGE_settings_sync0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head><title>Sync Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d = document;
)=====";
const char PAGE_settings_sync1[] PROGMEM = R"=====(
</head>
<body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Sync setup</h2>
<h3>Button setup</h3>
On/Off button enabled: <input type="checkbox" name="BT">
<h3>WLED Broadcast</h3>
UDP Port: <input name="UP" maxlength="5" size="4"><br>
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
Send notifications on direct change: <input type="checkbox" name="SD"><br>
Send notifications on button press: <input type="checkbox" name="SB"><br>
Send Alexa notifications: <input type="checkbox" name="SA"><br>
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
Send notifications twice: <input type="checkbox" name="S2">
<h3>Alexa Voice Assistant</h3>
Emulate Alexa device: <input type="checkbox" name="AL"><br>
Alexa invocation name: <input name="AI" maxlength="32"><br>
<h3>Philips Hue</h3>
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
Hue Bridge IP:<br>
<input name="H0" type="number" min="0" max="255" required> .
<input name="H1" type="number" min="0" max="255" required> .
<input name="H2" type="number" min="0" max="255" required> .
<input name="H3" type="number" min="0" max="255" required><br>
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
(when first connecting)<br>
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
Hue status: <span class="hms"> Internal ESP Error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>
)=====";
const char PAGE_settings_time0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head><title>Time Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}function GetV(){var d = document;
)=====";
const char PAGE_settings_time1[] PROGMEM = R"=====(
</head>
<body onload="S()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Time setup</h2>
Get time from NTP server: <input type="checkbox" name="NT"><br>
Use 24h format: <input type="checkbox" name="CF"><br>
Time zone:
<select name="TZ">
<option value="0" selected>GMT(UTC)</option>
<option value="1">GMT/BST</option>
<option value="2">CET/CEST</option>
<option value="3">EET/EEST</option>
<option value="4">US-EST/EDT</option>
<option value="5">US-CST/CDT</option>
<option value="6">US-MST/MDT</option>
<option value="7">US-AZ</option>
<option value="8">US-PST/PDT</option>
<option value="9">CST(AWST)</option>
<option value="10">JST(KST)</option>
<option value="11">AEST/AEDT</option>
<option value="12">NZST/NZDT</option>
</select><br>
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
Current local time is <span class="times">unknown</span>.
<h3>Clock</h3>
Clock Overlay:
<select name="OL" onchange="Cs()">
<option value="0" id="cn" selected>None</option>
<option value="1">Static color</option>
<option value="2" id="ca">Analog Clock</option>
<option value="3">Single Digit Clock</option>
<option value="4" id="cc">Cronixie Clock</option>
</select><br>
<div id="coc">
First LED: <input name="O1" type="number" min="0" max="255" required> Last LED: <input name="O2" type="number" min="0" max="255" required><br>
<div id="cac">
12h LED: <input name="OM" type="number" min="0" max="255" required><br>
Show 5min marks: <input type="checkbox" name="O5"><br></div>
Seconds (as trail): <input type="checkbox" name="OS"><br>
</div>
<div id="ccc">
Cronixie Display: <input name="CX" maxlength="6"><br>
Cronixie Backlight: <input type="checkbox" name="CB"><br>
</div>
Countdown Mode: <input type="checkbox" name="CE"><br>
Countdown Goal: Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
<h3>Advanced Macros</h3>
Define API macros here:<br>
1: <input name="M1" maxlength="64"><br>
2: <input name="M2" maxlength="64"><br>
3: <input name="M3" maxlength="64"><br>
4: <input name="M4" maxlength="64"><br>
5: <input name="M5" maxlength="64"><br>
6: <input name="M6" maxlength="64"><br>
7: <input name="M7" maxlength="64"><br>
8: <input name="M8" maxlength="64"><br>
9: <input name="M9" maxlength="64"><br>
10: <input name="M10" maxlength="64"><br>
11: <input name="M11" maxlength="64"><br>
12: <input name="M12" maxlength="64"><br>
13: <input name="M13" maxlength="64"><br>
14: <input name="M14" maxlength="64"><br>
15: <input name="M15" maxlength="64"><br>
16: <input name="M16" maxlength="64"><br><br>
<i>Use 0 for the default action instead of a macro</i><br>
Time controlled macros coming soon!<br>
Boot Macro: <input name="MB" type="number" min="0" max="16" required><br>
Alexa On/Off Macros: <input name="A0" type="number" min="0" max="16" required> <input name="A1" type="number" min="0" max="16" required><br>
Button Macro: <input name="MP" type="number" min="0" max="16" required> Long Press: <input name="ML" type="number" min="0" max="16" required><br>
Countdown-Over Macro: <input name="MC" type="number" min="0" max="16" required><br>
Timed-Light-Over Macro: <input name="MN" type="number" min="0" max="16" required><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
</body>
</html>
)=====";
const char PAGE_settings_sec0[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<title>Misc Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d = document;
)=====";
const char PAGE_settings_sec1[] PROGMEM = R"=====(
</head>
<body onload="GetV()">
<form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
<h2>Security & Update setup</h2>
Enable OTA lock: <input type="checkbox" name="NO"><br>
Passphrase: <input type="password" name="OP" maxlength="32"><br>
To enable OTA, for security reasons you need to also enter the correct password!<br>
The password should be changed when OTA is enabled.<br>
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
Disable recovery AP: <input type="checkbox" name="NA"><br>
In case of an error there will be no wireless recovery possible!<br>
Completely disables all Access Point functions.<br><br>
Factory reset: <input type="checkbox" name="RS"><br>
All EEPROM content (settings) will be erased.<br><br>
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
<h3>Software Update</h3>
<button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3>
<a href="https://github.com/Aircoookie/WLED">WLED</a> version 0.6.1<br>
(c) 2016-2018 Christian Schwinne <br>
<i>Licensed under the MIT license</i><br><br>
<i>Uses libraries:</i><br>
<i>ESP8266/ESP32 Arduino Core</i><br>
<i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng">WebServer_tng</a> by bbx10</i><br>
<i><a href="https://github.com/kitesurfer1404/WS2812FX">WS2812FX</a> by kitesurfer1404 (modified)</i><br>
<i><a href="https://github.com/JChristensen/Timezone">Timezone</a> library by JChristensen</i><br>
<i><a href="https://github.com/Aircoookie/Espalexa">Espalexa</a> by Aircoookie (modified)</i><br><br>
<i>UI icons by <a href="https://linearicons.com">Linearicons</a> created by <a href="https://perxis.com">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
Server message: <span class="msg"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form>
</body>
</html>
)=====";

File diff suppressed because one or more lines are too long

207
wled00/hue.cpp Normal file
View File

@@ -0,0 +1,207 @@
#include "wled.h"
/*
* Sync to Philips hue lights
*/
#ifndef WLED_DISABLE_HUESYNC
void handleHue()
{
if (hueReceived)
{
colorUpdated(NOTIFIER_CALL_MODE_HUE); hueReceived = false;
if (hueStoreAllowed && hueNewKey)
{
saveSettingsToEEPROM(); //save api key
hueStoreAllowed = false;
hueNewKey = false;
}
}
if (!WLED_CONNECTED || hueClient == nullptr || millis() - hueLastRequestSent < huePollIntervalMs) return;
hueLastRequestSent = millis();
if (huePollingEnabled)
{
reconnectHue();
} else {
hueClient->close();
if (hueError == HUE_ERROR_ACTIVE) hueError = HUE_ERROR_INACTIVE;
}
}
void reconnectHue()
{
if (!WLED_CONNECTED || !huePollingEnabled) return;
DEBUG_PRINTLN("Hue reconnect");
if (hueClient == nullptr) {
hueClient = new AsyncClient();
hueClient->onConnect(&onHueConnect, hueClient);
hueClient->onData(&onHueData, hueClient);
hueClient->onError(&onHueError, hueClient);
hueAuthRequired = (strlen(hueApiKey)<20);
}
hueClient->connect(hueIP, 80);
}
void onHueError(void* arg, AsyncClient* client, int8_t error)
{
DEBUG_PRINTLN("Hue err");
hueError = HUE_ERROR_TIMEOUT;
}
void onHueConnect(void* arg, AsyncClient* client)
{
DEBUG_PRINTLN("Hue connect");
sendHuePoll();
}
void sendHuePoll()
{
if (hueClient == nullptr || !hueClient->connected()) return;
String req = "";
if (hueAuthRequired)
{
req += F("POST /api HTTP/1.1\r\nHost: ");
req += hueIP.toString();
req += F("\r\nContent-Length: 25\r\n\r\n{\"devicetype\":\"wled#esp\"}");
} else
{
req += "GET /api/";
req += hueApiKey;
req += "/lights/" + String(huePollLightId);
req += F(" HTTP/1.1\r\nHost: ");
req += hueIP.toString();
req += "\r\n\r\n";
}
hueClient->add(req.c_str(), req.length());
hueClient->send();
hueLastRequestSent = millis();
}
void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
{
if (!len) return;
char* str = (char*)data;
DEBUG_PRINTLN(hueApiKey);
DEBUG_PRINTLN(str);
//only get response body
str = strstr(str,"\r\n\r\n");
if (str == nullptr) return;
str += 4;
StaticJsonDocument<512> root;
if (str[0] == '[') //is JSON array
{
auto error = deserializeJson(root, str);
if (error)
{
hueError = HUE_ERROR_JSON_PARSING; return;
}
int hueErrorCode = root[0]["error"]["type"];
if (hueErrorCode)//hue bridge returned error
{
hueError = hueErrorCode;
switch (hueErrorCode)
{
case 1: hueAuthRequired = true; break; //Unauthorized user
case 3: huePollingEnabled = false; break; //Invalid light ID
case 101: hueAuthRequired = true; break; //link button not presset
}
return;
}
if (hueAuthRequired)
{
const char* apikey = root[0]["success"]["username"];
if (apikey != nullptr && strlen(apikey) < sizeof(hueApiKey))
{
strcpy(hueApiKey, apikey);
hueAuthRequired = false;
hueNewKey = true;
}
}
return;
}
//else, assume it is JSON object, look for state and only parse that
str = strstr(str,"state");
if (str == nullptr) return;
str = strstr(str,"{");
auto error = deserializeJson(root, str);
if (error)
{
hueError = HUE_ERROR_JSON_PARSING; return;
}
float hueX=0, hueY=0;
uint16_t hueHue=0, hueCt=0;
byte hueBri=0, hueSat=0, hueColormode=0;
if (root["on"]) {
if (root.containsKey("bri")) //Dimmable device
{
hueBri = root["bri"];
hueBri++;
const char* cm =root["colormode"];
if (cm != nullptr) //Color device
{
if (strstr(cm,"ct") != nullptr) //ct mode
{
hueCt = root["ct"];
hueColormode = 3;
} else if (strstr(cm,"xy") != nullptr) //xy mode
{
hueX = root["xy"][0]; // 0.5051
hueY = root["xy"][1]; // 0.4151
hueColormode = 1;
} else //hs mode
{
hueHue = root["hue"];
hueSat = root["sat"];
hueColormode = 2;
}
}
} else //On/Off device
{
hueBri = briLast;
}
} else
{
hueBri = 0;
}
hueError = HUE_ERROR_ACTIVE;
//apply vals
if (hueBri != hueBriLast)
{
if (hueApplyOnOff)
{
if (hueBri==0) {bri = 0;}
else if (bri==0 && hueBri>0) bri = briLast;
}
if (hueApplyBri)
{
if (hueBri>0) bri = hueBri;
}
hueBriLast = hueBri;
}
if (hueApplyColor)
{
switch(hueColormode)
{
case 1: if (hueX != hueXLast || hueY != hueYLast) colorXYtoRGB(hueX,hueY,col); hueXLast = hueX; hueYLast = hueY; break;
case 2: if (hueHue != hueHueLast || hueSat != hueSatLast) colorHStoRGB(hueHue,hueSat,col); hueHueLast = hueHue; hueSatLast = hueSat; break;
case 3: if (hueCt != hueCtLast) colorCTtoRGB(hueCt,col); hueCtLast = hueCt; break;
}
}
hueReceived = true;
}
#else
void handleHue(){}
void reconnectHue(){}
#endif

466
wled00/ir.cpp Normal file
View File

@@ -0,0 +1,466 @@
#include "wled.h"
/*
* Infrared sensor support for generic 24/40/44 key RGB remotes
*/
#if defined(WLED_DISABLE_INFRARED)
void handleIR(){}
#else
IRrecv* irrecv;
//change pin in NpbWrapper.h
decode_results results;
unsigned long irCheckedTime = 0;
uint32_t lastValidCode = 0;
uint16_t irTimesRepeated = 0;
uint8_t lastIR6ColourIdx = 0;
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
bool decodeIRCustom(uint32_t code)
{
switch (code)
{
//just examples, feel free to modify or remove
case IRCUSTOM_ONOFF : toggleOnOff(); break;
case IRCUSTOM_MACRO1 : applyMacro(1); break;
default: return false;
}
if (code != IRCUSTOM_MACRO1) colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it
return true;
}
//relatively change brightness, minumum A=5
void relativeChange(byte* property, int8_t amount, byte lowerBoundary, byte higherBoundary)
{
int16_t new_val = (int16_t) *property + amount;
if (new_val > higherBoundary) new_val = higherBoundary;
else if (new_val < lowerBoundary) new_val = lowerBoundary;
*property = (byte)constrain(new_val,0.1,255.1);
}
void changeEffectSpeed(int8_t amount)
{
if (effectCurrent != 0) {
int16_t new_val = (int16_t) effectSpeed + amount;
effectSpeed = (byte)constrain(new_val,0.1,255.1);
} else { // if Effect == "solid Color", change the hue of the primary color
CRGB fastled_col;
fastled_col.red = col[0];
fastled_col.green = col[1];
fastled_col.blue = col[2];
CHSV prim_hsv = rgb2hsv_approximate(fastled_col);
int16_t new_val = (int16_t) prim_hsv.h + amount;
if (new_val > 255) new_val -= 255; // roll-over if bigger than 255
if (new_val < 0) new_val += 255; // roll-over if smaller than 0
prim_hsv.h = (byte)new_val;
hsv2rgb_rainbow(prim_hsv, fastled_col);
col[0] = fastled_col.red;
col[1] = fastled_col.green;
col[2] = fastled_col.blue;
}
}
void changeEffectIntensity(int8_t amount)
{
if (effectCurrent != 0) {
int16_t new_val = (int16_t) effectIntensity + amount;
effectIntensity = (byte)constrain(new_val,0.1,255.1);
} else { // if Effect == "solid Color", change the saturation of the primary color
CRGB fastled_col;
fastled_col.red = col[0];
fastled_col.green = col[1];
fastled_col.blue = col[2];
CHSV prim_hsv = rgb2hsv_approximate(fastled_col);
int16_t new_val = (int16_t) prim_hsv.s + amount;
prim_hsv.s = (byte)constrain(new_val,0.1,255.1); // constrain to 0-255
hsv2rgb_rainbow(prim_hsv, fastled_col);
col[0] = fastled_col.red;
col[1] = fastled_col.green;
col[2] = fastled_col.blue;
}
}
void decodeIR(uint32_t code)
{
if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down
{
irTimesRepeated++;
if (lastValidCode == IR24_BRIGHTER || lastValidCode == IR40_BPLUS )
{
relativeChange(&bri, 10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
}
else if (lastValidCode == IR24_DARKER || lastValidCode == IR40_BMINUS )
{
relativeChange(&bri, -10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
}
if (lastValidCode == IR40_WPLUS)
{
relativeChangeWhite(10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
}
else if (lastValidCode == IR40_WMINUS)
{
relativeChangeWhite(-10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
}
else if ((lastValidCode == IR24_ON || lastValidCode == IR40_ON) && irTimesRepeated > 7 )
{
nightlightActive = true;
nightlightStartTime = millis();
colorUpdated(NOTIFIER_CALL_MODE_BUTTON);
}
return;
}
lastValidCode = 0; irTimesRepeated = 0;
if (decodeIRCustom(code)) return;
if (code > 0xFFFFFF) return; //invalid code
else if (code > 0xF70000 && code < 0xF80000) decodeIR24(code); //is in 24-key remote range
else if (code > 0xFF0000) {
switch (irEnabled) {
case 1: decodeIR24OLD(code); break; // white 24-key remote (old) - it sends 0xFF0000 values
case 2: decodeIR24CT(code); break; // white 24-key remote with CW, WW, CT+ and CT- keys
case 3: decodeIR40(code); break; // blue 40-key remote with 25%, 50%, 75% and 100% keys
case 4: decodeIR44(code); break; // white 44-key remote with color-up/down keys and DIY1 to 6 keys
case 5: decodeIR21(code); break; // white 21-key remote
case 6: decodeIR6(code); break; // black 6-key learning remote defaults: "CH" controls brightness,
// "VOL +" controls effect, "VOL -" controls colour/palette, "MUTE"
// sets bright plain white
default: return;
}
}
if (nightlightActive && bri == 0) nightlightActive = false;
colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input
//code <= 0xF70000 also invalid
}
void decodeIR24(uint32_t code)
{
switch (code) {
case IR24_BRIGHTER : relativeChange(&bri, 10); break;
case IR24_DARKER : relativeChange(&bri, -10, 5); break;
case IR24_OFF : briLast = bri; bri = 0; break;
case IR24_ON : bri = briLast; break;
case IR24_RED : colorFromUint32(COLOR_RED); break;
case IR24_REDDISH : colorFromUint32(COLOR_REDDISH); break;
case IR24_ORANGE : colorFromUint32(COLOR_ORANGE); break;
case IR24_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
case IR24_YELLOW : colorFromUint32(COLOR_YELLOW); break;
case IR24_GREEN : colorFromUint32(COLOR_GREEN); break;
case IR24_GREENISH : colorFromUint32(COLOR_GREENISH); break;
case IR24_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
case IR24_CYAN : colorFromUint32(COLOR_CYAN); break;
case IR24_AQUA : colorFromUint32(COLOR_AQUA); break;
case IR24_BLUE : colorFromUint32(COLOR_BLUE); break;
case IR24_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break;
case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
case IR24_PINK : colorFromUint32(COLOR_PINK); break;
case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break;
default: return;
}
lastValidCode = code;
}
void decodeIR24OLD(uint32_t code)
{
switch (code) {
case IR24_OLD_BRIGHTER : relativeChange(&bri, 10); break;
case IR24_OLD_DARKER : relativeChange(&bri, -10, 5); break;
case IR24_OLD_OFF : briLast = bri; bri = 0; break;
case IR24_OLD_ON : bri = briLast; break;
case IR24_OLD_RED : colorFromUint32(COLOR_RED); break;
case IR24_OLD_REDDISH : colorFromUint32(COLOR_REDDISH); break;
case IR24_OLD_ORANGE : colorFromUint32(COLOR_ORANGE); break;
case IR24_OLD_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
case IR24_OLD_YELLOW : colorFromUint32(COLOR_YELLOW); break;
case IR24_OLD_GREEN : colorFromUint32(COLOR_GREEN); break;
case IR24_OLD_GREENISH : colorFromUint32(COLOR_GREENISH); break;
case IR24_OLD_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
case IR24_OLD_CYAN : colorFromUint32(COLOR_CYAN); break;
case IR24_OLD_AQUA : colorFromUint32(COLOR_AQUA); break;
case IR24_OLD_BLUE : colorFromUint32(COLOR_BLUE); break;
case IR24_OLD_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
case IR24_OLD_PURPLE : colorFromUint32(COLOR_PURPLE); break;
case IR24_OLD_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
case IR24_OLD_PINK : colorFromUint32(COLOR_PINK); break;
case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
case IR24_OLD_FLASH : if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break;
case IR24_OLD_STROBE : if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break;
case IR24_OLD_FADE : if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break;
case IR24_OLD_SMOOTH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break;
default: return;
}
lastValidCode = code;
}
void decodeIR24CT(uint32_t code)
{
switch (code) {
case IR24_CT_BRIGHTER : relativeChange(&bri, 10); break;
case IR24_CT_DARKER : relativeChange(&bri, -10, 5); break;
case IR24_CT_OFF : briLast = bri; bri = 0; break;
case IR24_CT_ON : bri = briLast; break;
case IR24_CT_RED : colorFromUint32(COLOR_RED); break;
case IR24_CT_REDDISH : colorFromUint32(COLOR_REDDISH); break;
case IR24_CT_ORANGE : colorFromUint32(COLOR_ORANGE); break;
case IR24_CT_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
case IR24_CT_YELLOW : colorFromUint32(COLOR_YELLOW); break;
case IR24_CT_GREEN : colorFromUint32(COLOR_GREEN); break;
case IR24_CT_GREENISH : colorFromUint32(COLOR_GREENISH); break;
case IR24_CT_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
case IR24_CT_CYAN : colorFromUint32(COLOR_CYAN); break;
case IR24_CT_AQUA : colorFromUint32(COLOR_AQUA); break;
case IR24_CT_BLUE : colorFromUint32(COLOR_BLUE); break;
case IR24_CT_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
case IR24_CT_PURPLE : colorFromUint32(COLOR_PURPLE); break;
case IR24_CT_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
case IR24_CT_PINK : colorFromUint32(COLOR_PINK); break;
case IR24_CT_COLDWHITE : colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; break;
case IR24_CT_WARMWHITE : colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; break;
case IR24_CT_CTPLUS : colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; break;
case IR24_CT_CTMINUS : colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; break;
case IR24_CT_MEMORY : {
if (col[3] > 0) col[3] = 0;
else colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; } break;
default: return;
}
lastValidCode = code;
}
void decodeIR40(uint32_t code)
{
switch (code) {
case IR40_BPLUS : relativeChange(&bri, 10); break;
case IR40_BMINUS : relativeChange(&bri, -10, 5); break;
case IR40_OFF : briLast = bri; bri = 0; break;
case IR40_ON : bri = briLast; break;
case IR40_RED : colorFromUint24(COLOR_RED); break;
case IR40_REDDISH : colorFromUint24(COLOR_REDDISH); break;
case IR40_ORANGE : colorFromUint24(COLOR_ORANGE); break;
case IR40_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break;
case IR40_YELLOW : colorFromUint24(COLOR_YELLOW); break;
case IR40_GREEN : colorFromUint24(COLOR_GREEN); break;
case IR40_GREENISH : colorFromUint24(COLOR_GREENISH); break;
case IR40_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break;
case IR40_CYAN : colorFromUint24(COLOR_CYAN); break;
case IR40_AQUA : colorFromUint24(COLOR_AQUA); break;
case IR40_BLUE : colorFromUint24(COLOR_BLUE); break;
case IR40_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break;
case IR40_PURPLE : colorFromUint24(COLOR_PURPLE); break;
case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break;
case IR40_PINK : colorFromUint24(COLOR_PINK); break;
case IR40_WARMWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE2); } break;
case IR40_WARMWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE); } break;
case IR40_WHITE : {
if (useRGBW) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_NEUTRALWHITE); } break;
case IR40_COLDWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE); } break;
case IR40_COLDWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE2); } break;
case IR40_WPLUS : relativeChangeWhite(10); break;
case IR40_WMINUS : relativeChangeWhite(-10, 5); break;
case IR40_WOFF : whiteLast = col[3]; col[3] = 0; break;
case IR40_WON : col[3] = whiteLast; break;
case IR40_W25 : bri = 63; break;
case IR40_W50 : bri = 127; break;
case IR40_W75 : bri = 191; break;
case IR40_W100 : bri = 255; break;
case IR40_QUICK : changeEffectSpeed( 16); break;
case IR40_SLOW : changeEffectSpeed(-16); break;
case IR40_JUMP7 : changeEffectIntensity( 16); break;
case IR40_AUTO : changeEffectIntensity(-16); break;
case IR40_JUMP3 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break;
case IR40_FADE3 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break;
case IR40_FADE7 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break;
case IR40_FLASH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break;
}
lastValidCode = code;
}
void decodeIR44(uint32_t code)
{
switch (code) {
case IR44_BPLUS : relativeChange(&bri, 10); break;
case IR44_BMINUS : relativeChange(&bri, -10, 5); break;
case IR44_OFF : briLast = bri; bri = 0; break;
case IR44_ON : bri = briLast; break;
case IR44_RED : colorFromUint24(COLOR_RED); break;
case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break;
case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break;
case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break;
case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break;
case IR44_GREEN : colorFromUint24(COLOR_GREEN); break;
case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break;
case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break;
case IR44_CYAN : colorFromUint24(COLOR_CYAN); break;
case IR44_AQUA : colorFromUint24(COLOR_AQUA); break;
case IR44_BLUE : colorFromUint24(COLOR_BLUE); break;
case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break;
case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break;
case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break;
case IR44_PINK : colorFromUint24(COLOR_PINK); break;
case IR44_WHITE : {
if (useRGBW) {
if (col[3] > 0) col[3] = 0;
else { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
} else colorFromUint24(COLOR_NEUTRALWHITE); } break;
case IR44_WARMWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE2); } break;
case IR44_WARMWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE); } break;
case IR44_COLDWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE); } break;
case IR44_COLDWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE2); } break;
case IR44_REDPLUS : relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break;
case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break;
case IR44_GREENPLUS : relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1); break;
case IR44_GREENMINUS : relativeChange(&effectPalette, -1, 0); break;
case IR44_BLUEPLUS : changeEffectIntensity( 16); break;
case IR44_BLUEMINUS : changeEffectIntensity(-16); break;
case IR44_QUICK : changeEffectSpeed( 16); break;
case IR44_SLOW : changeEffectSpeed(-16); break;
case IR44_DIY1 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break;
case IR44_DIY2 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break;
case IR44_DIY3 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break;
case IR44_DIY4 : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break;
case IR44_DIY5 : if (!applyPreset(5)) { effectCurrent = FX_MODE_METEOR_SMOOTH; effectPalette = 0; } break;
case IR44_DIY6 : if (!applyPreset(6)) { effectCurrent = FX_MODE_RAIN; effectPalette = 0; } break;
case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break;
case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break;
case IR44_JUMP3 : bri = 63; break;
case IR44_JUMP7 : bri = 127; break;
case IR44_FADE3 : bri = 191; break;
case IR44_FADE7 : bri = 255; break;
}
lastValidCode = code;
}
void decodeIR21(uint32_t code)
{
switch (code) {
case IR21_BRIGHTER: relativeChange(&bri, 10); break;
case IR21_DARKER: relativeChange(&bri, -10, 5); break;
case IR21_OFF: briLast = bri; bri = 0; break;
case IR21_ON: bri = briLast; break;
case IR21_RED: colorFromUint32(COLOR_RED); break;
case IR21_REDDISH: colorFromUint32(COLOR_REDDISH); break;
case IR21_ORANGE: colorFromUint32(COLOR_ORANGE); break;
case IR21_YELLOWISH: colorFromUint32(COLOR_YELLOWISH); break;
case IR21_GREEN: colorFromUint32(COLOR_GREEN); break;
case IR21_GREENISH: colorFromUint32(COLOR_GREENISH); break;
case IR21_TURQUOISE: colorFromUint32(COLOR_TURQUOISE); break;
case IR21_CYAN: colorFromUint32(COLOR_CYAN); break;
case IR21_BLUE: colorFromUint32(COLOR_BLUE); break;
case IR21_DEEPBLUE: colorFromUint32(COLOR_DEEPBLUE); break;
case IR21_PURPLE: colorFromUint32(COLOR_PURPLE); break;
case IR21_PINK: colorFromUint32(COLOR_PINK); break;
case IR21_WHITE: colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
case IR21_FLASH: if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break;
case IR21_STROBE: if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break;
case IR21_FADE: if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break;
case IR21_SMOOTH: if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break;
default: return;
}
lastValidCode = code;
}
void decodeIR6(uint32_t code)
{
switch (code) {
case IR6_POWER: toggleOnOff(); break;
case IR6_CHANNEL_UP: relativeChange(&bri, 10); break;
case IR6_CHANNEL_DOWN: relativeChange(&bri, -10, 5); break;
case IR6_VOLUME_UP: relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; // next effect
case IR6_VOLUME_DOWN: // next palette
relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1);
switch(lastIR6ColourIdx) {
case 0: colorFromUint32(COLOR_RED); break;
case 1: colorFromUint32(COLOR_REDDISH); break;
case 2: colorFromUint32(COLOR_ORANGE); break;
case 3: colorFromUint32(COLOR_YELLOWISH); break;
case 4: colorFromUint32(COLOR_GREEN); break;
case 5: colorFromUint32(COLOR_GREENISH); break;
case 6: colorFromUint32(COLOR_TURQUOISE); break;
case 7: colorFromUint32(COLOR_CYAN); break;
case 8: colorFromUint32(COLOR_BLUE); break;
case 9: colorFromUint32(COLOR_DEEPBLUE); break;
case 10:colorFromUint32(COLOR_PURPLE); break;
case 11:colorFromUint32(COLOR_PINK); break;
case 12:colorFromUint32(COLOR_WHITE); break;
default: break;
}
lastIR6ColourIdx++;
if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; break;
case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break;
}
lastValidCode = code;
}
void initIR()
{
if (irEnabled > 0)
{
irrecv = new IRrecv(IR_PIN);
irrecv->enableIRIn();
}
}
void handleIR()
{
if (irEnabled > 0 && millis() - irCheckedTime > 120)
{
irCheckedTime = millis();
if (irEnabled > 0)
{
if (irrecv == NULL)
{
initIR(); return;
}
if (irrecv->decode(&results))
{
if (results.value != 0) // only print results if anything is received ( != 0 )
{
Serial.print("IR recv\r\n0x");
Serial.println((uint32_t)results.value, HEX);
Serial.println();
}
decodeIR(results.value);
irrecv->resume();
}
} else if (irrecv != NULL)
{
irrecv->disableIRIn();
delete irrecv; irrecv = NULL;
}
}
}
#endif

231
wled00/ir_codes.h Normal file
View File

@@ -0,0 +1,231 @@
//Infrared codes
//Add your custom codes here
#define IRCUSTOM_ONOFF 0xA55AEA15 //Pioneer RC-975R "+FAV" button (example)
#define IRCUSTOM_MACRO1 0xFFFFFFFF //placeholder, will never be checked for
// Default IR codes for 6-key learning remote https://www.aliexpress.com/item/4000307837886.html
// This cheap remote has the advantage of being more powerful (longer range) than cheap credit-card remotes
#define IR6_POWER 0xFF0FF0
#define IR6_CHANNEL_UP 0xFF8F70
#define IR6_CHANNEL_DOWN 0xFF4FB0
#define IR6_VOLUME_UP 0xFFCF30
#define IR6_VOLUME_DOWN 0xFF2FD0
#define IR6_MUTE 0xFFAF50
//Infrared codes for 24-key remote from http://woodsgood.ca/projects/2015/02/13/rgb-led-strip-controllers-ir-codes/
#define IR24_BRIGHTER 0xF700FF
#define IR24_DARKER 0xF7807F
#define IR24_OFF 0xF740BF
#define IR24_ON 0xF7C03F
#define IR24_RED 0xF720DF
#define IR24_REDDISH 0xF710EF
#define IR24_ORANGE 0xF730CF
#define IR24_YELLOWISH 0xF708F7
#define IR24_YELLOW 0xF728D7
#define IR24_GREEN 0xF7A05F
#define IR24_GREENISH 0xF7906F
#define IR24_TURQUOISE 0xF7B04F
#define IR24_CYAN 0xF78877
#define IR24_AQUA 0xF7A857
#define IR24_BLUE 0xF7609F
#define IR24_DEEPBLUE 0xF750AF
#define IR24_PURPLE 0xF7708F
#define IR24_MAGENTA 0xF748B7
#define IR24_PINK 0xF76897
#define IR24_WHITE 0xF7E01F
#define IR24_FLASH 0xF7D02F
#define IR24_STROBE 0xF7F00F
#define IR24_FADE 0xF7C837
#define IR24_SMOOTH 0xF7E817
// 24-key defs for white remote control with CW / WW / CT+ and CT- keys (from ALDI LED pillar lamp)
#define IR24_CT_BRIGHTER 0xF700FF // BRI +
#define IR24_CT_DARKER 0xF7807F // BRI -
#define IR24_CT_OFF 0xF740BF // OFF
#define IR24_CT_ON 0xF7C03F // ON
#define IR24_CT_RED 0xF720DF // RED
#define IR24_CT_REDDISH 0xF710EF // REDDISH
#define IR24_CT_ORANGE 0xF730CF // ORANGE
#define IR24_CT_YELLOWISH 0xF708F7 // YELLOWISH
#define IR24_CT_YELLOW 0xF728D7 // YELLOW
#define IR24_CT_GREEN 0xF7A05F // GREEN
#define IR24_CT_GREENISH 0xF7906F // GREENISH
#define IR24_CT_TURQUOISE 0xF7B04F // TURQUOISE
#define IR24_CT_CYAN 0xF78877 // CYAN
#define IR24_CT_AQUA 0xF7A857 // AQUA
#define IR24_CT_BLUE 0xF7609F // BLUE
#define IR24_CT_DEEPBLUE 0xF750AF // DEEPBLUE
#define IR24_CT_PURPLE 0xF7708F // PURPLE
#define IR24_CT_MAGENTA 0xF748B7 // MAGENTA
#define IR24_CT_PINK 0xF76897 // PINK
#define IR24_CT_COLDWHITE 0xF7E01F // CW
#define IR24_CT_WARMWHITE 0xF7D02F // WW
#define IR24_CT_CTPLUS 0xF7F00F // CT+
#define IR24_CT_CTMINUS 0xF7C837 // CT-
#define IR24_CT_MEMORY 0xF7E817 // MEMORY
// 24-key defs for old remote control
#define IR24_OLD_BRIGHTER 0xFF906F // Brightness Up
#define IR24_OLD_DARKER 0xFFB847 // Brightness Down
#define IR24_OLD_OFF 0xFFF807 // Power OFF
#define IR24_OLD_ON 0xFFB04F // Power On
#define IR24_OLD_RED 0xFF9867 // RED
#define IR24_OLD_REDDISH 0xFFE817 // Light RED
#define IR24_OLD_ORANGE 0xFF02FD // Orange
#define IR24_OLD_YELLOWISH 0xFF50AF // Light Orange
#define IR24_OLD_YELLOW 0xFF38C7 // YELLOW
#define IR24_OLD_GREEN 0xFFD827 // GREEN
#define IR24_OLD_GREENISH 0xFF48B7 // Light GREEN
#define IR24_OLD_TURQUOISE 0xFF32CD // TURQUOISE
#define IR24_OLD_CYAN 0xFF7887 // CYAN
#define IR24_OLD_AQUA 0xFF28D7 // AQUA
#define IR24_OLD_BLUE 0xFF8877 // BLUE
#define IR24_OLD_DEEPBLUE 0xFF6897 // Dark BLUE
#define IR24_OLD_PURPLE 0xFF20DF // PURPLE
#define IR24_OLD_MAGENTA 0xFF708F // MAGENTA
#define IR24_OLD_PINK 0xFFF00F // PINK
#define IR24_OLD_WHITE 0xFFA857 // WHITE
#define IR24_OLD_FLASH 0xFFB24D // FLASH Mode
#define IR24_OLD_STROBE 0xFF00FF // STROBE Mode
#define IR24_OLD_FADE 0xFF58A7 // FADE Mode
#define IR24_OLD_SMOOTH 0xFF30CF // SMOOTH Mode
// 40-key defs for blue remote control
#define IR40_BPLUS 0xFF3AC5 //
#define IR40_BMINUS 0xFFBA45 //
#define IR40_OFF 0xFF827D //
#define IR40_ON 0xFF02FD //
#define IR40_RED 0xFF1AE5 //
#define IR40_GREEN 0xFF9A65 //
#define IR40_BLUE 0xFFA25D //
#define IR40_WHITE 0xFF22DD // natural white
#define IR40_REDDISH 0xFF2AD5 //
#define IR40_GREENISH 0xFFAA55 //
#define IR40_DEEPBLUE 0xFF926D //
#define IR40_WARMWHITE2 0xFF12ED // warmest white
#define IR40_ORANGE 0xFF0AF5 //
#define IR40_TURQUOISE 0xFF8A75 //
#define IR40_PURPLE 0xFFB24D //
#define IR40_WARMWHITE 0xFF32CD // warm white
#define IR40_YELLOWISH 0xFF38C7 //
#define IR40_CYAN 0xFFB847 //
#define IR40_MAGENTA 0xFF7887 //
#define IR40_COLDWHITE 0xFFF807 // cold white
#define IR40_YELLOW 0xFF18E7 //
#define IR40_AQUA 0xFF9867 //
#define IR40_PINK 0xFF58A7 //
#define IR40_COLDWHITE2 0xFFD827 // coldest white
#define IR40_WPLUS 0xFF28D7 // white chanel bright plus
#define IR40_WMINUS 0xFFA857 // white chanel bright minus
#define IR40_WOFF 0xFF6897 // white chanel on
#define IR40_WON 0xFFE817 // white chanel off
#define IR40_W25 0xFF08F7 // white chanel 25%
#define IR40_W50 0xFF8877 // white chanel 50%
#define IR40_W75 0xFF48B7 // white chanel 75%
#define IR40_W100 0xFFC837 // white chanel 100%
#define IR40_JUMP3 0xFF30CF // JUMP3
#define IR40_FADE3 0xFFB04F // FADE3
#define IR40_JUMP7 0xFF708F // JUMP7
#define IR40_QUICK 0xFFF00F // QUICK
#define IR40_FADE7 0xFF10EF // FADE7
#define IR40_FLASH 0xFF906F // FLASH
#define IR40_AUTO 0xFF50AF // AUTO
#define IR40_SLOW 0xFFD02F // SLOW
// 44-key defs, to be done later
#define IR44_BPLUS 0xFF3AC5 //
#define IR44_BMINUS 0xFFBA45 //
#define IR44_OFF 0xFF827D //
#define IR44_ON 0xFF02FD //
#define IR44_RED 0xFF1AE5 //
#define IR44_GREEN 0xFF9A65 //
#define IR44_BLUE 0xFFA25D //
#define IR44_WHITE 0xFF22DD // natural white
#define IR44_REDDISH 0xFF2AD5 //
#define IR44_GREENISH 0xFFAA55 //
#define IR44_DEEPBLUE 0xFF926D //
#define IR44_WARMWHITE2 0xFF12ED // warmest white
#define IR44_ORANGE 0xFF0AF5 //
#define IR44_TURQUOISE 0xFF8A75 //
#define IR44_PURPLE 0xFFB24D //
#define IR44_WARMWHITE 0xFF32CD // warm white
#define IR44_YELLOWISH 0xFF38C7 //
#define IR44_CYAN 0xFFB847 //
#define IR44_MAGENTA 0xFF7887 //
#define IR44_COLDWHITE 0xFFF807 // cold white
#define IR44_YELLOW 0xFF18E7 //
#define IR44_AQUA 0xFF9867 //
#define IR44_PINK 0xFF58A7 //
#define IR44_COLDWHITE2 0xFFD827 // coldest white
#define IR44_REDPLUS 0xFF28D7 //
#define IR44_GREENPLUS 0xFFA857 //
#define IR44_BLUEPLUS 0xFF6897 //
#define IR44_QUICK 0xFFE817 //
#define IR44_REDMINUS 0xFF08F7 //
#define IR44_GREENMINUS 0xFF8877 //
#define IR44_BLUEMINUS 0xFF48B7 //
#define IR44_SLOW 0xFFC837 //
#define IR44_DIY1 0xFF30CF //
#define IR44_DIY2 0xFFB04F //
#define IR44_DIY3 0xFF708F //
#define IR44_AUTO 0xFFF00F //
#define IR44_DIY4 0xFF10EF //
#define IR44_DIY5 0xFF906F //
#define IR44_DIY6 0xFF50AF //
#define IR44_FLASH 0xFFD02F //
#define IR44_JUMP3 0xFF20DF //
#define IR44_JUMP7 0xFFA05F //
#define IR44_FADE3 0xFF609F //
#define IR44_FADE7 0xFFE01F //
//Infrared codes for 21-key remote https://images-na.ssl-images-amazon.com/images/I/51NMA0XucnL.jpg
#define IR21_BRIGHTER 0xFFE01F
#define IR21_DARKER 0xFFA857
#define IR21_OFF 0xFF629D
#define IR21_ON 0xFFA25D
#define IR21_RED 0xFF6897
#define IR21_REDDISH 0xFF30CF
#define IR21_ORANGE 0xFF10EF
#define IR21_YELLOWISH 0xFF42BD
#define IR21_GREEN 0xFF9867
#define IR21_GREENISH 0xFF18E7
#define IR21_TURQUOISE 0xFF38C7
#define IR21_CYAN 0xFF4AB5
#define IR21_BLUE 0xFFB04F
#define IR21_DEEPBLUE 0xFF7A85
#define IR21_PURPLE 0xFF5AA5
#define IR21_PINK 0xFF52AD
#define IR21_WHITE 0xFF906F
#define IR21_FLASH 0xFFE21D
#define IR21_STROBE 0xFF22DD
#define IR21_FADE 0xFF02FD
#define IR21_SMOOTH 0xFFC23D
#define COLOR_RED 0xFF0000
#define COLOR_REDDISH 0xFF7800
#define COLOR_ORANGE 0xFFA000
#define COLOR_YELLOWISH 0xFFC800
#define COLOR_YELLOW 0xFFFF00
#define COLOR_GREEN 0x00FF00
#define COLOR_GREENISH 0x00FF78
#define COLOR_TURQUOISE 0x00FFA0
#define COLOR_CYAN 0x00FFDC
#define COLOR_AQUA 0x00C8FF
#define COLOR_BLUE 0x00A0FF
#define COLOR_DEEPBLUE 0x0000FF
#define COLOR_PURPLE 0xAA00FF
#define COLOR_MAGENTA 0xFF00DC
#define COLOR_PINK 0xFF00A0
#define COLOR_WHITE 0xFFFFDC
#define COLOR_WARMWHITE2 0xFFAA69
#define COLOR_WARMWHITE 0xFFBF8E
#define COLOR_NEUTRALWHITE 0xFFD4B4
#define COLOR_COLDWHITE 0xFFE9D9
#define COLOR_COLDWHITE2 0xFFFFFF
#define COLOR2_WARMWHITE2 0xFFFF9900
#define COLOR2_WARMWHITE 0xFF825A00
#define COLOR2_NEUTRALWHITE 0xFF000000
#define COLOR2_COLDWHITE 0xFF7F7F7F
#define COLOR2_COLDWHITE2 0xFFFFFFFF

469
wled00/json.cpp Normal file
View File

@@ -0,0 +1,469 @@
#include "wled.h"
/*
* JSON API (De)serialization
*/
void deserializeSegment(JsonObject elem, byte it)
{
byte id = elem["id"] | it;
if (id < strip.getMaxSegments())
{
WS2812FX::Segment& seg = strip.getSegment(id);
uint16_t start = elem["start"] | seg.start;
int stop = elem["stop"] | -1;
if (stop < 0) {
uint16_t len = elem["len"];
stop = (len > 0) ? start + len : seg.stop;
}
uint16_t grp = elem["grp"] | seg.grouping;
uint16_t spc = elem["spc"] | seg.spacing;
strip.setSegment(id, start, stop, grp, spc);
int segbri = elem["bri"] | -1;
if (segbri == 0) {
seg.setOption(SEG_OPTION_ON, 0);
} else if (segbri > 0) {
seg.opacity = segbri;
seg.setOption(SEG_OPTION_ON, 1);
}
seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON));
JsonArray colarr = elem["col"];
if (!colarr.isNull())
{
for (uint8_t i = 0; i < 3; i++)
{
JsonArray colX = colarr[i];
if (colX.isNull()) break;
byte sz = colX.size();
if (sz > 0 && sz < 5)
{
int rgbw[] = {0,0,0,0};
byte cp = copyArray(colX, rgbw);
if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
{
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
} else {
seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
}
}
}
}
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
seg.setOption(SEG_OPTION_SELECTED, elem["sel"] | seg.getOption(SEG_OPTION_SELECTED));
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
//temporary, strip object gets updated via colorUpdated()
if (id == strip.getMainSegmentId()) {
effectCurrent = elem["fx"] | effectCurrent;
effectSpeed = elem["sx"] | effectSpeed;
effectIntensity = elem["ix"] | effectIntensity;
effectPalette = elem["pal"] | effectPalette;
} else { //permanent
byte fx = elem["fx"] | seg.mode;
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
seg.speed = elem["sx"] | seg.speed;
seg.intensity = elem["ix"] | seg.intensity;
seg.palette = elem["pal"] | seg.palette;
}
}
}
bool deserializeState(JsonObject root)
{
strip.applyToAllSelected = false;
bool stateResponse = root["v"] | false;
int ps = root["ps"] | -1;
if (ps >= 0) applyPreset(ps);
bri = root["bri"] | bri;
bool on = root["on"] | (bri > 0);
if (!on != !bri) toggleOnOff();
int tr = root["transition"] | -1;
if (tr >= 0)
{
transitionDelay = tr;
transitionDelay *= 100;
}
tr = root["tt"] | -1;
if (tr >= 0)
{
transitionDelayTemp = tr;
transitionDelayTemp *= 100;
jsonTransitionOnce = true;
}
int cy = root["pl"] | -2;
if (cy > -2) presetCyclingEnabled = (cy >= 0);
JsonObject ccnf = root["ccnf"];
presetCycleMin = ccnf["min"] | presetCycleMin;
presetCycleMax = ccnf["max"] | presetCycleMax;
tr = ccnf["time"] | -1;
if (tr >= 2)
{
presetCycleTime = tr;
presetCycleTime *= 100;
}
JsonObject nl = root["nl"];
nightlightActive = nl["on"] | nightlightActive;
nightlightDelayMins = nl["dur"] | nightlightDelayMins;
nightlightFade = nl["fade"] | nightlightFade;
nightlightTargetBri = nl["tbri"] | nightlightTargetBri;
JsonObject udpn = root["udpn"];
notifyDirect = udpn["send"] | notifyDirect;
receiveNotifications = udpn["recv"] | receiveNotifications;
bool noNotification = udpn["nn"]; //send no notification just for this request
int timein = root["time"] | -1;
if (timein != -1) setTime(timein);
doReboot = root["rb"] | doReboot;
realtimeOverride = root["lor"] | realtimeOverride;
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
byte prevMain = strip.getMainSegmentId();
strip.mainSegment = root["mainseg"] | prevMain;
if (strip.getMainSegmentId() != prevMain) setValuesFromMainSeg();
int it = 0;
JsonVariant segVar = root["seg"];
if (segVar.is<JsonObject>())
{
int id = segVar["id"] | -1;
if (id < 0) { //set all selected segments
bool didSet = false;
byte lowestActive = 99;
for (byte s = 0; s < strip.getMaxSegments(); s++)
{
WS2812FX::Segment sg = strip.getSegment(s);
if (sg.isActive())
{
if (lowestActive == 99) lowestActive = s;
if (sg.isSelected()) {
deserializeSegment(segVar, s);
didSet = true;
}
}
}
if (!didSet && lowestActive < strip.getMaxSegments()) deserializeSegment(segVar, lowestActive);
} else { //set only the segment with the specified ID
deserializeSegment(segVar, it);
}
} else {
JsonArray segs = segVar.as<JsonArray>();
for (JsonObject elem : segs)
{
deserializeSegment(elem, it);
it++;
}
}
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
//write presets to flash directly?
bool persistSaves = !(root["np"] | false);
ps = root["psave"] | -1;
if (ps >= 0) savePreset(ps, persistSaves);
return stateResponse;
}
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
{
root["id"] = id;
root["start"] = seg.start;
root["stop"] = seg.stop;
root["len"] = seg.stop - seg.start;
root["grp"] = seg.grouping;
root["spc"] = seg.spacing;
root["on"] = seg.getOption(SEG_OPTION_ON);
byte segbri = seg.opacity;
root["bri"] = (segbri) ? segbri : 255;
JsonArray colarr = root.createNestedArray("col");
for (uint8_t i = 0; i < 3; i++)
{
JsonArray colX = colarr.createNestedArray();
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
{
if (i == 0) {
colX.add(col[0]); colX.add(col[1]); colX.add(col[2]); if (useRGBW) colX.add(col[3]);
} else {
colX.add(colSec[0]); colX.add(colSec[1]); colX.add(colSec[2]); if (useRGBW) colX.add(colSec[3]);
}
} else {
colX.add((seg.colors[i] >> 16) & 0xFF);
colX.add((seg.colors[i] >> 8) & 0xFF);
colX.add((seg.colors[i]) & 0xFF);
if (useRGBW)
colX.add((seg.colors[i] >> 24) & 0xFF);
}
}
root["fx"] = seg.mode;
root["sx"] = seg.speed;
root["ix"] = seg.intensity;
root["pal"] = seg.palette;
root["sel"] = seg.isSelected();
root["rev"] = seg.getOption(SEG_OPTION_REVERSED);
}
void serializeState(JsonObject root)
{
if (errorFlag) root["error"] = errorFlag;
root["on"] = (bri > 0);
root["bri"] = briLast;
root["transition"] = transitionDelay/100; //in 100ms
root["ps"] = currentPreset;
root["pss"] = savedPresets;
root["pl"] = (presetCyclingEnabled) ? 0: -1;
//temporary for preser cycle
JsonObject ccnf = root.createNestedObject("ccnf");
ccnf["min"] = presetCycleMin;
ccnf["max"] = presetCycleMax;
ccnf["time"] = presetCycleTime/100;
JsonObject nl = root.createNestedObject("nl");
nl["on"] = nightlightActive;
nl["dur"] = nightlightDelayMins;
nl["fade"] = nightlightFade;
nl["tbri"] = nightlightTargetBri;
JsonObject udpn = root.createNestedObject("udpn");
udpn["send"] = notifyDirect;
udpn["recv"] = receiveNotifications;
root["lor"] = realtimeOverride;
root["mainseg"] = strip.getMainSegmentId();
JsonArray seg = root.createNestedArray("seg");
for (byte s = 0; s < strip.getMaxSegments(); s++)
{
WS2812FX::Segment sg = strip.getSegment(s);
if (sg.isActive())
{
JsonObject seg0 = seg.createNestedObject();
serializeSegment(seg0, sg, s);
}
}
}
//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp
int getSignalQuality(int rssi)
{
int quality = 0;
if (rssi <= -100)
{
quality = 0;
}
else if (rssi >= -50)
{
quality = 100;
}
else
{
quality = 2 * (rssi + 100);
}
return quality;
}
void serializeInfo(JsonObject root)
{
root["ver"] = versionString;
root["vid"] = VERSION;
//root["cn"] = WLED_CODENAME;
JsonObject leds = root.createNestedObject("leds");
leds["count"] = ledCount;
leds["rgbw"] = useRGBW;
leds["wv"] = useRGBW && (strip.rgbwMode == RGBW_MODE_MANUAL_ONLY || strip.rgbwMode == RGBW_MODE_DUAL); //should a white channel slider be displayed?
JsonArray leds_pin = leds.createNestedArray("pin");
leds_pin.add(LEDPIN);
leds["pwr"] = strip.currentMilliamps;
leds["maxpwr"] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
leds["maxseg"] = strip.getMaxSegments();
leds["seglock"] = false; //will be used in the future to prevent modifications to segment config
root["str"] = syncToggleReceive;
root["name"] = serverDescription;
root["udpport"] = udpPort;
root["live"] = (bool)realtimeMode;
switch (realtimeMode) {
case REALTIME_MODE_INACTIVE: root["lm"] = ""; break;
case REALTIME_MODE_GENERIC: root["lm"] = ""; break;
case REALTIME_MODE_UDP: root["lm"] = "UDP"; break;
case REALTIME_MODE_HYPERION: root["lm"] = "Hyperion"; break;
case REALTIME_MODE_E131: root["lm"] = "E1.31"; break;
case REALTIME_MODE_ADALIGHT: root["lm"] = F("USB Adalight");
case REALTIME_MODE_ARTNET: root["lm"] = "Art-Net"; break;
}
if (realtimeIP[0] == 0)
{
root["lip"] = "";
} else {
root["lip"] = realtimeIP.toString();
}
root["fxcount"] = strip.getModeCount();
root["palcount"] = strip.getPaletteCount();
JsonObject wifi_info = root.createNestedObject("wifi");
wifi_info["bssid"] = WiFi.BSSIDstr();
int qrssi = WiFi.RSSI();
wifi_info["rssi"] = qrssi;
wifi_info["signal"] = getSignalQuality(qrssi);
wifi_info["channel"] = WiFi.channel();
#ifdef ARDUINO_ARCH_ESP32
#ifdef WLED_DEBUG
wifi_info["txPower"] = (int) WiFi.getTxPower();
wifi_info["sleep"] = (bool) WiFi.getSleep();
#endif
root["arch"] = "esp32";
root["core"] = ESP.getSdkVersion();
//root["maxalloc"] = ESP.getMaxAllocHeap();
#ifdef WLED_DEBUG
root["resetReason0"] = (int)rtc_get_reset_reason(0);
root["resetReason1"] = (int)rtc_get_reset_reason(1);
#endif
root["lwip"] = 0;
#else
root["arch"] = "esp8266";
root["core"] = ESP.getCoreVersion();
//root["maxalloc"] = ESP.getMaxFreeBlockSize();
#ifdef WLED_DEBUG
root["resetReason"] = (int)ESP.getResetInfoPtr()->reason;
#endif
root["lwip"] = LWIP_VERSION_MAJOR;
#endif
root["freeheap"] = ESP.getFreeHeap();
root["uptime"] = millis()/1000 + rolloverMillis*4294967;
byte os = 0;
#ifdef WLED_DEBUG
os = 0x80;
#endif
#ifndef WLED_DISABLE_ALEXA
os += 0x40;
#endif
#ifndef WLED_DISABLE_BLYNK
os += 0x20;
#endif
#ifndef WLED_DISABLE_CRONIXIE
os += 0x10;
#endif
#ifndef WLED_DISABLE_FILESYSTEM
os += 0x08;
#endif
#ifndef WLED_DISABLE_HUESYNC
os += 0x04;
#endif
#ifdef WLED_ENABLE_ADALIGHT
os += 0x02;
#endif
#ifndef WLED_DISABLE_OTA
os += 0x01;
#endif
root["opt"] = os;
root["brand"] = "WLED";
root["product"] = "FOSS";
root["mac"] = escapedMac;
}
void serveJson(AsyncWebServerRequest* request)
{
byte subJson = 0;
const String& url = request->url();
if (url.indexOf("state") > 0) subJson = 1;
else if (url.indexOf("info") > 0) subJson = 2;
else if (url.indexOf("si") > 0) subJson = 3;
else if (url.indexOf("live") > 0) {
serveLiveLeds(request);
return;
}
else if (url.indexOf("eff") > 0) {
request->send_P(200, "application/json", JSON_mode_names);
return;
}
else if (url.indexOf("pal") > 0) {
request->send_P(200, "application/json", JSON_palette_names);
return;
}
else if (url.length() > 6) { //not just /json
request->send( 501, "application/json", F("{\"error\":\"Not implemented\"}"));
return;
}
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject doc = response->getRoot();
switch (subJson)
{
case 1: //state
serializeState(doc); break;
case 2: //info
serializeInfo(doc); break;
default: //all
JsonObject state = doc.createNestedObject("state");
serializeState(state);
JsonObject info = doc.createNestedObject("info");
serializeInfo(info);
if (subJson != 3)
{
doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names);
doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names);
}
}
response->setLength();
request->send(response);
}
#define MAX_LIVE_LEDS 180
void serveLiveLeds(AsyncWebServerRequest* request)
{
uint16_t used = ledCount;
uint16_t n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS
char buffer[2000] = "{\"leds\":[";
olen = 9;
obuf = buffer;
for (uint16_t i= 0; i < used; i += n)
{
olen += sprintf(buffer + olen, "\"%06X\",", strip.getPixelColor(i));
}
olen -= 1;
oappend("],\"n\":");
oappendi(n);
oappend("}");
request->send(200, "application/json", buffer);
}

262
wled00/led.cpp Normal file
View File

@@ -0,0 +1,262 @@
#include "wled.h"
/*
* LED methods
*/
void setValuesFromMainSeg()
{
WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
colorFromUint32(seg.colors[0]);
colorFromUint32(seg.colors[1], true);
effectCurrent = seg.mode;
effectSpeed = seg.speed;
effectIntensity = seg.intensity;
effectPalette = seg.palette;
}
void resetTimebase()
{
strip.timebase = 0 - millis();
}
void toggleOnOff()
{
if (bri == 0)
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
}
void setAllLeds() {
if (!realtimeMode || !arlsForceMaxBri)
{
double d = briT*briMultiplier;
int val = d/100;
if (val > 255) val = 255;
strip.setBrightness(val);
}
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY)
{
colorRGBtoRGBW(colT);
colorRGBtoRGBW(colSecT);
}
strip.setColor(0, colT[0], colT[1], colT[2], colT[3]);
strip.setColor(1, colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
}
void setLedsStandard(bool justColors)
{
for (byte i=0; i<4; i++)
{
colOld[i] = col[i];
colT[i] = col[i];
colSecOld[i] = colSec[i];
colSecT[i] = colSec[i];
}
if (justColors) return;
briOld = bri;
briT = bri;
setAllLeds();
}
bool colorChanged()
{
for (byte i=0; i<4; i++)
{
if (col[i] != colIT[i]) return true;
if (colSec[i] != colSecIT[i]) return true;
}
if (bri != briIT) return true;
return false;
}
void colorUpdated(int callMode)
{
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
if (callMode != NOTIFIER_CALL_MODE_INIT &&
callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
bool colChanged = colorChanged();
if (fxChanged || colChanged)
{
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
if (isPreset) {isPreset = false;}
else {currentPreset = -1;}
notify(callMode);
//set flag to update blynk and mqtt
if (callMode != NOTIFIER_CALL_MODE_PRESET_CYCLE) interfaceUpdateCallMode = callMode;
} else {
if (nightlightActive && !nightlightActiveOld &&
callMode != NOTIFIER_CALL_MODE_NOTIFICATION &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY)
{
notify(NOTIFIER_CALL_MODE_NIGHTLIGHT);
interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT;
}
}
if (!colChanged) return; //following code is for e.g. initiating transitions
if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && nightlightFade)
{
briNlT = bri;
nightlightDelayMs -= (millis() - nightlightStartTime);
nightlightStartTime = millis();
}
for (byte i=0; i<4; i++)
{
colIT[i] = col[i];
colSecIT[i] = colSec[i];
}
if (briT == 0)
{
setLedsStandard(true); //do not color transition if starting from off
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
}
briIT = bri;
if (bri > 0) briLast = bri;
if (fadeTransition)
{
//set correct delay if not using notification delay
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay;
jsonTransitionOnce = false;
if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;}
if (transitionActive)
{
for (byte i=0; i<4; i++)
{
colOld[i] = colT[i];
colSecOld[i] = colSecT[i];
}
briOld = briT;
tperLast = 0;
}
strip.setTransitionMode(true);
transitionActive = true;
transitionStartTime = millis();
} else
{
setLedsStandard();
strip.trigger();
}
}
void updateInterfaces(uint8_t callMode)
{
#ifndef WLED_DISABLE_ALEXA
if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
espalexaDevice->setValue(bri);
espalexaDevice->setColor(col[0], col[1], col[2]);
}
#endif
if (callMode != NOTIFIER_CALL_MODE_BLYNK &&
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk();
doPublishMqtt = true;
lastInterfaceUpdate = millis();
}
void handleTransitions()
{
//handle still pending interface update
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > 2000)
{
updateInterfaces(interfaceUpdateCallMode);
interfaceUpdateCallMode = 0; //disable
}
if (doPublishMqtt) publishMqtt();
if (transitionActive && transitionDelayTemp > 0)
{
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;
if (tper >= 1.0)
{
strip.setTransitionMode(false);
transitionActive = false;
tperLast = 0;
setLedsStandard();
return;
}
if (tper - tperLast < 0.004) return;
tperLast = tper;
for (byte i=0; i<4; i++)
{
colT[i] = colOld[i]+((col[i] - colOld[i])*tper);
colSecT[i] = colSecOld[i]+((colSec[i] - colSecOld[i])*tper);
}
briT = briOld +((bri - briOld )*tper);
setAllLeds();
}
}
void handleNightlight()
{
if (nightlightActive)
{
if (!nightlightActiveOld) //init
{
nightlightStartTime = millis();
nightlightDelayMs = (int)(nightlightDelayMins*60000);
nightlightActiveOld = true;
briNlT = bri;
for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color
}
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
if (nightlightFade)
{
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
if (nightlightColorFade) // color fading only is enabled with "NF=2"
{
for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
}
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
}
if (nper >= 1)
{
nightlightActive = false;
if (!nightlightFade)
{
bri = nightlightTargetBri;
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
}
updateBlynk();
if (bri == 0) briLast = briNlT;
}
} else if (nightlightActiveOld) //early de-init
{
nightlightActiveOld = false;
}
//also handle preset cycle here
if (presetCyclingEnabled && (millis() - presetCycledTime > presetCycleTime))
{
applyPreset(presetCycCurr,presetApplyBri);
presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin;
if (presetCycCurr > 25) presetCycCurr = 1;
colorUpdated(NOTIFIER_CALL_MODE_PRESET_CYCLE);
presetCycledTime = millis();
}
}

143
wled00/mqtt.cpp Normal file
View File

@@ -0,0 +1,143 @@
#include "wled.h"
/*
* MQTT communication protocol for home automation
*/
#ifdef WLED_ENABLE_MQTT
#define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds
void parseMQTTBriPayload(char* payload)
{
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
else if (strstr(payload, "T" ) || strstr(payload, "t" )) {toggleOnOff(); colorUpdated(1);}
else {
uint8_t in = strtoul(payload, NULL, 10);
if (in == 0 && bri > 0) briLast = bri;
bri = in;
colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE);
}
}
void onMqttConnect(bool sessionPresent)
{
//(re)subscribe to required topics
char subuf[38];
if (mqttDeviceTopic[0] != 0)
{
strcpy(subuf, mqttDeviceTopic);
mqtt->subscribe(subuf, 0);
strcat(subuf, "/col");
mqtt->subscribe(subuf, 0);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/api");
mqtt->subscribe(subuf, 0);
}
if (mqttGroupTopic[0] != 0)
{
strcpy(subuf, mqttGroupTopic);
mqtt->subscribe(subuf, 0);
strcat(subuf, "/col");
mqtt->subscribe(subuf, 0);
strcpy(subuf, mqttGroupTopic);
strcat(subuf, "/api");
mqtt->subscribe(subuf, 0);
}
doPublishMqtt = true;
DEBUG_PRINTLN("MQTT ready");
}
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
DEBUG_PRINT("MQTT msg: ");
DEBUG_PRINTLN(topic);
DEBUG_PRINTLN(payload);
//no need to check the topic because we only get topics we are subscribed to
if (strstr(topic, "/col"))
{
colorFromDecOrHexString(col, (char*)payload);
colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE);
} else if (strstr(topic, "/api"))
{
String apireq = "win&";
apireq += (char*)payload;
handleSet(nullptr, apireq);
} else parseMQTTBriPayload(payload);
}
void publishMqtt()
{
doPublishMqtt = false;
if (mqtt == nullptr || !mqtt->connected()) return;
DEBUG_PRINTLN("Publish MQTT");
char s[10];
char subuf[38];
sprintf(s, "%ld", bri);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/g");
mqtt->publish(subuf, 0, true, s);
sprintf(s, "#%06X", (col[3] << 24) | (col[0] << 16) | (col[1] << 8) | (col[2]));
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/c");
mqtt->publish(subuf, 0, true, s);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/status");
mqtt->publish(subuf, 0, true, "online");
char apires[1024];
XML_response(nullptr, apires);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/v");
mqtt->publish(subuf, 0, true, apires);
}
//HA autodiscovery was removed in favor of the native integration in HA v0.102.0
bool initMqtt()
{
lastMqttReconnectAttempt = millis();
if (!mqttEnabled || mqttServer[0] == 0 || !WLED_CONNECTED) return false;
if (mqtt == nullptr) {
mqtt = new AsyncMqttClient();
mqtt->onMessage(onMqttMessage);
mqtt->onConnect(onMqttConnect);
}
if (mqtt->connected()) return true;
DEBUG_PRINTLN("Reconnecting MQTT");
IPAddress mqttIP;
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
{
mqtt->setServer(mqttIP, mqttPort);
} else {
mqtt->setServer(mqttServer, mqttPort);
}
mqtt->setClientId(mqttClientID);
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
strcpy(mqttStatusTopic, mqttDeviceTopic);
strcat(mqttStatusTopic, "/status");
mqtt->setWill(mqttStatusTopic, 0, true, "offline");
mqtt->setKeepAlive(MQTT_KEEP_ALIVE_TIME);
mqtt->connect();
return true;
}
#else
bool initMqtt(){return false;}
void publishMqtt(){}
#endif

View File

@@ -1,3 +1,6 @@
#include "src/dependencies/timezone/Timezone.h"
#include "wled.h"
/*
* Acquires time from NTP server
*/
@@ -25,6 +28,8 @@ TimeChangeRule CDT = {Second, Sun, Mar, 2, -300 }; //Daylight time = UTC - 5
TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours
Timezone tzUSCentral(CDT, CST);
Timezone tzCASaskatchewan(CST, CST); //Central without DST
TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours
TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours
Timezone tzUSMountain(MDT, MST);
@@ -49,11 +54,23 @@ TimeChangeRule NZDT = {Second, Sun, Sep, 2, 780 }; //Daylight time = UTC + 13
TimeChangeRule NZST = {First, Sun, Apr, 3, 720 }; //Standard time = UTC + 12 hours
Timezone tzNZ(NZDT, NZST);
Timezone* timezones[] = { &tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ};
TimeChangeRule NKST = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours
Timezone tzNK(NKST, NKST);
TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours
Timezone tzIndia(IST, IST);
TimeChangeRule ACST = {First, Sun, Apr, 3, 570}; //Australian Central Standard = UTC + 9.5 hours
TimeChangeRule ACDT = {First, Sun, Oct, 2, 630}; //Australian Central Daylight = UTC + 10.5 hours
Timezone tzAUNorthern(ACST, ACST);
Timezone tzAUSouthern(ACDT, ACST);
// Pick your timezone from here.
Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan, &tzAUNorthern, &tzAUSouthern};
void handleNetworkTime()
{
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WiFi.status() == WL_CONNECTED)
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WLED_CONNECTED)
{
if (millis() - ntpPacketSentTime > 10000)
{
@@ -69,24 +86,31 @@ void handleNetworkTime()
void sendNTPPacket()
{
const char* ntpsrv = ntpServerName.c_str();
WiFi.hostByName(ntpsrv, ntpServerIP);
DEBUG_PRINTLN("send NTP packet");
if (!ntpServerIP.fromString(ntpServerName)) //see if server is IP or domain
{
#ifdef ESP8266
WiFi.hostByName(ntpServerName, ntpServerIP, 750);
#else
WiFi.hostByName(ntpServerName, ntpServerIP);
#endif
}
memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
DEBUG_PRINTLN("send NTP");
byte pbuf[NTP_PACKET_SIZE];
memset(pbuf, 0, NTP_PACKET_SIZE);
ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode
ntpPacketBuffer[1] = 0; // Stratum, or type of clock
ntpPacketBuffer[2] = 6; // Polling Interval
ntpPacketBuffer[3] = 0xEC; // Peer Clock Precision
pbuf[0] = 0b11100011; // LI, Version, Mode
pbuf[1] = 0; // Stratum, or type of clock
pbuf[2] = 6; // Polling Interval
pbuf[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
ntpPacketBuffer[12] = 49;
ntpPacketBuffer[13] = 0x4E;
ntpPacketBuffer[14] = 49;
ntpPacketBuffer[15] = 52;
pbuf[12] = 49;
pbuf[13] = 0x4E;
pbuf[14] = 49;
pbuf[15] = 52;
ntpUdp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123
ntpUdp.write(ntpPacketBuffer, NTP_PACKET_SIZE);
ntpUdp.write(pbuf, NTP_PACKET_SIZE);
ntpUdp.endPacket();
}
@@ -94,19 +118,19 @@ bool checkNTPResponse()
{
int cb = ntpUdp.parsePacket();
if (cb) {
DEBUG_PRINT("packet received, length=");
DEBUG_PRINT("NTP recv, l=");
DEBUG_PRINTLN(cb);
byte pbuf[NTP_PACKET_SIZE];
ntpUdp.read(pbuf, NTP_PACKET_SIZE); // read the packet into the buffer
ntpUdp.read(ntpPacketBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(ntpPacketBuffer[40], ntpPacketBuffer[41]);
unsigned long lowWord = word(ntpPacketBuffer[42], ntpPacketBuffer[43]);
unsigned long highWord = word(pbuf[40], pbuf[41]);
unsigned long lowWord = word(pbuf[42], pbuf[43]);
if (highWord == 0 && lowWord == 0) return false;
unsigned long secsSince1900 = highWord << 16 | lowWord;
DEBUG_PRINT("Unix time = ");
unsigned long epoch = secsSince1900 - 2208988800UL; //subtract 70 years
unsigned long epoch = secsSince1900 - 2208988799UL; //subtract 70 years -1sec (on avg. more precision)
setTime(epoch);
DEBUG_PRINTLN(epoch);
if (countdownTime - now() > 0) countdownOverTriggered = false;
@@ -121,27 +145,22 @@ void updateLocalTime()
local = timezones[currentTimezone]->toLocal(tmc);
}
String getTimeString()
void getTimeString(char* out)
{
updateLocalTime();
String ret = monthStr(month(local));
ret = ret + " ";
ret = ret + day(local);
ret = ret + " ";
ret = ret + year(local);
ret = ret + ", ";
ret += (useAMPM)? hour(local)%12:hour(local);
ret = ret + ":";
if (minute(local) < 10) ret = ret + "0";
ret = ret + minute(local);
ret = ret + ":";
if (second(local) < 10) ret = ret + "0";
ret = ret + second(local);
byte hr = hour(local);
if (useAMPM)
{
ret += (hour(local) > 11)? " PM":" AM";
if (hr > 11) hr -= 12;
if (hr == 0) hr = 12;
}
sprintf(out,"%i-%i-%i, %i:%s%i:%s%i",year(local), month(local), day(local),
hr,(minute(local)<10)?"0":"",minute(local),
(second(local)<10)?"0":"",second(local));
if (useAMPM)
{
strcat(out,(hour(local) > 11)? " PM":" AM");
}
return ret;
}
void setCountdown()
@@ -153,14 +172,42 @@ void setCountdown()
//returns true if countdown just over
bool checkCountdown()
{
long diff = countdownTime - now();
local = abs(diff);
if (diff <0 && !countdownOverTriggered)
{
if (macroCountdown != 0) applyMacro(macroCountdown);
countdownOverTriggered = true;
return true;
unsigned long n = now();
if (countdownMode) local = countdownTime - n + utcOffsetSecs;
if (n > countdownTime) {
if (countdownMode) local = n - countdownTime + utcOffsetSecs;
if (!countdownOverTriggered)
{
if (macroCountdown != 0) applyMacro(macroCountdown);
countdownOverTriggered = true;
return true;
}
}
return false;
}
byte weekdayMondayFirst()
{
byte wd = weekday(local) -1;
if (wd == 0) wd = 7;
return wd;
}
void checkTimers()
{
if (lastTimerMinute != minute(local)) //only check once a new minute begins
{
lastTimerMinute = minute(local);
for (uint8_t i = 0; i < 8; i++)
{
if (timerMacro[i] != 0
&& (timerHours[i] == hour(local) || timerHours[i] == 24) //if hour is set to 24, activate every hour
&& timerMinutes[i] == minute(local)
&& (timerWeekday[i] & 0x01) //timer is enabled
&& timerWeekday[i] >> weekdayMondayFirst() & 0x01) //timer should activate at current day of week
{
applyMacro(timerMacro[i]);
}
}
}
}

376
wled00/overlay.cpp Normal file
View File

@@ -0,0 +1,376 @@
#include "wled.h"
/*
* Used to draw clock overlays over the strip
*/
void initCronixie()
{
if (overlayCurrent == 3 && !cronixieInit)
{
setCronixie();
strip.getSegment(0).grouping = 10; //10 LEDs per digit
cronixieInit = true;
} else if (cronixieInit && overlayCurrent != 3)
{
strip.getSegment(0).grouping = 1;
cronixieInit = false;
}
}
void handleOverlays()
{
if (millis() - overlayRefreshedTime > overlayRefreshMs)
{
initCronixie();
updateLocalTime();
checkTimers();
checkCountdown();
if (overlayCurrent == 3) _overlayCronixie();//Diamex cronixie clock kit
overlayRefreshedTime = millis();
}
}
void _overlayAnalogClock()
{
int overlaySize = overlayMax - overlayMin +1;
if (countdownMode)
{
_overlayAnalogCountdown(); return;
}
double hourP = ((double)(hour(local)%12))/12;
double minuteP = ((double)minute(local))/60;
hourP = hourP + minuteP/12;
double secondP = ((double)second(local))/60;
int hourPixel = floor(analogClock12pixel + overlaySize*hourP);
if (hourPixel > overlayMax) hourPixel = overlayMin -1 + hourPixel - overlayMax;
int minutePixel = floor(analogClock12pixel + overlaySize*minuteP);
if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax;
int secondPixel = floor(analogClock12pixel + overlaySize*secondP);
if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax;
if (analogClockSecondsTrail)
{
if (secondPixel < analogClock12pixel)
{
strip.setRange(analogClock12pixel, overlayMax, 0xFF0000);
strip.setRange(overlayMin, secondPixel, 0xFF0000);
} else
{
strip.setRange(analogClock12pixel, secondPixel, 0xFF0000);
}
}
if (analogClock5MinuteMarks)
{
int pix;
for (int i = 0; i <= 12; i++)
{
pix = analogClock12pixel + round((overlaySize / 12.0) *i);
if (pix > overlayMax) pix -= overlaySize;
strip.setPixelColor(pix, 0x00FFAA);
}
}
if (!analogClockSecondsTrail) strip.setPixelColor(secondPixel, 0xFF0000);
strip.setPixelColor(minutePixel, 0x00FF00);
strip.setPixelColor(hourPixel, 0x0000FF);
overlayRefreshMs = 998;
}
void _overlayAnalogCountdown()
{
if (now() < countdownTime)
{
long diff = countdownTime - now();
double pval = 60;
if (diff > 31557600L) //display in years if more than 365 days
{
pval = 315576000L; //10 years
} else if (diff > 2592000L) //display in months if more than a month
{
pval = 31557600L; //1 year
} else if (diff > 604800) //display in weeks if more than a week
{
pval = 2592000L; //1 month
} else if (diff > 86400) //display in days if more than 24 hours
{
pval = 604800; //1 week
} else if (diff > 3600) //display in hours if more than 60 minutes
{
pval = 86400; //1 day
} else if (diff > 60) //display in minutes if more than 60 seconds
{
pval = 3600; //1 hour
}
int overlaySize = overlayMax - overlayMin +1;
double perc = (pval-(double)diff)/pval;
if (perc > 1.0) perc = 1.0;
byte pixelCnt = perc*overlaySize;
if (analogClock12pixel + pixelCnt > overlayMax)
{
strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
} else
{
strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
}
}
overlayRefreshMs = 998;
}
void handleOverlayDraw() {
if (!overlayCurrent) return;
switch (overlayCurrent)
{
case 1: _overlayAnalogClock(); break;
case 3: _drawOverlayCronixie(); break;
}
}
/*
* Support for the Cronixie clock
*/
#ifndef WLED_DISABLE_CRONIXIE
byte _digitOut[6] = {10,10,10,10,10,10};
byte getSameCodeLength(char code, int index, char const cronixieDisplay[])
{
byte counter = 0;
for (int i = index+1; i < 6; i++)
{
if (cronixieDisplay[i] == code)
{
counter++;
} else {
return counter;
}
}
return counter;
}
void setCronixie()
{
/*
* digit purpose index
* 0-9 | 0-9 (incl. random)
* 10 | blank
* 11 | blank, bg off
* 12 | test upw.
* 13 | test dnw.
* 14 | binary AM/PM
* 15 | BB upper +50 for no trailing 0
* 16 | BBB
* 17 | BBBB
* 18 | BBBBB
* 19 | BBBBBB
* 20 | H
* 21 | HH
* 22 | HHH
* 23 | HHHH
* 24 | M
* 25 | MM
* 26 | MMM
* 27 | MMMM
* 28 | MMMMM
* 29 | MMMMMM
* 30 | S
* 31 | SS
* 32 | SSS
* 33 | SSSS
* 34 | SSSSS
* 35 | SSSSSS
* 36 | Y
* 37 | YY
* 38 | YYYY
* 39 | I
* 40 | II
* 41 | W
* 42 | WW
* 43 | D
* 44 | DD
* 45 | DDD
* 46 | V
* 47 | VV
* 48 | VVV
* 49 | VVVV
* 50 | VVVVV
* 51 | VVVVVV
* 52 | v
* 53 | vv
* 54 | vvv
* 55 | vvvv
* 56 | vvvvv
* 57 | vvvvvv
*/
//H HourLower | HH - Hour 24. | AH - Hour 12. | HHH Hour of Month | HHHH Hour of Year
//M MinuteUpper | MM Minute of Hour | MMM Minute of 12h | MMMM Minute of Day | MMMMM Minute of Month | MMMMMM Minute of Year
//S SecondUpper | SS Second of Minute | SSS Second of 10 Minute | SSSS Second of Hour | SSSSS Second of Day | SSSSSS Second of Week
//B AM/PM | BB 0-6/6-12/12-18/18-24 | BBB 0-3... | BBBB 0-1.5... | BBBBB 0-1 | BBBBBB 0-0.5
//Y YearLower | YY - Year LU | YYYY - Std.
//I MonthLower | II - Month of Year
//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);
overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed
for (int i = 0; i < 6; i++)
{
dP[i] = 10;
switch (cronixieDisplay[i])
{
case '_': dP[i] = 10; break;
case '-': dP[i] = 11; break;
case 'r': dP[i] = random(1,7); break; //random btw. 1-6
case 'R': dP[i] = random(0,10); break; //random btw. 0-9
//case 't': break; //Test upw.
//case 'T': break; //Test dnw.
case 'b': dP[i] = 14 + getSameCodeLength('b',i,cronixieDisplay); i = i+dP[i]-14; break;
case 'B': dP[i] = 14 + getSameCodeLength('B',i,cronixieDisplay); i = i+dP[i]-14; break;
case 'h': dP[i] = 70 + getSameCodeLength('h',i,cronixieDisplay); i = i+dP[i]-70; break;
case 'H': dP[i] = 20 + getSameCodeLength('H',i,cronixieDisplay); i = i+dP[i]-20; break;
case 'A': dP[i] = 108; i++; break;
case 'a': dP[i] = 58; i++; break;
case 'm': dP[i] = 74 + getSameCodeLength('m',i,cronixieDisplay); i = i+dP[i]-74; break;
case 'M': dP[i] = 24 + getSameCodeLength('M',i,cronixieDisplay); i = i+dP[i]-24; break;
case 's': dP[i] = 80 + getSameCodeLength('s',i,cronixieDisplay); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs
case 'S': dP[i] = 30 + getSameCodeLength('S',i,cronixieDisplay); i = i+dP[i]-30; overlayRefreshMs = 497; break;
case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,cronixieDisplay); i = i+dP[i]-36; break;
case 'y': dP[i] = 86 + getSameCodeLength('y',i,cronixieDisplay); i = i+dP[i]-86; break;
case 'I': dP[i] = 39 + getSameCodeLength('I',i,cronixieDisplay); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M.
case 'i': dP[i] = 89 + getSameCodeLength('i',i,cronixieDisplay); i = i+dP[i]-89; break;
//case 'W': break;
//case 'w': break;
case 'D': dP[i] = 43 + getSameCodeLength('D',i,cronixieDisplay); i = i+dP[i]-43; break;
case 'd': dP[i] = 93 + getSameCodeLength('d',i,cronixieDisplay); i = i+dP[i]-93; break;
case '0': dP[i] = 0; break;
case '1': dP[i] = 1; break;
case '2': dP[i] = 2; break;
case '3': dP[i] = 3; break;
case '4': dP[i] = 4; break;
case '5': dP[i] = 5; break;
case '6': dP[i] = 6; break;
case '7': dP[i] = 7; break;
case '8': dP[i] = 8; break;
case '9': dP[i] = 9; break;
//case 'V': break; //user var0
//case 'v': break; //user var1
}
}
DEBUG_PRINT("result ");
for (int i = 0; i < 5; i++)
{
DEBUG_PRINT((int)dP[i]);
DEBUG_PRINT(" ");
}
DEBUG_PRINTLN((int)dP[5]);
_overlayCronixie(); //refresh
}
void _overlayCronixie()
{
byte h = hour(local);
byte h0 = h;
byte m = minute(local);
byte s = second(local);
byte d = day(local);
byte mi = month(local);
int y = year(local);
//this has to be changed in time for 22nd century
y -= 2000; if (y<0) y += 30; //makes countdown work
if (useAMPM && !countdownMode)
{
if (h>12) h-=12;
else if (h==0) h+=12;
}
for (int i = 0; i < 6; i++)
{
if (dP[i] < 12) _digitOut[i] = dP[i];
else {
if (dP[i] < 65)
{
switch(dP[i])
{
case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH
case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM
case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS
case 20: _digitOut[i] = h- (h/10)*10; break; //H
case 24: _digitOut[i] = m/10; break; //M
case 30: _digitOut[i] = s/10; break; //S
case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D
case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD
case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II
case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY
case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY
//case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI)
//case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB
case 14: _digitOut[i] = (h0>11)?1:0; break; //B
}
} else
{
switch(dP[i])
{
case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh
case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm
case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss
//case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI)
//case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb
case 64: _digitOut[i] = (h0>11)?1:10; break; //b
case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d
case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd
case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii
case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy
case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy
}
}
}
}
}
void _drawOverlayCronixie()
{
byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4};
for (uint16_t i = 0; i < 6; i++)
{
byte o = 10*i;
byte excl = 10;
if(_digitOut[i] < 10) excl = offsets[_digitOut[i]];
excl += o;
if (cronixieBacklight && _digitOut[i] <11)
{
uint32_t col = strip.gamma32(strip.getSegment(0).colors[1]);
for (uint16_t j=o; j< o+10; j++) {
if (j != excl) strip.setPixelColor(j, col);
}
} else
{
for (uint16_t j=o; j< o+10; j++) {
if (j != excl) strip.setPixelColor(j, 0);
}
}
}
}
#else // WLED_DISABLE_CRONIXIE
byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {}
void setCronixie() {}
void _overlayCronixie() {}
void _drawOverlayCronixie() {}
#endif

633
wled00/palettes.h Normal file
View File

@@ -0,0 +1,633 @@
/*
* Color palettes for FastLED effects (65-73).
*/
// From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
// Unfortunaltely, these are stored in RAM!
// Gradient palette "ib_jul01_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/xmas/tn/ib_jul01.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 16 bytes of program space.
#ifndef PalettesWLED_h
#define PalettesWLED_h
#define GRADIENT_PALETTE_COUNT 39
const byte ib_jul01_gp[] PROGMEM = {
0, 194, 1, 1,
94, 1, 29, 18,
132, 57,131, 28,
255, 113, 1, 1};
// Gradient palette "es_vintage_57_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_57.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte es_vintage_57_gp[] PROGMEM = {
0, 2, 1, 1,
53, 18, 1, 0,
104, 69, 29, 1,
153, 167,135, 10,
255, 46, 56, 4};
// Gradient palette "es_vintage_01_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_01.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.
const byte es_vintage_01_gp[] PROGMEM = {
0, 4, 1, 1,
51, 16, 0, 1,
76, 97,104, 3,
101, 255,131, 19,
127, 67, 9, 4,
153, 16, 0, 1,
229, 4, 1, 1,
255, 4, 1, 1};
// Gradient palette "es_rivendell_15_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/rivendell/tn/es_rivendell_15.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte es_rivendell_15_gp[] PROGMEM = {
0, 1, 14, 5,
101, 16, 36, 14,
165, 56, 68, 30,
242, 150,156, 99,
255, 150,156, 99};
// Gradient palette "rgi_15_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/rgi/tn/rgi_15.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 36 bytes of program space.
// Edited to be brighter
const byte rgi_15_gp[] PROGMEM = {
0, 4, 1, 70,
31, 55, 1, 30,
63, 255, 4, 7,
95, 59, 2, 29,
127, 11, 3, 50,
159, 39, 8, 60,
191, 112, 19, 40,
223, 78, 11, 39,
255, 29, 8, 59};
// Gradient palette "retro2_16_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/retro2/tn/retro2_16.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 8 bytes of program space.
const byte retro2_16_gp[] PROGMEM = {
0, 188,135, 1,
255, 46, 7, 1};
// Gradient palette "Analogous_1_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/red/tn/Analogous_1.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte Analogous_1_gp[] PROGMEM = {
0, 3, 0,255,
63, 23, 0,255,
127, 67, 0,255,
191, 142, 0, 45,
255, 255, 0, 0};
// Gradient palette "es_pinksplash_08_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/pink_splash/tn/es_pinksplash_08.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte es_pinksplash_08_gp[] PROGMEM = {
0, 126, 11,255,
127, 197, 1, 22,
175, 210,157,172,
221, 157, 3,112,
255, 157, 3,112};
// Gradient palette "es_ocean_breeze_036_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/ocean_breeze/tn/es_ocean_breeze_036.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 16 bytes of program space.
const byte es_ocean_breeze_036_gp[] PROGMEM = {
0, 1, 6, 7,
89, 1, 99,111,
153, 144,209,255,
255, 0, 73, 82};
// Gradient palette "departure_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/mjf/tn/departure.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 88 bytes of program space.
const byte departure_gp[] PROGMEM = {
0, 8, 3, 0,
42, 23, 7, 0,
63, 75, 38, 6,
84, 169, 99, 38,
106, 213,169,119,
116, 255,255,255,
138, 135,255,138,
148, 22,255, 24,
170, 0,255, 0,
191, 0,136, 0,
212, 0, 55, 0,
255, 0, 55, 0};
// Gradient palette "es_landscape_64_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_64.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 36 bytes of program space.
const byte es_landscape_64_gp[] PROGMEM = {
0, 0, 0, 0,
37, 2, 25, 1,
76, 15,115, 5,
127, 79,213, 1,
128, 126,211, 47,
130, 188,209,247,
153, 144,182,205,
204, 59,117,250,
255, 1, 37,192};
// Gradient palette "es_landscape_33_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_33.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 24 bytes of program space.
const byte es_landscape_33_gp[] PROGMEM = {
0, 1, 5, 0,
19, 32, 23, 1,
38, 161, 55, 1,
63, 229,144, 1,
66, 39,142, 74,
255, 1, 4, 1};
// Gradient palette "rainbowsherbet_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/icecream/tn/rainbowsherbet.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte rainbowsherbet_gp[] PROGMEM = {
0, 255, 33, 4,
43, 255, 68, 25,
86, 255, 7, 25,
127, 255, 82,103,
170, 255,255,242,
209, 42,255, 22,
255, 87,255, 65};
// Gradient palette "gr65_hult_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr65_hult.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 24 bytes of program space.
const byte gr65_hult_gp[] PROGMEM = {
0, 247,176,247,
48, 255,136,255,
89, 220, 29,226,
160, 7, 82,178,
216, 1,124,109,
255, 1,124,109};
// Gradient palette "gr64_hult_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr64_hult.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.
const byte gr64_hult_gp[] PROGMEM = {
0, 1,124,109,
66, 1, 93, 79,
104, 52, 65, 1,
130, 115,127, 1,
150, 52, 65, 1,
201, 1, 86, 72,
239, 0, 55, 45,
255, 0, 55, 45};
// Gradient palette "GMT_drywet_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/gmt/tn/GMT_drywet.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte GMT_drywet_gp[] PROGMEM = {
0, 47, 30, 2,
42, 213,147, 24,
84, 103,219, 52,
127, 3,219,207,
170, 1, 48,214,
212, 1, 1,111,
255, 1, 7, 33};
// Gradient palette "ib15_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/general/tn/ib15.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 24 bytes of program space.
const byte ib15_gp[] PROGMEM = {
0, 113, 91,147,
72, 157, 88, 78,
89, 208, 85, 33,
107, 255, 29, 11,
141, 137, 31, 39,
255, 59, 33, 89};
// Gradient palette "Tertiary_01_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/vermillion/tn/Tertiary_01.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte Tertiary_01_gp[] PROGMEM = {
0, 0, 1,255,
63, 3, 68, 45,
127, 23,255, 0,
191, 100, 68, 1,
255, 255, 1, 4};
// Gradient palette "lava_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/lava.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 52 bytes of program space.
const byte lava_gp[] PROGMEM = {
0, 0, 0, 0,
46, 18, 0, 0,
96, 113, 0, 0,
108, 142, 3, 1,
119, 175, 17, 1,
146, 213, 44, 2,
174, 255, 82, 4,
188, 255,115, 4,
202, 255,156, 4,
218, 255,203, 4,
234, 255,255, 4,
244, 255,255, 71,
255, 255,255,255};
// Gradient palette "fierce_ice_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/fierce-ice.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte fierce_ice_gp[] PROGMEM = {
0, 0, 0, 0,
59, 0, 9, 45,
119, 0, 38,255,
149, 3,100,255,
180, 23,199,255,
217, 100,235,255,
255, 255,255,255};
// Gradient palette "Colorfull_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Colorfull.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 44 bytes of program space.
const byte Colorfull_gp[] PROGMEM = {
0, 10, 85, 5,
25, 29,109, 18,
60, 59,138, 42,
93, 83, 99, 52,
106, 110, 66, 64,
109, 123, 49, 65,
113, 139, 35, 66,
116, 192,117, 98,
124, 255,255,137,
168, 100,180,155,
255, 22,121,174};
// Gradient palette "Pink_Purple_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Pink_Purple.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 44 bytes of program space.
const byte Pink_Purple_gp[] PROGMEM = {
0, 19, 2, 39,
25, 26, 4, 45,
51, 33, 6, 52,
76, 68, 62,125,
102, 118,187,240,
109, 163,215,247,
114, 217,244,255,
122, 159,149,221,
149, 113, 78,188,
183, 128, 57,155,
255, 146, 40,123};
// Gradient palette "Sunset_Real_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte Sunset_Real_gp[] PROGMEM = {
0, 120, 0, 0,
22, 179, 22, 0,
51, 255,104, 0,
85, 167, 22, 18,
135, 100, 0,103,
198, 16, 0,130,
255, 0, 0,160};
// Gradient palette "Sunset_Yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 44 bytes of program space.
const byte Sunset_Yellow_gp[] PROGMEM = {
0, 10, 62,123,
36, 56,130,103,
87, 153,225, 85,
100, 199,217, 68,
107, 255,207, 54,
115, 247,152, 57,
120, 239,107, 61,
128, 247,152, 57,
180, 255,207, 54,
223, 255,227, 48,
255, 255,248, 42};
// Gradient palette "Beech_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Beech.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 60 bytes of program space.
const byte Beech_gp[] PROGMEM = {
0, 255,252,214,
12, 255,252,214,
22, 255,252,214,
26, 190,191,115,
28, 137,141, 52,
28, 112,255,205,
50, 51,246,214,
71, 17,235,226,
93, 2,193,199,
120, 0,156,174,
133, 1,101,115,
136, 1, 59, 71,
136, 7,131,170,
208, 1, 90,151,
255, 0, 56,133};
// Gradient palette "Another_Sunset_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Another_Sunset.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.
const byte Another_Sunset_gp[] PROGMEM = {
0, 110, 49, 11,
29, 55, 34, 10,
68, 22, 22, 9,
68, 239,124, 8,
97, 220,156, 27,
124, 203,193, 61,
178, 33, 53, 56,
255, 0, 1, 52};
// Gradient palette "es_autumn_19_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/autumn/tn/es_autumn_19.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 52 bytes of program space.
const byte es_autumn_19_gp[] PROGMEM = {
0, 26, 1, 1,
51, 67, 4, 1,
84, 118, 14, 1,
104, 137,152, 52,
112, 113, 65, 1,
122, 133,149, 59,
124, 137,152, 52,
135, 113, 65, 1,
142, 139,154, 46,
163, 113, 13, 1,
204, 55, 3, 1,
249, 17, 1, 1,
255, 17, 1, 1};
// Gradient palette "BlacK_Blue_Magenta_White_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Blue_Magenta_White.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte BlacK_Blue_Magenta_White_gp[] PROGMEM = {
0, 0, 0, 0,
42, 0, 0, 45,
84, 0, 0,255,
127, 42, 0,255,
170, 255, 0,255,
212, 255, 55,255,
255, 255,255,255};
// Gradient palette "BlacK_Magenta_Red_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Magenta_Red.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte BlacK_Magenta_Red_gp[] PROGMEM = {
0, 0, 0, 0,
63, 42, 0, 45,
127, 255, 0,255,
191, 255, 0, 45,
255, 255, 0, 0};
// Gradient palette "BlacK_Red_Magenta_Yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Red_Magenta_Yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.
const byte BlacK_Red_Magenta_Yellow_gp[] PROGMEM = {
0, 0, 0, 0,
42, 42, 0, 0,
84, 255, 0, 0,
127, 255, 0, 45,
170, 255, 0,255,
212, 255, 55, 45,
255, 255,255, 0};
// Gradient palette "Blue_Cyan_Yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Blue_Cyan_Yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.
const byte Blue_Cyan_Yellow_gp[] PROGMEM = {
0, 0, 0,255,
63, 0, 55,255,
127, 0,255,255,
191, 42,255, 45,
255, 255,255, 0};
//Custom palette by Aircoookie
const byte Orange_Teal_gp[] PROGMEM = {
0, 0,150, 92,
55, 0,150, 92,
200, 255, 72, 0,
255, 255, 72, 0};
//Custom palette by Aircoookie
const byte Tiamat_gp[] PROGMEM = {
0, 1, 2, 14, //gc
33, 2, 5, 35, //gc from 47, 61,126
100, 13,135, 92, //gc from 88,242,247
120, 43,255,193, //gc from 135,255,253
140, 247, 7,249, //gc from 252, 69,253
160, 193, 17,208, //gc from 231, 96,237
180, 39,255,154, //gc from 130, 77,213
200, 4,213,236, //gc from 57,122,248
220, 39,252,135, //gc from 177,254,255
240, 193,213,253, //gc from 203,239,253
255, 255,249,255};
//Custom palette by Aircoookie
const byte April_Night_gp[] PROGMEM = {
0, 1, 5, 45, //deep blue
10, 1, 5, 45,
25, 5,169,175, //light blue
40, 1, 5, 45,
61, 1, 5, 45,
76, 45,175, 31, //green
91, 1, 5, 45,
112, 1, 5, 45,
127, 249,150, 5, //yellow
143, 1, 5, 45,
162, 1, 5, 45,
178, 255, 92, 0, //pastel orange
193, 1, 5, 45,
214, 1, 5, 45,
229, 223, 45, 72, //pink
244, 1, 5, 45,
255, 1, 5, 45};
const byte Orangery_gp[] PROGMEM = {
0, 255, 95, 23,
30, 255, 82, 0,
60, 223, 13, 8,
90, 144, 44, 2,
120, 255,110, 17,
150, 255, 69, 0,
180, 158, 13, 11,
210, 241, 82, 17,
255, 213, 37, 4};
//inspired by Mark Kriegsman https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
const byte C9_gp[] PROGMEM = {
0, 184, 4, 0, //red
60, 184, 4, 0,
65, 144, 44, 2, //amber
125, 144, 44, 2,
130, 4, 96, 2, //green
190, 4, 96, 2,
195, 7, 7, 88, //blue
255, 7, 7, 88};
const byte Sakura_gp[] PROGMEM = {
0, 196, 19, 10,
65, 255, 69, 45,
130, 223, 45, 72,
195, 255, 82,103,
255, 223, 13, 17};
const byte Aurora_gp[] PROGMEM = {
0, 1, 5, 45, //deep blue
64, 0,200, 23,
128, 0,255, 0, //green
170, 0,243, 45,
200, 0,135, 7,
255, 1, 5, 45};//deep blue
const byte Atlantica_gp[] PROGMEM = {
0, 0, 28,112, //#001C70
50, 32, 96,255, //#2060FF
100, 0,243, 45,
150, 12, 95, 82, //#0C5F52
200, 25,190, 95, //#19BE5F
255, 40,170, 80};//#28AA50
// Single array of defined cpt-city color palettes.
// This will let us programmatically choose one based on
// a number, rather than having to activate each explicitly
// by name every time.
const byte* const gGradientPalettes[] PROGMEM = {
Sunset_Real_gp, //13-00 Sunset
es_rivendell_15_gp, //14-01 Rivendell
es_ocean_breeze_036_gp, //15-02 Breeze
rgi_15_gp, //16-03 Red & Blue
retro2_16_gp, //17-04 Yellowout
Analogous_1_gp, //18-05 Analogous
es_pinksplash_08_gp, //19-06 Splash
Sunset_Yellow_gp, //20-07 Pastel
Another_Sunset_gp, //21-08 Sunset2
Beech_gp, //22-09 Beech
es_vintage_01_gp, //23-10 Vintage
departure_gp, //24-11 Departure
es_landscape_64_gp, //25-12 Landscape
es_landscape_33_gp, //26-13 Beach
rainbowsherbet_gp, //27-14 Sherbet
gr65_hult_gp, //28-15 Hult
gr64_hult_gp, //29-16 Hult64
GMT_drywet_gp, //30-17 Drywet
ib_jul01_gp, //31-18 Jul
es_vintage_57_gp, //32-19 Grintage
ib15_gp, //33-20 Rewhi
Tertiary_01_gp, //34-21 Tertiary
lava_gp, //35-22 Fire
fierce_ice_gp, //36-23 Icefire
Colorfull_gp, //37-24 Cyane
Pink_Purple_gp, //38-25 Light Pink
es_autumn_19_gp, //39-26 Autumn
BlacK_Blue_Magenta_White_gp, //40-27 Magenta
BlacK_Magenta_Red_gp, //41-28 Magred
BlacK_Red_Magenta_Yellow_gp, //42-29 Yelmag
Blue_Cyan_Yellow_gp, //43-30 Yelblu
Orange_Teal_gp, //44-31 Orange & Teal
Tiamat_gp, //45-32 Tiamat
April_Night_gp, //46-33 April Night
Orangery_gp, //47-34 Orangery
C9_gp, //48-35 C9
Sakura_gp, //49-36 Sakura
Aurora_gp, //50-37 Aurora
Atlantica_gp, //51-38 Atlantica
};
#endif

704
wled00/set.cpp Normal file
View File

@@ -0,0 +1,704 @@
#include "wled.h"
/*
* Receives client input
*/
void _setRandomColor(bool _sec,bool fromButton)
{
lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex);
if (_sec){
colorHStoRGB(lastRandomIndex*256,255,colSec);
} else {
colorHStoRGB(lastRandomIndex*256,255,col);
}
if (fromButton) colorUpdated(2);
}
bool isAsterisksOnly(const char* str, byte maxLen)
{
for (byte i = 0; i < maxLen; i++) {
if (str[i] == 0) break;
if (str[i] != '*') return false;
}
return true;
}
//called upon POST settings form submit
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
{
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 7: DMX
if (subPage <1 || subPage >7) return;
//WIFI SETTINGS
if (subPage == 1)
{
strlcpy(clientSSID,request->arg("CS").c_str(), 33);
if (!isAsterisksOnly(request->arg("CP").c_str(), 65)) strlcpy(clientPass, request->arg("CP").c_str(), 65);
strlcpy(cmDNS, request->arg("CM").c_str(), 33);
apBehavior = request->arg("AB").toInt();
strlcpy(apSSID, request->arg("AS").c_str(), 33);
apHide = request->hasArg("AH");
int passlen = request->arg("AP").length();
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg("AP").c_str(), 65))) strlcpy(apPass, request->arg("AP").c_str(), 65);
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
noWifiSleep = request->hasArg("WS");
char k[3]; k[2] = 0;
for (int i = 0; i<4; i++)
{
k[1] = i+48;//ascii 0,1,2,3
k[0] = 'I'; //static IP
staticIP[i] = request->arg(k).toInt();
k[0] = 'G'; //gateway
staticGateway[i] = request->arg(k).toInt();
k[0] = 'S'; //subnet
staticSubnet[i] = request->arg(k).toInt();
}
}
//LED SETTINGS
if (subPage == 2)
{
int t = request->arg("LC").toInt();
if (t > 0 && t <= MAX_LEDS) ledCount = t;
#ifdef ESP8266
#if LEDPIN == 3
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
#endif
#endif
strip.ablMilliampsMax = request->arg("MA").toInt();
strip.milliampsPerLed = request->arg("LA").toInt();
useRGBW = request->hasArg("EW");
strip.colorOrder = request->arg("CO").toInt();
strip.rgbwMode = request->arg("AW").toInt();
briS = request->arg("CA").toInt();
saveCurrPresetCycConf = request->hasArg("PC");
turnOnAtBoot = request->hasArg("BO");
t = request->arg("BP").toInt();
if (t <= 25) bootPreset = t;
strip.gammaCorrectBri = request->hasArg("GB");
strip.gammaCorrectCol = request->hasArg("GC");
fadeTransition = request->hasArg("TF");
t = request->arg("TD").toInt();
if (t > 0) transitionDelay = t;
transitionDelayDefault = t;
strip.paletteFade = request->hasArg("PF");
nightlightTargetBri = request->arg("TB").toInt();
t = request->arg("TL").toInt();
if (t > 0) nightlightDelayMinsDefault = t;
nightlightDelayMins = nightlightDelayMinsDefault;
nightlightFade = request->hasArg("TW");
t = request->arg("PB").toInt();
if (t >= 0 && t < 4) strip.paletteBlend = t;
strip.reverseMode = request->hasArg("RV");
skipFirstLed = request->hasArg("SL");
t = request->arg("BF").toInt();
if (t > 0) briMultiplier = t;
}
//UI
if (subPage == 3)
{
strlcpy(serverDescription, request->arg("DS").c_str(), 33);
syncToggleReceive = request->hasArg("ST");
}
//SYNC
if (subPage == 4)
{
buttonEnabled = request->hasArg("BT");
irEnabled = request->arg("IR").toInt();
int t = request->arg("UP").toInt();
if (t > 0) udpPort = t;
receiveNotificationBrightness = request->hasArg("RB");
receiveNotificationColor = request->hasArg("RC");
receiveNotificationEffects = request->hasArg("RX");
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
notifyDirectDefault = request->hasArg("SD");
notifyDirect = notifyDirectDefault;
notifyButton = request->hasArg("SB");
notifyAlexa = request->hasArg("SA");
notifyHue = request->hasArg("SH");
notifyMacro = request->hasArg("SM");
notifyTwice = request->hasArg("S2");
receiveDirect = request->hasArg("RD");
e131SkipOutOfSequence = request->hasArg("ES");
e131Multicast = request->hasArg("EM");
t = request->arg("EP").toInt();
if (t > 0) e131Port = t;
t = request->arg("EU").toInt();
if (t >= 0 && t <= 63999) e131Universe = t;
t = request->arg("DA").toInt();
if (t >= 0 && t <= 510) DMXAddress = t;
t = request->arg("DM").toInt();
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_MULTIPLE_DRGB) DMXMode = t;
t = request->arg("ET").toInt();
if (t > 99 && t <= 65000) realtimeTimeoutMs = t;
arlsForceMaxBri = request->hasArg("FB");
arlsDisableGammaCorrection = request->hasArg("RG");
t = request->arg("WO").toInt();
if (t >= -255 && t <= 255) arlsOffset = t;
alexaEnabled = request->hasArg("AL");
strlcpy(alexaInvocationName, request->arg("AI").c_str(), 33);
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
strlcpy(blynkApiKey, request->arg("BK").c_str(), 36); initBlynk(blynkApiKey);
}
#ifdef WLED_ENABLE_MQTT
mqttEnabled = request->hasArg("MQ");
strlcpy(mqttServer, request->arg("MS").c_str(), 33);
t = request->arg("MQPORT").toInt();
if (t > 0) mqttPort = t;
strlcpy(mqttUser, request->arg("MQUSER").c_str(), 41);
if (!isAsterisksOnly(request->arg("MQPASS").c_str(), 41)) strlcpy(mqttPass, request->arg("MQPASS").c_str(), 41);
strlcpy(mqttClientID, request->arg("MQCID").c_str(), 41);
strlcpy(mqttDeviceTopic, request->arg("MD").c_str(), 33);
strlcpy(mqttGroupTopic, request->arg("MG").c_str(), 33);
#endif
#ifndef WLED_DISABLE_HUESYNC
for (int i=0;i<4;i++){
String a = "H"+String(i);
hueIP[i] = request->arg(a).toInt();
}
t = request->arg("HL").toInt();
if (t > 0) huePollLightId = t;
t = request->arg("HI").toInt();
if (t > 50) huePollIntervalMs = t;
hueApplyOnOff = request->hasArg("HO");
hueApplyBri = request->hasArg("HB");
hueApplyColor = request->hasArg("HC");
huePollingEnabled = request->hasArg("HP");
hueStoreAllowed = true;
reconnectHue();
#endif
}
//TIME
if (subPage == 5)
{
ntpEnabled = request->hasArg("NT");
strlcpy(ntpServerName, request->arg("NS").c_str(), 33);
useAMPM = !request->hasArg("CF");
currentTimezone = request->arg("TZ").toInt();
utcOffsetSecs = request->arg("UO").toInt();
//start ntp if not already connected
if (ntpEnabled && WLED_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
if (request->hasArg("OL")){
overlayDefault = request->arg("OL").toInt();
overlayCurrent = overlayDefault;
}
overlayMin = request->arg("O1").toInt();
overlayMax = request->arg("O2").toInt();
analogClock12pixel = request->arg("OM").toInt();
analogClock5MinuteMarks = request->hasArg("O5");
analogClockSecondsTrail = request->hasArg("OS");
strcpy(cronixieDisplay,request->arg("CX").c_str());
cronixieBacklight = request->hasArg("CB");
countdownMode = request->hasArg("CE");
countdownYear = request->arg("CY").toInt();
countdownMonth = request->arg("CI").toInt();
countdownDay = request->arg("CD").toInt();
countdownHour = request->arg("CH").toInt();
countdownMin = request->arg("CM").toInt();
countdownSec = request->arg("CS").toInt();
for (int i=1;i<17;i++)
{
String a = "M"+String(i);
if (request->hasArg(a.c_str())) saveMacro(i,request->arg(a),false);
}
macroBoot = request->arg("MB").toInt();
macroAlexaOn = request->arg("A0").toInt();
macroAlexaOff = request->arg("A1").toInt();
macroButton = request->arg("MP").toInt();
macroLongPress = request->arg("ML").toInt();
macroCountdown = request->arg("MC").toInt();
macroNl = request->arg("MN").toInt();
macroDoublePress = request->arg("MD").toInt();
char k[3]; k[2] = 0;
for (int i = 0; i<8; i++)
{
k[1] = i+48;//ascii 0,1,2,3
k[0] = 'H'; //timer hours
timerHours[i] = request->arg(k).toInt();
k[0] = 'N'; //minutes
timerMinutes[i] = request->arg(k).toInt();
k[0] = 'T'; //macros
timerMacro[i] = request->arg(k).toInt();
k[0] = 'W'; //weekdays
timerWeekday[i] = request->arg(k).toInt();
}
}
//SECURITY
if (subPage == 6)
{
if (request->hasArg("RS")) //complete factory reset
{
clearEEPROM();
serveMessage(request, 200, "All Settings erased.", "Connect to WLED-AP to setup again",255);
doReboot = true;
}
bool pwdCorrect = !otaLock; //always allow access if ota not locked
if (request->hasArg("OP"))
{
if (otaLock && strcmp(otaPass,request->arg("OP").c_str()) == 0)
{
pwdCorrect = true;
}
if (!otaLock && request->arg("OP").length() > 0)
{
strlcpy(otaPass,request->arg("OP").c_str(), 33);
}
}
if (pwdCorrect) //allow changes if correct pwd or no ota active
{
otaLock = request->hasArg("NO");
wifiLock = request->hasArg("OW");
aOtaEnabled = request->hasArg("AO");
}
}
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
if (subPage == 7)
{
int t = request->arg("CN").toInt();
if (t>0 && t<16) {
DMXChannels = t;
}
t = request->arg("CS").toInt();
if (t>0 && t<513) {
DMXStart = t;
}
t = request->arg("CG").toInt();
if (t>0 && t<513) {
DMXGap = t;
}
t = request->arg("SL").toInt();
if (t>=0 && t < MAX_LEDS) {
DMXStartLED = t;
}
for (int i=0; i<15; i++) {
String argname = "CH" + String((i+1));
t = request->arg(argname).toInt();
DMXFixtureMap[i] = t;
}
}
#endif
if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
if (subPage == 2) {
strip.init(useRGBW,ledCount,skipFirstLed);
}
if (subPage == 4) alexaInit();
}
//helper to get int value at a position in string
int getNumVal(const String* req, uint16_t pos)
{
return req->substring(pos+3).toInt();
}
//helper to get int value at a position in string
bool updateVal(const String* req, const char* key, byte* val, byte minv, byte maxv)
{
int pos = req->indexOf(key);
if (pos < 1) return false;
if (req->charAt(pos+3) == '~') {
int out = getNumVal(req, pos+1);
if (out == 0)
{
if (req->charAt(pos+4) == '-')
{
*val = (*val <= minv)? maxv : *val -1;
} else {
*val = (*val >= maxv)? minv : *val +1;
}
} else {
out += *val;
if (out > maxv) out = maxv;
if (out < minv) out = minv;
*val = out;
}
} else
{
*val = getNumVal(req, pos);
}
return true;
}
//HTTP API request parser
bool handleSet(AsyncWebServerRequest *request, const String& req)
{
if (!(req.indexOf("win") >= 0)) return false;
int pos = 0;
DEBUG_PRINT("API req: ");
DEBUG_PRINTLN(req);
//write presets and macros saved to flash directly?
bool persistSaves = true;
pos = req.indexOf("NP");
if (pos > 0) {
persistSaves = false;
}
//save macro, requires &MS=<slot>(<macro>) format
pos = req.indexOf("&MS=");
if (pos > 0) {
int i = req.substring(pos + 4).toInt();
pos = req.indexOf('(') +1;
if (pos > 0) {
int en = req.indexOf(')');
String mc = req.substring(pos);
if (en > 0) mc = req.substring(pos, en);
saveMacro(i, mc, persistSaves);
}
pos = req.indexOf("IN");
if (pos < 1) XML_response(request);
return true;
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
}
strip.applyToAllSelected = true;
//segment select (sets main segment)
byte prevMain = strip.getMainSegmentId();
pos = req.indexOf("SM=");
if (pos > 0) {
strip.mainSegment = getNumVal(&req, pos);
}
byte main = strip.getMainSegmentId();
if (main != prevMain) setValuesFromMainSeg();
pos = req.indexOf("SS=");
if (pos > 0) {
byte t = getNumVal(&req, pos);
if (t < strip.getMaxSegments()) main = t;
}
WS2812FX::Segment& mainseg = strip.getSegment(main);
pos = req.indexOf("SV="); //segment selected
if (pos > 0) mainseg.setOption(SEG_OPTION_SELECTED, (req.charAt(pos+3) != '0'));
uint16_t startI = mainseg.start;
uint16_t stopI = mainseg.stop;
uint8_t grpI = mainseg.grouping;
uint16_t spcI = mainseg.spacing;
pos = req.indexOf("&S="); //segment start
if (pos > 0) {
startI = getNumVal(&req, pos);
}
pos = req.indexOf("S2="); //segment stop
if (pos > 0) {
stopI = getNumVal(&req, pos);
}
pos = req.indexOf("GP="); //segment grouping
if (pos > 0) {
grpI = getNumVal(&req, pos);
if (grpI == 0) grpI = 1;
}
pos = req.indexOf("SP="); //segment spacing
if (pos > 0) {
spcI = getNumVal(&req, pos);
}
strip.setSegment(main, startI, stopI, grpI, spcI);
main = strip.getMainSegmentId();
//set presets
pos = req.indexOf("P1="); //sets first preset for cycle
if (pos > 0) presetCycleMin = getNumVal(&req, pos);
pos = req.indexOf("P2="); //sets last preset for cycle
if (pos > 0) presetCycleMax = getNumVal(&req, pos);
//preset cycle
pos = req.indexOf("CY=");
if (pos > 0)
{
presetCyclingEnabled = (req.charAt(pos+3) != '0');
presetCycCurr = presetCycleMin;
}
pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) {
int v = getNumVal(&req, pos);
if (v > 49) presetCycleTime = v;
}
pos = req.indexOf("PA="); //apply brightness from preset
if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0');
pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) savePreset(getNumVal(&req, pos), persistSaves);
//apply preset
if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) {
applyPreset(presetCycCurr, presetApplyBri);
}
//set brightness
updateVal(&req, "&A=", &bri);
//set colors
updateVal(&req, "&R=", &col[0]);
updateVal(&req, "&G=", &col[1]);
updateVal(&req, "&B=", &col[2]);
updateVal(&req, "&W=", &col[3]);
updateVal(&req, "R2=", &colSec[0]);
updateVal(&req, "G2=", &colSec[1]);
updateVal(&req, "B2=", &colSec[2]);
updateVal(&req, "W2=", &colSec[3]);
//set hue
pos = req.indexOf("HU=");
if (pos > 0) {
uint16_t temphue = getNumVal(&req, pos);
byte tempsat = 255;
pos = req.indexOf("SA=");
if (pos > 0) {
tempsat = getNumVal(&req, pos);
}
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
}
//set color from HEX or 32bit DEC
pos = req.indexOf("CL=");
if (pos > 0) {
colorFromDecOrHexString(col, (char*)req.substring(pos + 3).c_str());
}
pos = req.indexOf("C2=");
if (pos > 0) {
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
}
pos = req.indexOf("C3=");
if (pos > 0) {
byte t[4];
colorFromDecOrHexString(t, (char*)req.substring(pos + 3).c_str());
strip.setColor(2, t[0], t[1], t[2], t[3]);
}
//set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR");
if (pos > 0) {
_setRandomColor(getNumVal(&req, pos));
}
//swap 2nd & 1st
pos = req.indexOf("SC");
if (pos > 0) {
byte temp;
for (uint8_t i=0; i<4; i++)
{
temp = col[i];
col[i] = colSec[i];
colSec[i] = temp;
}
}
//set effect parameters
if (updateVal(&req, "FX=", &effectCurrent, 0, strip.getModeCount()-1)) presetCyclingEnabled = false;
updateVal(&req, "SX=", &effectSpeed);
updateVal(&req, "IX=", &effectIntensity);
updateVal(&req, "FP=", &effectPalette, 0, strip.getPaletteCount()-1);
//set advanced overlay
pos = req.indexOf("OL=");
if (pos > 0) {
overlayCurrent = getNumVal(&req, pos);
}
//apply macro
pos = req.indexOf("&M=");
if (pos > 0) {
applyMacro(getNumVal(&req, pos));
}
//toggle send UDP direct notifications
pos = req.indexOf("SN=");
if (pos > 0) notifyDirect = (req.charAt(pos+3) != '0');
//toggle receive UDP direct notifications
pos = req.indexOf("RN=");
if (pos > 0) receiveNotifications = (req.charAt(pos+3) != '0');
//receive live data via UDP/Hyperion
pos = req.indexOf("RD=");
if (pos > 0) receiveDirect = (req.charAt(pos+3) != '0');
//toggle nightlight mode
bool aNlDef = false;
if (req.indexOf("&ND") > 0) aNlDef = true;
pos = req.indexOf("NL=");
if (pos > 0)
{
if (req.charAt(pos+3) == '0')
{
nightlightActive = false;
bri = briT;
} else {
nightlightActive = true;
if (!aNlDef) nightlightDelayMins = getNumVal(&req, pos);
nightlightStartTime = millis();
}
} else if (aNlDef)
{
nightlightActive = true;
nightlightStartTime = millis();
}
//set nightlight target brightness
pos = req.indexOf("NT=");
if (pos > 0) {
nightlightTargetBri = getNumVal(&req, pos);
nightlightActiveOld = false; //re-init
}
//toggle nightlight fade
pos = req.indexOf("NF=");
if (pos > 0)
{
nightlightFade = (req.charAt(pos+3) != '0');
nightlightColorFade = (req.charAt(pos+3) == '2'); //NighLightColorFade can only be enabled via API or Macro with "NF=2"
nightlightActiveOld = false; //re-init
}
#if AUXPIN >= 0
//toggle general purpose output
pos = req.indexOf("AX=");
if (pos > 0) {
auxTime = getNumVal(&req, pos);
auxActive = true;
if (auxTime == 0) auxActive = false;
}
#endif
pos = req.indexOf("TT=");
if (pos > 0) transitionDelay = getNumVal(&req, pos);
//main toggle on/off
pos = req.indexOf("&T=");
if (pos > 0) {
nightlightActive = false; //always disable nightlight when toggling
switch (getNumVal(&req, pos))
{
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
case 1: bri = briLast; break; //on
default: toggleOnOff(); //toggle
}
}
//Segment reverse
pos = req.indexOf("RV=");
if (pos > 0) strip.getSegment(main).setOption(SEG_OPTION_REVERSED, req.charAt(pos+3) != '0');
//Segment brightness/opacity
pos = req.indexOf("SB=");
if (pos > 0) {
byte segbri = getNumVal(&req, pos);
strip.getSegment(main).setOption(SEG_OPTION_ON, segbri);
if (segbri) {
strip.getSegment(main).opacity = segbri;
}
}
//deactivate nightlight if target brightness is reached
if (bri == nightlightTargetBri) nightlightActive = false;
//set time (unix timestamp)
pos = req.indexOf("ST=");
if (pos > 0) {
setTime(getNumVal(&req, pos));
}
//set countdown goal (unix timestamp)
pos = req.indexOf("CT=");
if (pos > 0) {
countdownTime = getNumVal(&req, pos);
if (countdownTime - now() > 0) countdownOverTriggered = false;
}
pos = req.indexOf("RB");
if (pos > 0) doReboot = true;
//cronixie
#ifndef WLED_DISABLE_CRONIXIE
//mode, 1 countdown
pos = req.indexOf("NM=");
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
pos = req.indexOf("NX="); //sets digits to code
if (pos > 0) {
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
setCronixie();
}
pos = req.indexOf("NB=");
if (pos > 0) //sets backlight
{
cronixieBacklight = (req.charAt(pos+3) != '0');
overlayRefreshedTime = 0;
}
#endif
pos = req.indexOf("U0="); //user var 0
if (pos > 0) {
userVar0 = getNumVal(&req, pos);
}
pos = req.indexOf("U1="); //user var 1
if (pos > 0) {
userVar1 = getNumVal(&req, pos);
}
//you can add more if you need
//internal call, does not send XML response
pos = req.indexOf("IN");
if (pos < 1) XML_response(request);
pos = req.indexOf("&NN"); //do not send UDP notifications this time
colorUpdated((pos > 0) ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
return true;
}

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