diff --git a/search/search_index.json b/search/search_index.json index 021afe73d..856ea23b1 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to WLED MoonModules & Sound Reactive","text":""},{"location":"#welcome-to-wled-moonmodules","title":"Welcome to WLED MoonModules","text":"

MoonModules/WLED is a fork from Aircoookie/WLED which contains latest merge of v0.14 of WLED with additional features.

This fork is created by members of the Atuline/WLED team to make development against v0.14 possible while still preserving Atuline/WLED v0.13 as a stable and supported version. The Atuline/WLED fork is also called WLED SR (Sound Reactive).

More info here.

"},{"location":"#good-to-know","title":"Good to know","text":"

Disclaimer: using this software is the users responsibility as it is not bug free. Therefore contributors of this repo are not reliable for anything including but not limited to spontaneous combustion of the entire led strip, the house and the inevitable heat death of the universe

Join the Discord server to discuss everything about WLED MM and SR!

WLED Aircoookie welcome \ud83d\udc47

"},{"location":"#welcome-to-my-project-wled","title":"Welcome to my project WLED! \u2728","text":"

A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!

"},{"location":"#features","title":"\u2699\ufe0f Features","text":""},{"location":"#supported-light-control-interfaces","title":"\ud83d\udca1 Supported light control interfaces","text":""},{"location":"#quick-start-guide-and-documentation","title":"\ud83d\udcf2 Quick start guide and documentation","text":"

See the getting started page!

On this page you can find excellent tutorials made by the community and helpful tools to help you get your new lamp up and running!

"},{"location":"#user-interface","title":"\ud83d\uddbc\ufe0f User interface","text":""},{"location":"#compatible-hardware","title":"\ud83d\udcbe Compatible hardware","text":"

See here!

"},{"location":"#other","title":"\u270c\ufe0f Other","text":"

Licensed under the MIT license Credits here!

Join the Discord server to discuss everything about WLED!

Check out the WLED Discourse forum! You can also send me mails to 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

Disclaimer

If you are sensitive to photosensitive epilepsy 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.

"},{"location":"2D/HUB75/","title":"HUB75 support","text":"

WLED-MM now features support for LED matrix panels using the HUB75 format

You can use either a regular ESP32 with a suitable adapter board such as ESP32 Trinity or rorosaurus/esp32-hub75-driver or the dedicated Adafruit Matrix Portal S3

This support is supplied by the ESP32-HUB75-MatrixPanel-DMA library, so see here for more details about supported hardware

Support for HUB75 in WLED-MM should be considered experimental at the moment, but we welcome early feedback on this new feature - please share your experience in the 2D channel

"},{"location":"2D/HUB75/#setup","title":"Setup","text":""},{"location":"2D/HUB75/#required-software-build","title":"Required Software Build","text":""},{"location":"2D/HUB75/#adafruit-matrix-portal-s3","title":"Adafruit Matrix Portal S3","text":"

Please use the dedicated adafruit_matrixportal_esp32s3 build as this is pre-configured for the pins needed for HUB75 output

"},{"location":"2D/HUB75/#huidu-hd-wf2-esp32-s3","title":"Huidu HD-WF2 ESP32-S3","text":""},{"location":"2D/HUB75/#generic-esp32-support","title":"Generic ESP32 support","text":"

You must use a build with WLED_ENABLE_HUB75MATRIX defined, for example, esp32_4MB_V4_S. If you do not see Hub75 options in the list of LED types, you are not using the correct build

If you are using a board such as the ESP32 Trinity or other boards wired for the default pinout of the ESP32-HUB75-MatrixPanel-DMA driver, this is selected by default

If you are using the rorosaurus/esp32-hub75-driver or any other board using the SmartMatrix default pinout then you will need to do a custom build with ESP32_FORUM_PINOUT defined

If you are using any other config, you currently need to edit wled00/bus_manager.cpp to add a new elif block and define to your build - it is not possible to set the HUB75 pin config in LED preferences at the moment

"},{"location":"2D/HUB75/#configuration","title":"Configuration","text":""},{"location":"2D/HUB75/#panel-size-and-chain-length","title":"Panel size and chain length","text":""},{"location":"2D/HUB75/#setup_1","title":"Setup","text":"

First, you must set the LED output to match the correct Hub75Matrix option for the panel size you are using. The chain length is the number of panels connected. Note: currently only a horizontal chain of panels is supported. You can used 2D setup to configure physical panel positions.

Next, you need to go into the 2D Configuration and create a single matrix with the total size of your hub75 setup. e.g a chain of 2 panels with 32x32 pixels each, would be created as a 64x32 matrix in the 2D configuration page

"},{"location":"2D/HUB75/#hub75-known-problems-and-limitations","title":"HUB75 Known Problems and Limitations","text":""},{"location":"2D/wip/","title":"Work in Progress","text":"

This page is a work in progress

Check WLEDSR - 2D Support for original content

"},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/","title":"(temporary) WLEDSR improvements and bugfixes from 0.13.2 to 0.13.3","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#user-interface-and-generic-features","title":"User Interface and generic features","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#audio-processing","title":"Audio Processing","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#udp-sound-sync","title":"UDP sound sync","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#effects","title":"Effects","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#arti-fx-2d3d-live-preview","title":"ARTI-FX, 2D/3D, live preview","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#misc-bugfixes-and-fixes-from-upstream-wled-0140","title":"misc. bugfixes, and fixes from upstream WLED 0.14.0","text":""},{"location":"WLEDSR/%28temporary%29-WLEDSR-improvements-and-bugfixes-from-0.13.2-to-0.13.3/#changes-from-upstream-v0133","title":"Changes from upstream v0.13.3","text":""},{"location":"WLEDSR/2D-Functionality/","title":"2D Functionality","text":""},{"location":"WLEDSR/2D-Functionality/#2d-functionality","title":"2D functionality","text":"

As documented in FastLED, leds[0] should end up being at the top left of your array:

Don't enable serpentine setting if your pixels are\nlaid out all running the same way, like this:\n\n    0 >  1 >  2 >  3 >  4\n                        |\n    .----<----<----<----'\n    |\n    5 >  6 >  7 >  8 >  9\n                        |\n    .----<----<----<----'\n    |\n   10 > 11 > 12 > 13 > 14\n                        |\n    .----<----<----<----'\n    |\n   15 > 16 > 17 > 18 > 19\n\nEnable serpentine setting if your pixels are\nlaid out back-and-forth, like this:\n\n    0 >  1 >  2 >  3 >  4\n                        |\n                        |\n    9 <  8 <  7 <  6 <  5\n    |\n    |\n   10 > 11 > 12 > 13 > 14\n                       |\n                       |\n   19 < 18 < 17 < 16 < 15\n
"},{"location":"WLEDSR/2D-Functionality/#xy-routine-update","title":"XY() routine update","text":"

The dev branch has a new XY() function (thanks Sutaburosu) in FX.cpp, which supports multiple layouts.

There are 5 orientation flags as follows:

By comparison, the author's aliexpress purchased 16x16 array needs to be configured as:

Serpentine | Rowmajor | Flipmajor\n

Note: When an X,Y value goes out of bounds, this routine writes to an LED beyond SEGLEN, and as a result, we need to use the setPixels() routine to write to the display.

Note: Working with this can be confusing, so here's a simulator you can play around with to get familiar with XY() at Wokwi.

"},{"location":"WLEDSR/2D-Functionality/#multiple-panels-202106dev","title":"Multiple panels (202106/dev)","text":"

When you want to create larger matrices, the standard available panels are not big enough. They typically are 16x16 or 8x32 pixels. To support large matrices, they should be connected together. This is now supported in WLED SR (currently in dev version). Multiple panels can be specified in the LED-Preferences screen by checking Multiple Panels and then defining the number of horizontal and vertical panels. First panel should be top left, extending to the right, the extending down, until bottom right.

For example if you create a 32x32 matrix by connecting 4 8x32 panels together you have 4 horizontal panels and 1 vertical panel. Alternatively if you have 4 16x16 panels, you have 2 horizontal and 2 vertical panels. In the latter case, panel ordering is:

0 1

2 3

The XY() function supports this by first determining in which panel an (x,y) coordinate should be displayed and then within a panel it's position is determined as described above (using flipmajor, serpentine etc.).

In the 8x32 example above, 0<x<8 is displayed in the first panel, 8<x<16 in the second panel and so on. For each panel, the first led number is calculated. E.g. if each panel has 256 leds then the second panel first led is led[256]. The values of x and y are then corrected by the width and the height of the panel to find the place within the panel (major and minor values)

"},{"location":"WLEDSR/2D-Support/","title":"2D Support","text":""},{"location":"WLEDSR/2D-Support/#introduction","title":"Introduction","text":"

In order to accommodate 2D effects we have modified how Segment settings are used and added 2D Matrix and panel variables on the Led Preferences settings. Note: Currently only working in dev. You are invited to test this and give feedback on Beta testing discord channel

"},{"location":"WLEDSR/2D-Support/#2d-architecture","title":"2D architecture","text":"

WLED SR distinguishes between the following levels * 2D Segment (dev) * 2D Matrix (dev) * 2D Panel (dev)

An effect is plotted on a segment. A segment is a rectangle on a matrix (logical level). A matrix is implemented by one or more identical led panels, with a specific layout (e.g. first led bottom left, serpentine, physical level).

Note: 2D effects can also be projected on a 1D LED Strip instead of a 2D Panel. e.g. for a led strip of 144 leds you can define width=height=12 and each zone of 12 leds is a row of a matrix. Rows are then side by side instead of above each other. Some 2D effects, e.g. graphic equalizer look still pretty cool on strips (as is the other way around with 1D effects on a 2D matrix like NoiseMove or Sparkle).

"},{"location":"WLEDSR/2D-Support/#2d-segments","title":"2D Segments","text":"

As WLED supports multiple segments, all effects and therefore also 2D effects are first projected on a segment. In 1D, a segment is a zone on a LED strip and is specified by Start Led and a Stop Led (note that Stop Led is one led after the last led in the segment).

In 2D, a segment is a rectangle on a 2D matrix and 2D effects plot on this rectangle using x,y coordinates of the SEGMENT. A rectangle can be defined in the Segment UI where the start led specifies the top-left and the stop led specifies the bottom-right of the rectangle. Multiple segments can be specified this way. Segments can overlap. In fact overlapping creates very nice effects.

See Segment start stop charts to easy find matrix start and stop values

"},{"location":"WLEDSR/2D-Support/#rotation-and-reversexy","title":"Rotation and ReverseX/Y","text":"

A segment can be rotated 90\u00ba degrees and reversed on the X or Y-axis and can be specified in the Segment-UI. The SegmentRotation branch of dev supports this and is currently in beta-test. This will move to dev and release over time.

The following table shows the effect setting these values:

Value Rotation Reverse X Reverse Y Effect 0 - - - 0\u00ba rotation and no reverse 1 - - + Reverse horizontal 2 - + - Reverse vertical 3 - + + 180\u00ba rotation 4 + - - 90\u00ba rotation 5 + - + 90\u00ba and reverse horizontal 6 + + - 90\u00ba and vertical 7 + + + 270\u00ba rotation"},{"location":"WLEDSR/2D-Support/#2d-matrices-and-panels","title":"2D Matrices and panels","text":"

See Led Preferences

"},{"location":"WLEDSR/2D-Support/#technical","title":"Technical","text":""},{"location":"WLEDSR/2D-Support/#2d-segment-start-stop-charts","title":"2D Segment start stop charts","text":""},{"location":"WLEDSR/2D-Support/#16x16-matrix","title":"16x16 matrix","text":""},{"location":"WLEDSR/2D-Support/#32x32-matrix","title":"32x32 matrix","text":"

(Created by Harry Baas)

"},{"location":"WLEDSR/2D-Support/#examples","title":"Examples","text":""},{"location":"WLEDSR/2D-Support/#16x16-matrix_1","title":"16x16 matrix","text":"

To get the (x,y) coordinates from the start and stop led: * Segment top left = (start%matrixWidth, start/matrixWidth) * Segment bottom right = (stop%matrixWidth, stop/matrixWidth)

Example of 1 segment (default) covering a whole 16x16 matrix: * start = 0, stop = 255 * top left = (0,0) * bottom right = (15,15) * width = height = 16

Example of a segment covering a middle part rectangle of the 16x16 matrix: * start = 20, stop = 235 * top left = (4,1) * bottom right = (10,14) * width = 7 * height = 14

Example of a segment covering the left part of the 16x16 matrix: * start = 0, stop = 241 * top left = (0,0) * bottom right = (0,15) * width = 1 * height = 16

"},{"location":"WLEDSR/2D-Support/#16-x-12-matrix","title":"16 x 12 matrix","text":"

matrixWidth = 16, matrixHeight = 12.

Total led count 192 leds

left and right binmap effect. In the middle noisemove.

"},{"location":"WLEDSR/2D-Support/#api-commands-for-2d-effects","title":"Api commands for 2D effects","text":""},{"location":"WLEDSR/2D-Support/#16-segments-for-32x32-matrices","title":"16 segments for 32x32 matrices","text":"

Add the following Api command into a preset. This will show the Saw effect rotated and reversed in 16 8*8 segments.

After that you, if you select all 16 segments and select another effect, this effect will also be populated to all 16 segments, resulting in surprising new effects

{\"on\":true,\"bri\":89,\"transition\":7,\"mainseg\":0,\"seg\":[{\"id\":0,\"start\":0,\"stop\":232,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":1,\"start\":8,\"stop\":240,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":2,\"start\":16,\"stop\":248,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":3,\"start\":24,\"stop\":256,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":4,\"start\":256,\"stop\":488,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":5,\"start\":264,\"stop\":496,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":6,\"start\":272,\"stop\":504,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":7,\"start\":280,\"stop\":512,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":8,\"start\":512,\"stop\":744,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":9,\"start\":520,\"stop\":752,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":10,\"start\":528,\"stop\":760,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":11,\"start\":536,\"stop\":768,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":false,\"mi\":false,\"rot2D\":false},{\"id\":12,\"start\":768,\"stop\":1000,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":13,\"start\":776,\"stop\":1008,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":14,\"start\":784,\"stop\":1016,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":false,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"id\":15,\"start\":792,\"stop\":1024,\"grp\":1,\"spc\":0,\"on\":true,\"bri\":255,\"col\":[[255,0,0],[59,42,27],[0,0,255]],\"fx\":16,\"sx\":47,\"ix\":142,\"f1x\":89,\"f2x\":74,\"f3x\":111,\"pal\":12,\"sel\":true,\"rev\":true,\"rev2D\":true,\"mi\":false,\"rot2D\":false},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0},{\"stop\":0}]}

"},{"location":"WLEDSR/A-question-on-leds%5Bi%5D-in-FastLED/","title":"A question on leds[i] in FastLED","text":"

In order to be able to use leds[i] in WLED, we add the following global variable:

uint32_t ledData[MAX_LEDS];                 // See const.h for a value of 1500.\n

In many routines, we are adding the following code so that we don't have lossy data when copying led information from one element to the next:

  CRGB *leds = (CRGB*) ledData;\n\n  // leds[i] code in here\n\n  setPixels(leds);\n  return FRAMETIME;\n

This works with SEGMENTS in that two different animations don't clash. The questions I have are:

If the latter, would that not be very inefficient, and if inefficient, would it not make more sense to use:

 if (!SEGENV.allocateData(sizeof(CRGB)*SEGLEN)) return mode_static(); //Allocates based on the size of a CRGB\n  CRGB* leds = reinterpret_cast<CRGB*>(SEGENV.data);\n\n  // leds[i] code in here\n\n  setPixels(leds);\n  return FRAMETIME;\n

That being said, an associate with embedded system support says that dynamic memory allocation is NOT a good thing to perform on embedded systems.

Thoughts?

In the meantime, and I quote: \"When allocating memory the danger is always that that memory isn't deallocated properly, and thus leaks memory. Running out of RAM happens very fast on embedded devices that's why it's discouraged.\"

"},{"location":"WLEDSR/Adding-Sliders/","title":"Sliders in WLED","text":""},{"location":"WLEDSR/Adding-Sliders/#introduction","title":"Introduction","text":"

This page provides WLED programmers information on adding another slider to WLED. This information is not yet complete, as it doesn't yet deal with icons, EEPROM or IR. I will also be researching how to programmatically show/hide these sliders.

"},{"location":"WLEDSR/Adding-Sliders/#updating-html_uih","title":"Updating html_ui.h","text":"

Please see https://mm.kno.wled.ge/WLEDSR/Modifying-Sound-Reactive-WLED on how to generate html_ui.h since the UI was changed in v0.10.0-alpha-lw.

The information below describes the way html_ui.h was generated before the UI change and is deprecated.

This file is compressed and is taken from data\\index.htm. Please see Aircoookie's page on 'adding your own effect:

https://github.com/Aircoookie/WLED/wiki/Add-own-functionality

To serve your changes by the internal webserver, you will need to follow these or similar steps to gzip compress the index.html file:

  1. Gzip compress the file. I use this online converter, use setting Compress this file, output \u2013 gz
  2. Rename file to xxx.gz.png (change file type to image)
  3. Convert it to a C-style byte/char array. I use this converter, intended for image sprites. Therefore, the previous step of changing the file format was neccessary. Select Raw as Color format.
  4. Open the downloaded .c file in a text editor, e. g. Notepad++. Select the contents of the array and replace the array contents in html_ui.h with them.
  5. Update PAGE_index_L to the binary size stated in the bottom of the downloaded .c file Recompile and flash WLED!

Here's a link to my Google document containing the changes required:

https://docs.google.com/document/d/1m6dm3O_aXgJLGDJfM6E-4CHzzvU8bsaHqrs7VmisYko/edit

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/","title":"Adding a new Settings Page","text":""},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#introduction","title":"Introduction","text":"

This page outlines the methods we used and the files that must be modified to add a Sound Settings page to the WLED UI.

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#new-settings_soundhtm","title":"NEW settings_sound.htm","text":"

I first added a new file in the data folder named settings_sound.htm. I did a copy/paste from settings_leds.htm to have a base for the new settings page. Let's break down this file. * At the top, we have our standard HTML beginning lines with the TITLE of the page between the <title> tags. * Inside of the <script> tags we have a few functions that are necessary for the page to function. * function H() is our help button function. When called, the UI will direct you to the relevant wiki page inside the window.open() function. * function B() is our back button function. When called, the UI will direct you to the previous main settings page via window.open(\"/settings\",\"_self\"). * function GetV() injects the values from the relevant settings stored in EEPROM to the settings page. * Inside the <style> tag we @import the relevant style.css file. This closes our <head> tag. * When the body of the page is loaded, function GetV() is called. This can vary depending on the functions that need to be called when the page loads. * Inside the <body> tag we have our form. This form holds the layout for the settings page. * Our squelch and gain settings have the names \"SQ\" and \"GN\" respectively. These names refer to the name given to the setting in xml.cpp and are used to retrieve and save these settings from/to EEPROM.

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#modify-settingshtm","title":"Modify settings.htm","text":"

This file holds the settings page button layout. We want to add an entry so we can access our new settings page. This was pretty straight forward. I added the following line, in the position I wanted it to appear on the page, using the previous entries as an example.

<form action=\"/settings/sound\"><button type=\"submit\">Sound Settings</button></form>\n
I also made some changes to the style of the buttons so they all show on the same page. This was not necessary but I feel it gave a more polished look.

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#modify-xmlcpp","title":"Modify xml.cpp","text":"

This is our map, so to speak. Each setting is given a unique 2 character string that will be used to reference it in the UI. In our case, \"SQ\" and \"GN\". This file is also the map for the XML response when querying the API. Our settings aren't used in the API at this time so I won't go into that right now.

There are two important functions in xml.cpp that relates to our task which are void sappend() and void sappends() * sappend() takes a numeric setting and appends it to the string buffer. Valid cases for this function are: * 'c', a check box * 'v', a numeric value * 'i', the selected index * sappends() takes a string setting and appends it to the string buffer. Valid cases for this function are: * 's', a string setting * 'm', a message to be displayed

Around line 192 in xml.cpp we have the function getSettingsJS() which retrieves the settings values from EEPROM based on the current sub-page which is defined in wled_server.cpp.

We want to add a sub-page so we need to change the following line from if (subPage <1 || subPage >7) to if (subPage <1 || subPage >8). At the end of this function, after the last sub-page (previously 7) we have the following code block around line 522:

if (subPage == 8)\n{\n  sappend('v',\"SQ\",soundSquelch);\n  sappend('v',\"GN\",sampleGain);\n  }\n
Here we can see our SQ and GN settings are loaded from EEPROM and filled in to their respective form field using the v case from the sappend() function.

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#modify-setcpp","title":"Modify set.cpp","text":"

This file handles storing the settings entered into EEPROM. Similar to xml.cpp, we want to add a settings page so we need to tell WLED there is an additional page in the handleSettingsSet() function. I changed the following line from if (subPage <1 || subPage >7) return; to if (subPage <1 || subPage >8) return;.

Lastly, I added the following code block after the last defined sub-page around line 361:

//SOUND SETTINGS\nif (subPage == 8)\n{\n  int t;\n  t = request->arg(\"SQ\").toInt();\n  if (t > 0) soundSquelch = t;\n  t = request->arg(\"GN\").toInt();\n  if (t > 0) sampleGain = t;\n}\n

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#modify-wled_servercpp","title":"Modify wled_server.cpp","text":"

This file serves the webpage for the WLED frontend. We want to add a settings page so we will add the following block of code around line 82, using the previous block as an example. Notice the sub-page defined in xml.cpp is referenced as well as the NEW setting page URL defined in settings.htm.

// add sound settings page\nserver.on(\"/settings/sound\", HTTP_POST, [](AsyncWebServerRequest *request){\n  handleSettingsSet(request, 8);\n  serveMessage(request, 200,F(\"Sound settings saved.\"),\"Redirecting...\",1);\n});\n
In the serveSettings() function around line 383 we need to add else if (url.indexOf(\"sound\")> 0) subPage = 8; // add sound settings page, so the webserver knows to load those settings.

And finally we need to add a case around line 406 for our new sub-page like this case 8: request->send_P(200, \"text/html\", PAGE_settings_sound, settingsProcessor); break;.

"},{"location":"WLEDSR/Adding-a-Sound-Settings-page-to-the-UI/#modify-cdatajs","title":"Modify cdata.js","text":"

Finally, we need to add our new settings page to cdata.js in the tools folder. This file holds the framework for modifying the compressed *.h files that serve the WLED frontend. This is the file nodejs looks to when running npm run build to compress the *.htm files in the data folder into *.h files which are compiled with the firmware.

I used the previous entries as an example and added the following code block around line 243:

{\n  file: \"settings_sound.htm\",\n  name: \"PAGE_settings_sound\",\n  prepend: \"=====(\",\n  append: \")=====\",\n  method: \"plaintext\",\n  filter: \"html-minify\",\n  mangle: (str) =>\n    str\n      .replace(/\\<link rel=\"stylesheet\".*\\>/gms, \"\")\n      .replace(/\\<style\\>.*\\<\\/style\\>/gms, \"%CSS%%SCSS%\")\n      .replace(\n        /function GetV().*\\<\\/script\\>/gms,\n        \"function GetV() {var d=document;\\n\"\n      ),\n},\n

Those are the steps I took to modify the WLED settings pages and add a page for the sound reactive related settings in the UI. Once those were completed, I ran npm install and npm run build to compress the new UI and include it in the firmware. After compiling the new firmware, I needed to reset the EEPROM via http://WLED/settings/sec? -> Factory reset.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/","title":"Analog Audio Input Options","text":""},{"location":"WLEDSR/Analog-Audio-Input-Options/#microphone-input","title":"Microphone Input","text":"

Generally we recommend using I2S digital sound input - like INMP441, SPH0645, ICS-43434, or PDM I2S microphones. Additionally there are solutions for line-in via I2S. For example, boards/shields with \"es7243\" chip should work already (we have a special driver for these), and we're investigating \"es8388\".

Below are a number of popular Arduino compatible analog microphones that have been tested.

Model Compatibility Notes MAX9814 Good+ Best to set the gain to 40dB. MAX9812 Fair Only 20dB gain, but worked OK. MAX4466 bad Is very sensitive to 3.3V noise and voltage dropout due to Wifi activity. Avoid powering your LED strip from ESP32, as the strip causes a lot of noise on the 3.3V/5V power lines. INMP401 Good Some Chinese ones are not reliable. Clap Sensors (LM393, KY-038, KY-037) unusable these sensors may have an \"analogue output\" but the signal quality is extremely poor. Don't use them as a microphone, they were designed for other purposes.

See also

\u21d2 Sound setting examples for common microphones

\u21d2 noise and spikes on analog microphones

If you are using the MAX9814, you need to connect gain to vdd to set the gain to 40dB as the default 60db has far too much background noise.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#dont-waste-your-money-on-cheapest-hardware","title":"Don't waste your money on cheapest hardware","text":"

Important: there are some inexpensive sound sensors you can buy from Aliexpress or elsewhere (such as LM393, KY-038 or KY-037). Typically these have an on/off output only (detecting \"sound\" or \"silence\"), sometimes there is an additional \"analog data out\" with very low quality. They may or may not work adequately. For more information on our microphone test results, see our Arduino Compatible Microphones document.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#use-squelch","title":"Use Squelch","text":"

If the LED's are active when the ambient volume is low while running volume only effects beginning with a single '*', you can increase the background noise filtering (or squelch) by navigating to the 'Config | Sound Settings' and increase the Squelch value. You can also make it more sensitive by lowering that Squelch value. In addition, there is a gain setting, which is required especially for the much lower signal level provided by the line-in configuration. Gain, Squelch and AGC are affecting all soundreactive, volumereactive and frequency (FFT) reactive effects.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#good-to-know","title":"good to know","text":"

Note 1: Do NOT connect input devices to 5V (or Vin). The power should be connected to the 3.3V pin.

Note 2: A piezo vibration sensor (from aliexpress) was successfully hooked up and tested. This piezo hack is not possible any more, as piezo impulses would be filtered out as random noise.

Note 3: On the ESP32, the default ADC pin is GPI36 (also known as VP), while the ESP8266 uses A0. On ESP32, any GPIO related to ADC1 can be used - see next note.

Note 4: If your ESP32 doesn't have pin 36, any of the other ADC1 (and not ADC2) pins should work.

Note 5: On the ESP32, the ADC and I2S pins are defined in audio_reactive.h. You can also select them in the sound settings UI.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#wiring","title":"Wiring","text":""},{"location":"WLEDSR/Analog-Audio-Input-Options/#the-following-schematics-are-provided-as-an-example-only-there-are-many-ways-to-achieve-the-same-results-these-are-only-a-few-of-those-ways","title":"The following schematics are provided as an example only. There are many ways to achieve the same results. These are only a few of those ways.","text":"Microphone Wiring Example (MAX9814) Line In Wiring Example

Some folks have mentioned that they don't need this line-in circuit, which is fine. Here's an explanation of that circuit.

The 680 ohm resistors provide termination so that you don't get reflection on the incoming signals. The 100nf capacitors remove any DC offset from the incoming signal. Remember that the ESP goes from 0V to 3.3V. Beyond that lay dragons. Finally, the 1M resistors provide DC centering of the incoming (now) AC only signal halfway between 0 and 3.3V.

Note 1: If you are just using a single L or R channel for the line-in, disconnect the capacitor for the other channel, or the resultant sample will be significantly reduced in amplitude.

Note 2: Providing a 'T' connector so that you can hear the music as it goes into the circuit is highly recommended. In the author's case, there was considerable static when the ESP32 was powered by the computer's USB port, but was fine when the ESP32 was powered by a USB powerbank.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#dual-input-wiring","title":"Dual Input Wiring","text":"

The following diagram shows one way of connecting a 3.5mm jack and an analog microphone to the ESP8266/32 while being able to change your desired input with a simple SPDT switch.

The left and right channels of the TRS Jack are connected together to sample both channels simultaneously as one channel.

Connect the output of the capacitor to the ADC pin for your board.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#pins-used","title":"Pins Used","text":"

On the ESP32, the default ADC pin used is GPI36 (also known as VP), while the ESP8266 uses A0. Power is connected to the 3.3V pin. On ESP32 The ADC pin can be configured on the sound settings page; any GPIO associated with ADC1 (i.e. GPIO32 to GPI39) can be used.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#squelch","title":"Squelch","text":"

The volume and frequency reactive routines (starting with a single or double *), support a squelch or background noise suppression. This can be configured on the Sound Settings page.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#gain","title":"Gain","text":"

Line-in signals are typically much lower than that of some of the microphones. Rather than use an auto gain function, you can manually adjust the gain from 1 to 255, which translate to a gain factor from 0.1 up to 6.5 gain. That's equivalent to a range of -20dB up to +16dB.

"},{"location":"WLEDSR/Analog-Audio-Input-Options/#problems-encountered","title":"Problems Encountered","text":""},{"location":"WLEDSR/Analog-Sound-Sampling-Sketch-Example/","title":"Analog Sound Sampling Sketch Example","text":"

Use this basic code to read and calculate the average from the INMP401/MAX4466/MAX9814 microphone on an ESP32 or ESP8266

/* ESPSample\n *\n * By: Andrew Tuline\n *\n * Updated: Feb, 2019\n *\n * Basic code to read and calculate average from the Sparkfun INMP401/MAX4466/MAX9814 microphone\n * on an ESP32 or ESP8266.\n * \n * Use the Arduino Serial plotter to view the output. Compare results to those found at:\n * \n * https://github.com/atuline/WLED/blob/assets/docs/Microphones.pdf\n *\n * Note that the ESP32 employs a 12 bit A/D, while the ESP8266 has a 10 bit A/D. Also note\n * the anomalous spikes on the ESP8266.\n * \n * The micLev variable is the DC Offset value that you can use for zeroeing your samples.\n * \n */\n\n#ifdef ESP8266\n#define MIC_PIN A0                              // ESP8266 pin A0\n#else\n#define MIC_PIN 36                              // ESP32 pin also known as 'VP'.\n#endif\n\nvoid setup() {\n  delay(1000);\n  Serial.begin(115200);                         // Initialize serial port for debugging.\n} // setup()\n\nvoid loop() {\n  analog_sample();\n} // loop()\n\nvoid analog_sample() {\n  static float micLev;                          // Needs to be a float, or smoothing calculation below will be very inaccurate.\n  int micIn = analogRead(MIC_PIN);\n  micLev = ((micLev*31)+micIn)/32;              // Smooth out the data to get average value (used for zeroeing).\n  Serial.print(micIn); Serial.print(\" \");\n  Serial.print(micLev); Serial.println(\" \");\n} // analog_sample()\n
Original code can be found here.

"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/","title":"Arduino IDE Compile (Outdated)","text":""},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#compiling-from-a-fresh-install-of-the-arduino-ide","title":"Compiling from a fresh install of the Arduino IDE","text":"

Note: Around October 2020, mismatching library version issues made it increasingly difficult to compile WLED with the Arduino IDE. Your best bet is to use VS Code with Platform IO. In the meantime, here's the old Arduino IDE instructions:

  1. Have a read through Aircoookie's compiling documentation at https://github.com/Aircoookie/WLED/wiki/Compiling-WLED
  2. Download and install the Arduino IDE from arduino.cc. Defaults are OK.
  3. Start the Arduino IDE and add ESP8266/ESP32 board support by going to \"File | Preferences\" (\"Arduino | Preferences\" for macOS (\u2318,))
  4. In the \"Additional Boards Manager URLs\" section, copy these URL's and add: https://arduino.esp8266.com/stable/package_esp8266com_index.json for an ESP8266 and https://dl.espressif.com/dl/package_esp32_index.json for an ESP32. You can add both by separating them with a comma.
  5. Press \"OK\" to install support for the ESP8266/ESP32 platform
  6. Go to \"Tools | Board | Boards Manager...\"
  7. For the ESP8266/32, search for \"ESP8266\" and/or \"ESP32\"
  8. Click on \"Install\" for each.
  9. As of May 2020, the current version for ESP8266 was 2.7.1
  10. As of May 2020, the current version for ESP32 was 1.0.4

If you already have ESP8266/32 drivers installed, please ensure your drivers are recent:

  1. Go to \"Tools | Board | Boards Manager...\".
  2. For the ESP8266/32, search for \"ESP8266\" or \"ESP32\"
  3. As of July 2020, the current version was 2.7.2
  4. As of July 2020, the current version was 1.0.4
"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#board-settings","title":"Board Settings","text":""},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#lolin-d32-esp32","title":"LOLIN D32 (ESP32)","text":""},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#lolin-wemos-d1-mini-esp8266","title":"LOLIN WeMOS D1 Mini (ESP8266)","text":"

Note: Before attempting to compile WLED, make sure you can select your ESP board and compile a basic sketch such as: \"File | Examples | 01.Basics | Blink\"

"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#wled-library-pre-requisites","title":"WLED library pre-requisites:","text":"

WLED makes use of a LOT of 3rd party libraries and is NOT easy to compile, especially for anyone new to Arduino. Although the WLED distribution contains several of these libraries, it doesn't include them all. Additional libraries you need to install are:

See the next section to find/install these libraries.

"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#install-libraries-that-are-included-in-the-library-manager","title":"Install libraries that are included in the Library Manager","text":"
  1. Navigate to \"Tools | Manage Libraries...\" or \"Sketch | Include Libraries | Manage Libraries...\" for macOS (\u21e7\u2318I)
  2. Search for and install \"NeoPixelBus by Makuna\"
  3. Search for and install \"FastLED by Daniel Garcia\"
  4. Search for and install \"IRremoteESP8266 by Ken Shirriff, etc\"
  5. Search for and install \"arduinoFFT by Enqrique Condes\"
"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#install-libraries-that-are-not-included-in-the-library-manager","title":"Install libraries that are not included in the Library Manager:","text":"

To install libraries that are not in the library manager, you would typically:

  1. Download the zip file
  2. In the Arduino IDE use \"Sketch | Include Library | Add Zip Library\"
  3. Navigate to where you downloaded the .zipped library.
  4. Select it and press OK.
  5. Your library should now be included if you go \"Sketch | Include Libraries\" and navigate down to Contributed libraries.

  6. Download and install ESPAsyncTCP

  7. Download and install ESPAsyncWebServer

  8. Download and install ESPAsyncUDP

  9. For ESP32 Download and install AsyncTCP

Note: AirCoookie has since created a fork of ESPAsyncWebServer, and the original ESPAsyncWebServer will no longer work with WLED. If you have the original installed, you can edit wled.h and comment out the line as follows:

// #define WLED_ENABLE_WEBSOCKETS

If you add the library manually or with git you will most likely need to restart, yes restart the Arduino IDE before it will be recognized. For more information on libraries, see: https://www.arduino.cc/en/Guide/Libraries.

When you are done, if you navigate to 'File | Examples' and scroll all the way down, you should see:

"},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#download-wled","title":"Download WLED","text":""},{"location":"WLEDSR/Arduino-IDE-Compile-%28Outdated%29/#compiling-wled-for-arduino-ide-outdated","title":"Compiling WLED for Arduino IDE (OUTDATED)","text":"

Once you have:

You should now be able to compile and upload WLED to your ESP device.

If this feels like a treasure hunt, it is. Now, imagine what the authors of WLED had to go through just to get this all working together. We just figured out how to compile it and to get some sound reactive code running.

"},{"location":"WLEDSR/Connectivity-Issues/","title":"Connectivity Issues","text":"

We've sometimes been unable to connect to one or more of our WLED enabled devices. Here are some things to try:

Note: This page has been brought to you by our Discord friend @tuantrung2905. Thanks for your continued and persistent testing efforts!

"},{"location":"WLEDSR/Contributing-Code-to-SR-WLED/","title":"Contributing Code to SR WLED","text":"

We learned a long time ago that adding new code can make for a LOT of testing. If you offer to help out with this fork, please keep in mind that we support:

If you'd like to contribute, you would need to be able to perform a significant amount of testing and future maintenance (see above) so your new code doesn't unintentionally break other functionality.

"},{"location":"WLEDSR/Contributing-Code-to-SR-WLED/#what-functionality-to-add","title":"What functionality to add:","text":""},{"location":"WLEDSR/Contributing-Code-to-SR-WLED/#in-addition","title":"In addition:","text":""},{"location":"WLEDSR/Contributing-Code-to-SR-WLED/#knowledge-that-helps","title":"Knowledge That Helps:","text":"

We still have the occasional issue with our dev/master branches where we lose connectivity with the web server. This was most prevalent with the ESP8266 branch in AP mode, and precipitated a re-write for that platform. As a result of this ongoing issue, we are sensitive to new functionality being added without adequate testing.

In conclusion, the most important factors are commitment, teamwork, communication, documentation, testing, testing and more testing. Oh yea, and a bit of new code as well, just so long as it's thoroughly tested across the range of supported environments.

"},{"location":"WLEDSR/Contributing-Code-to-SR-WLED/#can-i-help","title":"Can I help?","text":"

Yes! This is a community project, and contributions are welcome! We're always up for a good PR(see above).

Just remember that any code you add will need to be maintained when we attempt to incorporate future versions of WLED. It's easy to add new code; maintaining it across multiple versions of WLED is a whole other matter. Be sparing with your additions.

"},{"location":"WLEDSR/Contributors-and-credits/","title":"Contributors and credits","text":"
  1. Contributors and Credits of sound reactive WLED fork
  2. Contributors and Credits of upstream WLED
"},{"location":"WLEDSR/Digital-Microphone-Hookup/","title":"Digital Microphone Hookup","text":""},{"location":"WLEDSR/Digital-Microphone-Hookup/#i2s-digital-audio","title":"I2S Digital Audio","text":"

I2S digital sound modules utilize the industry-standard 24-bit I\u00b2S interface. The I\u00b2S interface allows to connect them directly to an ESP32 (but NOT an ESP8266). The INMP441, and also the recently tested ICS-43434 (thanks to Serg74) work very well with SR WLED, and they perform much better than any analog device at a comparable price.

from INMP441, ICS-43434 from PDM (e.g. SPM1423) from Other to ESP32 GPIO L/R SEL SEL Gnd ground => left channel. Don't leave this pin unconnected! SD DATA DOUT 32 serial data WS CLK LRCK 15 left right clock SCK -- BCLK 14 serial clock -- -- MCLK 0 master clock (if needed) VDD 3V3 VDD 3.3V power don't use 5V! GND GND GND Gnd ground, 0V

ESP32 pins in the table are just examples. In fact any available GPIO can be used for I\u00b2S on ESP32. * SD can be either an in/out pin (gpio < 34) or an input-only pin (gpi >= 34), * while WS and SCK must be in/out pins (gpio < 34).

See also \u21d2 Sound setting examples for common microphones

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#microphone-type-sr-wled-sound-settings","title":"Microphone type (SR-WLED sound settings) )","text":"

Important: please make sure that your I2S device provides sound input on the LEFT audio channel! For the INMP441 this is achieved by wiring the 'L/R' connection to GND (ground). Only exception is the \"ES7243\" driver, which is always using the RIGHT audio channel.

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#pins","title":"Pins","text":"

Since 0.12.0, you can change I2S GPIO pins in the Sound Settings interface; on ESP32 any available GPIO can be used for I\u00b2S. The 'SD' signal could also be mapped to an input-only (GPI) pin (*), if you are low on GPIO pins. You'll need to reboot when done with pin assignment - don't forget to \"save\". To reboot, please press 'reset' on your ESP32. Unfortunately a restart by software (\"soft reboot\") is not always sufficient to activate new driver settings.

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#line-in","title":"Line-in","text":"

In addition to I2S microphones, there are solutions available for line-in via I2S. We already have driver support for Boards/Shields with \"es7243\" chip, and we're investigating \"es8388\".

Other I2S ADC (analog-to-digital-converter) devices and microphones that have a standard I2S interface may already work with WLED-SR, by using one of the I2S \"Generic\" drivers (Generic I2S, Generic I2S PDM, or Generic I2S with Mclk). It is important however that sound input comes on the LEFT audio channel. Please keep in mind that this is a spare-time open source project - we do our best to make generic drivers but we cannot test with all available devices.

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#notes-for-older-releases-of-sr-wled-before-0132","title":"Notes for older releases of SR WLED (before 0.13.2)","text":""},{"location":"WLEDSR/Digital-Microphone-Hookup/#still-having-problems","title":"Still having problems?","text":"

We do not have these digital microphones running on an ESP8266.

Having problems getting the INMP441 running with WLED? Here's a test sketch (which you can compile with the Arduino IDE): https://pastebin.com/Ua7s7LYF . If you are still having a problem with that sketch, change the line with ONLY_LEFT to ONLY_RIGHT. If that works, you'll need to go into audio_source.h and change that line.

Initial I2S support by @spedione

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#some-i2s-audio-modules-and-boards","title":"Some I2S audio modules and boards","text":""},{"location":"WLEDSR/Digital-Microphone-Hookup/#imnp441","title":"IMNP441","text":"

This is the IMNP441; you can find it in many shops including Amazon and Aliexpress. It works very well with SR WLED.

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#ics-43434","title":"ICS-43434","text":"

Here's the first board I've seen with the ICS-43434 at: https://www.tindie.com/products/serg74/digital-i2s-microphone-ics-43434-add-on/

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#i2s-adc-for-line-in","title":"I2S ADC for Line-In","text":"

It is recomended to capture audio using a digital input for Line-In rather than the analog solution, see this guide Line-Input

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#es7243-based-boards","title":"ES7243 based boards","text":""},{"location":"WLEDSR/Digital-Microphone-Hookup/#es8388-based-boards","title":"ES8388 based boards","text":"

with I2S on-board microphone and I2S Line-In (SR WLED support not available yet, but is supported in MoonModules)

"},{"location":"WLEDSR/Digital-Microphone-Hookup/#other-ideas-needs-some-work-to-make-it-work","title":"Other Ideas (needs some work to make it work)","text":""},{"location":"WLEDSR/Digital-Microphone-Hookup/#use-a-second-esp32-as-bluetooth-audio-to-i2s-device","title":"use a second esp32 as bluetooth audio to I2S device","text":"

In principle, its possible to have a second ESP32 that provides sound input to WLED via I2S.

"},{"location":"WLEDSR/Digital-Sound-Sampling-Sketch-Example/","title":"Digital Sound Sampling Sketch Example","text":"

Use this code to read and calculate the average from the INMP441/ICS-43434 microphone on an ESP32 or ESP8266

/* \n * ESP32 I2S Noise Level Example.\n * \n * By: maspetsberger\n * \n * Updated by: Andrew Tuline\n * \n * This example calculates a mean noise level.\n * \n * Tie the L/R pin to ground. Other pins are listed below.\n * VDD goes to 3.3V\n * GND goes to Gnd \n * \n */\n\n#include <driver/i2s.h>\n\n#define I2S_WS  15         // aka LRCL\n#define I2S_SD  32         // aka DOUT\n#define I2S_SCK 14         // aka BCLK\n\nconst i2s_port_t I2S_PORT = I2S_NUM_0;\nconst int BLOCK_SIZE = 64;\nconst int SAMPLE_RATE = 10240;\n\nfloat mean = 0;\nbool INMP_flag = 0;\n\nvoid setup() {\n\n  Serial.begin(115200);\n\n  Serial.println(\"Configuring I2S...\");\n  esp_err_t i2s_err;\n\n  // The I2S config as per the example\n  const i2s_config_t i2s_config = {\n      .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), // Receive, not transfer\n      .sample_rate = SAMPLE_RATE,                         // 16KHz\n      .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // could only get it to work with 32bits\n      .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // LEFT when pin is tied to ground.\n      .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),\n      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,     // Interrupt level 1\n      .dma_buf_count = 8,                           // number of buffers\n      .dma_buf_len = BLOCK_SIZE                     // samples per buffer\n  };\n\n  // The pin config as per the setup\n  const i2s_pin_config_t pin_config = {\n      .bck_io_num = I2S_SCK,       // BCLK aka SCK\n      .ws_io_num = I2S_WS,        // LRCL aka WS\n      .data_out_num = -1,         // not used (only for speakers)\n      .data_in_num = I2S_SD       // DOUT aka SD\n  };\n\n  // Configuring the I2S driver and pins.\n  // This function must be called before any I2S driver read/write operations.\n  i2s_err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);\n  if (i2s_err != ESP_OK) {\n    Serial.printf(\"Failed installing driver: %d\\n\", i2s_err);\n    while (true);\n  }\n  i2s_err = i2s_set_pin(I2S_PORT, &pin_config);\n  if (i2s_err != ESP_OK) {\n    Serial.printf(\"Failed setting pin: %d\\n\", i2s_err);\n    while (true);\n  }\n  Serial.println(\"I2S driver installed.\");\n\n  delay(1000);                        // Enough time to see these messages. This need to be BEFORE the INMP test.\n\n  getINMP();\n  if (mean != 0.0) {\n    Serial.println(\"INMP is present.\");\n    INMP_flag = 1;\n  }\n\n} // setup()\n\n\n\nvoid loop() {\n\n  if (INMP_flag) {\n    getINMP();\n    Serial.print(abs(mean)); Serial.print(\" \");\n    Serial.println(1600);\n\n  } else {\n    // Analog Read here!!\n  }\n\n} // loop()\n\n\n\nvoid getINMP() {\n  // Read multiple samples at once and calculate the sound pressure\n  int32_t samples[BLOCK_SIZE];\n  int num_bytes_read = i2s_read_bytes(I2S_PORT, \n                                      (char *)samples, \n                                      BLOCK_SIZE,     // the doc says bytes, but its elements.\n                                      portMAX_DELAY); // no timeout\n\n  int samples_read = num_bytes_read / 8;\n  if (samples_read > 0) {\n\n    for (int i = 0; i < samples_read; ++i) {\n      mean += samples[i];\n    }\n    mean = mean/BLOCK_SIZE/16384;\n  }  \n}\n
"},{"location":"WLEDSR/End-user-guide/","title":"End user guide","text":""},{"location":"WLEDSR/End-user-guide/#introduction","title":"Introduction","text":"

As WLED Sound Reactive is a fork of WLED, a general End User Guide can be found here.

This page will show Sound Reactive specific information (in the near future)

"},{"location":"WLEDSR/First-Time-Setup/","title":"First Time Setup","text":""},{"location":"WLEDSR/First-Time-Setup/#introduction","title":"Introduction","text":"

The sound reactive version of WLED provides all of the functionality of WLED with a few caveats:

"},{"location":"WLEDSR/First-Time-Setup/#first-steps","title":"First Steps","text":""},{"location":"WLEDSR/First-Time-Setup/#first-contact-after-uploading","title":"First Contact (after uploading)","text":"

After uploading WLED to the ESP, use your phone and connect to the WLED-AP using the password 'wled1234'. Click 'Login to network' when the notification about this shows up. You are then transfered to the WLED's start page, and here we should click \"WIFI SETTINGS\" to connect to the local network. Fill in the settings for your local Wifi network, and then click 'Save & Connect'. The device will reboot and if everything worked it will now be connected to the local network. Finding it's IP-address can be done via the network routers administration page, or via an mobile app like Fing were you can find a new device called \"wled-WLED\". Open this IP in a webbrowser to access WLED's control page.

"},{"location":"WLEDSR/First-Time-Setup/#wifi-and-leds","title":"Wifi and LEDs","text":"
  1. On the WiFi Setup page, it is highly recommended that you connect your SR WLED strip to an existing network.
  2. At the bottom of the WiFi Setup page, check on 'Disable WiFi sleep'. This may not be necessary if you're not experiencing noise or UDP Sync lag issues.
  3. On the LED Preferences page, configure the length of your led strip.
  4. On the LED Preference page, configure the 2D matrix size, i.e. 1x30 or 16x16, etc. If you have not configured this, 2D routines may not work.
"},{"location":"WLEDSR/First-Time-Setup/#sound","title":"Sound","text":"
  1. On the Sound Setting page, set the Squelch setting to '1', the Gain > 200, and AGC = Off.
  2. On the Effects page, set the animation to 'Gravcenter' or 'Gravimeter'.
  3. Back on the Sound Settings page, increase/save Squelch setting until strip no longer reacts to the ambient noise.
  4. On the Sound Settings page, set the Gain to 40. Then reduce/adjust the Gain setting until the leds react reasonably with your voice.
  5. You might also want to run a Pink Noise video and fine tune the values from there.
"},{"location":"WLEDSR/First-Time-Setup/#sound-settings-getting-started-with-common-microphones","title":"Sound Settings: getting started with common microphones","text":"

Disclaimer: The information below is for the latest release version of SR WLED. If you use an older release, please divide _Gain values by 4._

Here's a starting point table of Squelch and Gain settings for different input types:

Input (I2S digital) Squelch Gain Type comments INMP441 6 60 Generic I2S ICS-43434 16 30 Generic I2S SPM1423 tbd tbd Generic I2S PDM M5StickC, M5AtomU SPH0654 tbd tbd SPH0654 ES7243 tbd tbd ES7243 ESP32 Lyra-T Mini Line-In CS5343 tbd tbd Generic I2S with Mclk MCLK to GPIO0 Input (ADC analog) Squelch Gain Type MAX9814 @40dB 10 80 Generic Analog Line-In 8 120 Generic Analog INMP411 20 80 Generic Analog MAX4466 16 120 Generic Analog"},{"location":"WLEDSR/First-Time-Setup/#analog-or-i2s-digital","title":"Analog or I2S Digital?","text":"

We recommend using an I2S digital microphone, like INMP441, ICS-43434, or PDM microphones.

Analog input (Microphone or Line-in) is also possible, however you might have power fluctuation (3.3V) and noise issues when using these. Analog devices are handled by the \"ADC1\" unit of your ESP32. Problems can be expected when connecting \"analog buttons\" (Potentiometer) to the same ADC1 unit.

Finally Analog Microphones often work best when placed very close to the sound source, while digital ones like the INMP441 can easily pick up sound from several meters apart. With the analog MAX4466, we found that 30-50cm is an optimal distance.

"},{"location":"WLEDSR/First-Time-Setup/#agc","title":"AGC","text":"

Automatic gain control (AGC) is not enabled by default in SR WLED, because of so many different input types and ambient noise in different environments. We don't know what your 'quiet' is. In addition, the LED's should NOT be reacting when it IS quiet, so it's up to you to first make those adjustments. In addition, sensitivity can be further adjusted with either the Intensity or Speed slider in many of the animations.

While an improved autonomous gain control (iAGC) feature is available since version 0.13.1, it is still very important that you first find a good Squelch setting for your environment. Afterwards you can enable AGC and let the controller adjust input levels automatically.

"},{"location":"WLEDSR/First-Time-Setup/#noise-and-spikes","title":"Noise and Spikes","text":"

While providing a lot of functionality, the ESP8266 and the ESP32 boards (typical ones) we have been using, have experienced a lot of spurious noise on their ADC pins. This has also been discussed at length on various ESP related forums. Methods that may help remediate this include:

"},{"location":"WLEDSR/Future-Directions/","title":"Future Directions","text":"

We've had a lot of fun creating our audio reactive fork of WLED, and we've got more to come.

"},{"location":"WLEDSR/Future-Directions/#wish-list","title":"Wish List","text":"Topic Notes Skills Required \u2714\ufe0f Dynamic sliders/controls Allow additional sliders to be hidden by default, or displayed depending on the effect. Javascript, XML, JSON, HTML, CSS \u2714\ufe0f Improved default values for sliders Allow improved default values for sliders and on a per SEGMENT basis. Javascript, XML, JSON, HTML Add 2D Library support Add a full 2D library for FastLED functionality C, System \u2714\ufe0f Add SEGMENT support for 2D Improve SEGMENT capabilities Everything Improved/documented QA process We need to be able to better test our significant updates. A test/release plan would be a good start. ITIL Coordinated light show To have delayed/coordinated lighting effects in different devices. To run on Android. Kotlin (for Android), C Multi-pin To support SR WLED with SEGMENTS and multi-pin per-device squelch + gain see https://github.com/atuline/WLED/issues/221 for users who configure several sound inputs (use one at a time) it might be useful to have squelch/gain settings for each device. C++

Our focus for new functionality should be specific to sound reactivity. Otherwise, we should get some idea as to if/when AirCoookie is planning to implement this functionality.

"},{"location":"WLEDSR/Future-Directions/#outstanding-issues","title":"Outstanding Issues","text":"Issue Notes"},{"location":"WLEDSR/Home/","title":"Introduction","text":"

The WLEDSR help you can find here have been copied from https://github.com/atuline/WLED/wiki.

In this section you will find everything related to sound for versions <= 0.13

These pages are here temporarily: Aim is to migrate them step by step to 0.14 general and MM specific pages (Sound Reactive).

"},{"location":"WLEDSR/Home/#wled-sound-reactive-introduction","title":"WLED Sound Reactive Introduction","text":"

This is a FORK of the original WLED code as found at wled.me. It provides basic sound reactivity for both the ESP8266 and ESP32 platforms as well as FFT sound reactivity for the ESP32.

Due to the performance limitations of the ESP8266, we decided to separate the ESP8266 and ESP32 code in order to provide a more stable build for the ESP8266. Beginning with version 0.10.2 and moving forward, ESP8266 support has been removed from the master branch. It receives very limited support and updates and is located at ESP8266 Branch.

We have also disabled functionality for other interfaces, such as Alexa, Blynk, Cronixie, Huesync, Infrared. If you would like to enable them, you will need to modify wled.h, compile and upload to your device. If you have any issues, please engage the Discord community, as we only support functionality for the web interface.

"},{"location":"WLEDSR/Home/#features","title":"Features","text":"

We do our best to perform upstream merges with the original WLED. Our fork includes:

"},{"location":"WLEDSR/Home/#sound-reactive-wled-fork-team","title":"Sound Reactive WLED Fork Team:","text":"

Other members of the WLED Discord group have provided code and testing support as well. Thanks all!

"},{"location":"WLEDSR/Home/#knowledge-and-pre-requisites","title":"Knowledge and Pre-Requisites","text":"

Before attempting to compile this fork of WLED with Platform IO (the Arduino IDE is no longer viable for this project), make sure you CAN compile the one from wled.me.

If you are unable to compile WLED, please consider flashing your device with binaries instead.

"},{"location":"WLEDSR/Home/#hardware-used","title":"Hardware used","text":"

Using the WLED 0.10 codebase, our code has been tested with:

For more information, see our Analog Audio Input Options or Digital Audio Input Options page.

"},{"location":"WLEDSR/Home/#default-pins-used","title":"Default pins used","text":""},{"location":"WLEDSR/Home/#discussion-and-support","title":"Discussion and Support","text":"

Please consider joining the WLED Discord groups where we have dedicated channels to discuss this project, your projects, and answer any questions you may have.

Join Discord to discuss beta testing of our sound reactive fork of WLED.

Join Discord to discuss AirCookie's WLED.

We can also be found on reddit at r/soundreactive.

"},{"location":"WLEDSR/Home/#support-forums","title":"Support Forums","text":""},{"location":"WLEDSR/Installing-and-Compiling/","title":"Installing and Compiling","text":"

IMPORTANT: Before attempting to compile this fork of WLED, make sure you can compile the original WLED - instructions are here. If you are unable to compile WLED, please consider flashing your device with binaries instead.

If you managed to compile original WLED, test your new skills and compile the soundreactive fork of WLED.

"},{"location":"WLEDSR/Installing-and-Compiling/#installing-pre-built-binaries","title":"Installing pre-built binaries","text":""},{"location":"WLEDSR/Installing-and-Compiling/#downloading-usb-drivers","title":"Downloading USB Drivers","text":"

Download the CH340 drivers at https://www.wemos.cc/en/latest/ch340_driver.html

"},{"location":"WLEDSR/Installing-and-Compiling/#flashing-from-binary","title":"Flashing From Binary","text":"

The Sound Reactive WLED binaries for ESP32 are located here.

SR WLED releases are also included in this web-based installer: https://wled-install.github.io

"},{"location":"WLEDSR/Installing-and-Compiling/#flashing-esp32-binaries-with-esptool","title":"Flashing ESP32 Binaries with esptool","text":"

Warning: We had to change the partition size on the ESP32 in order to 'fit' all the new features. This means that the 'old way' of upgrading/flashing, no longer work unfortunately. You cannot use ESPHome Flasher, and you cannot use OTA from a build prior to v0.13.0-b5.

  1. Download esptool binary for your PC or MAC.
  2. Download the ESP32 bootloader, such as esp32_bootloader_v4
  3. Download the sound reactive binary, such as Atuline releases
  4. Plug the ESP32 board into your computer.
  5. Optionally determine which Com port it uses. You could use NodeMCU-PyFlasher to do this, but don't flash the binary with it.
  6. Open a Command prompt on your computer.
  7. Assuming you copied esptool and both binaries to the same directory, you could clear the contents of the ESP32 with: esptool.exe erase_flash
  8. Then burn the bootloader with: esptool.exe write_flash 0x0 esp32_bootloader_v4.bin
  9. Once complete, you can now burn the sound reactive binary with: esptool write_flash 0x10000 WLEDSR_0.13.X_soundReactive_esp32dev.bin
  10. You can optionally add the port, such as '-p COM6'.
  11. In addition, if this is the first time you've used this version, you need to go to the \"Security & Updates\" settings page and tick the \"Factory reset\" box, then select \"Save & Reboot\". Caveat: May not be necessary if you ran 'erase_flash' above.
  12. This will reset the EEPROM and remove any settings or presets you may have saved.

Note: If you Flash via another method, you will definitely need to perform a Factory Reset. Cycling the power is also a requirement if you're doing anything with I2S.

"},{"location":"WLEDSR/Installing-and-Compiling/#flashing-esp8266-binaries","title":"Flashing ESP8266 Binaries","text":"
  1. Download for your platform NodeMCU-PyFlasher.
  2. Plug the WeMOS D1 Mini (or other ESP8266 device) into your computer.
  3. Run NodeMCU-PyFlasher.
  4. Load the binary.
  5. Select the Com port.
  6. Select 'yes, wipes all data'.
  7. Press Flash NodeMCU.
"},{"location":"WLEDSR/Installing-and-Compiling/#unofficial-development-binaries-here-be-dragons","title":"unofficial development binaries - here be dragons","text":"

You can find some unofficial SR WLED binaries, including intermediate development builds for ESP32, here:

"},{"location":"WLEDSR/Installing-and-Compiling/#installation-services","title":"Installation services","text":""},{"location":"WLEDSR/Installing-and-Compiling/#firmware-binaries","title":"Firmware Binaries","text":"

Please keep in mind that these sites are not maintained by the SR WLED team. You may find old outdated binaries, or binaries that might not work on generic ESP32 hardware. So please compare build number and dates, and read descriptions before installing one of these.

"},{"location":"WLEDSR/Installing-and-Compiling/#compiling-from-platform-io","title":"Compiling from Platform IO","text":""},{"location":"WLEDSR/Installing-and-Compiling/#getting-started","title":"Getting started","text":"

\u21db first read https://mm.kno.wled.ge/advanced/compiling-wled/ \u2192 use source code from https://github.com/atuline/WLED/tree/master \u2192 start with one of the sound reactive compile environments, like env:soundReactive_esp32dev \u2192 read wled00/wled.h, add your own settings to wled00/my_config.h \u2192 put your own compile environment(s) into platformio_override.ini.

SoundReactive has some additional compile time options - see wled00/audio_reactive.h and wled00/audio_source.h.

"},{"location":"WLEDSR/Installing-and-Compiling/#additional-compile-guidelines","title":"Additional Compile Guidelines","text":"

Note: We have long since stopped compiling WLED with the Arduino IDE.

"},{"location":"WLEDSR/Installing-and-Compiling/#disabled-feature-of-wled","title":"Disabled Feature of WLED","text":"

Some features of \"standard WLED\" are by default disabled in SR WLED. These extended features have shown negative impacts on performance and stability - we need all available \"power\" to run sound analysis. For example, they possibly use too much memory (FLASH or RAM), can lead to lags in animations, or may cause slow responses to sound input.

The same is true for many WLED usermods: they might work (like 4LineDisplay), but could have side-effects on our sound reactive features so we disabled them in our \"official\" firmware builds.

"},{"location":"WLEDSR/Installing-and-Compiling/#how-to-shoot-yourself-in-the-foot","title":"How to Shoot Yourself in the Foot","text":"

If you're keen to use a disabled WLED feature, in your personal build of SR-WLED:

  1. check if there is a -D DISABLE_... flag in your build environment (platformio.ini, or platformio_override.ini), and comment it out or remove it.
  2. check if the feature is disabled explicitly in wled00/wled.h.
  3. If a feature has been disabled explicitly in wled.h, then there is usually a good technical reason for that decision. Please don't write bug reports for feature that were disabled explicitly.

  4. If you still want that feature, you can un-disable it like this

Add to your wled00/my_config.h

// re-activate Alexa support. Yes I know this is not supported officially. \n// I don't mind if animations will sometimes \"stutter\" and lag behind the sound.\n#ifdef WLED_DISABLE_ALEXA\n  #undef WLED_DISABLE_ALEXA\n#endif\n\n// re-activate MQTT support. Yes I know this is not supported officially. \n// I am ready to take good care of my hung, non-responsive device if necessary.\n#ifndef WLED_ENABLE_MQTT\n  #define WLED_ENABLE_MQTT\n  #ifdef WLED_DISABLE_MQTT\n  #undef WLED_DISABLE_MQTT\n  #endif\n#endif\n\n// re-activate IR receiver support. Yes I know this is not supported officially. \n// I can live with my LEDs flickering sometimes, and effects stuttering randomly.\n#ifdef WLED_DISABLE_INFRARED\n  #undef WLED_DISABLE_INFRARED\n#endif\n

"},{"location":"WLEDSR/LED-Preferences/","title":"2D LED Preferences","text":""},{"location":"WLEDSR/LED-Preferences/#led-preferences-for-sound-reactive-wled","title":"LED Preferences for Sound Reactive WLED","text":"

The sound reactive fork of WLED supports multiple layouts of a 2D matrix led panel as well as multiple identical 2D matrix led panels. Many effects were written with a 16x16 panel in mind, so some 2D effects may not display properly on a panel/matrix of a different size.

"},{"location":"WLEDSR/LED-Preferences/#2d-matrix","title":"2D Matrix","text":"

2D effects are projected on a 2 dimensional matrix.

A specific led is identified by led[x,y] where led[0,0] is in the top left corner (logical layer)

Setting name Value Range Description Master/Dev Width 1..x Width of the matrix Master Height 1..y Height of the matrix Master

Note: width x height should match LED count!

"},{"location":"WLEDSR/LED-Preferences/#2d-panels","title":"2D Panels","text":"

A matrix is made of 1 or more identical physical led panels (physical layer)

Setting name Value Range Description Master/Dev Multiple panels Y/N No if only one panel, yes if more than one Dev Horizontal panels 1..x Number of panels side by side Dev Vertical panels 1..y Number of panels above each other Dev

Note: Panel width = matrix width / horizontal panels and panel height = matrix height / vertical panels

Note: Total panels = horizontal * vertical

"},{"location":"WLEDSR/LED-Preferences/#2d-panel-layout","title":"2D Panel layout","text":"

Specify how a led panel is wired.

This is in most cases different from the logical layer (first led top left). Parameters here translate the logical layer (led[x,y]) to the physical layer (led[0] .. led[n]).

Setting name Value Range Description Master/Dev First led position Top/Bottom & Left/Right Where is the first led positioned Dev (replacing flipmajor/minor) Orientation Horizontal / Vertical Are rows of leds wired horizontal or vertical Dev (replacing rowMajor) Serpentine Y/N Are rows of leds wired zig-zag or not Master Transpose Y/N Swap the axes (otherwise no swap). Don't use on non-square panels Dev

Note: If multiple panels are used, they must be identical.

"},{"location":"WLEDSR/LED-Preferences/#example","title":"Example:","text":"

I have a 2D matrix of 6 - 8x8 panels. They are connected sequentially with a total of 24 led's wide and 16 led's high.

The first led of each panel starts in the top left corner, the subsequent led is to the right of it (horizontally), and the panel is in a serpentine layout. These should be the settings for that layout:

"},{"location":"WLEDSR/Modifying-Sound-Reactive-WLED/","title":"Modifying Sound Reactive WLED","text":""},{"location":"WLEDSR/Modifying-Sound-Reactive-WLED/#changing-web-ui","title":"Changing Web UI","text":"

In order to conserve space, Web UI interface are represented as a series of wled00/html_ui.h, wled00/html_settings.h and wled00/html_other.h files which contain C/C++ strings with specific parts of the Web UI.

These files are automatically created from source files available in wled00/data folder. To generate files, install NodeJS 11.0+ globally. After that, recreate html_*.h files by running in the repo directory:

> npm install\n> npm run build\n

If you want to test changes to the UI, it is easiest to work with the local wled00/data/index.htm file. You just need to enter the IP address of a WLED 0.10.0 or newer instance into the popup. If you accidentally input an incorrect IP or want to test with a different instance, clear the local storage (in Chrome: Developer Tools -> Application -> Local Storage)

If you continuously modify files in the wled00/data directory, you want to monitor these changes to make local html_*.h files being updated automatically. To do this, run this in repo directory:

> npm run dev\n

This will start monitoring wled00/data folder for changes.

WARNING!!! Be careful with changing the javascript in HTML files! For example function GetV() {} must be the last javascript function in the <script> element as it will be replaced by automatically generated code to fetch relevant settings from EEPROM. See tools/cdata.js for the replacement rules which run for every *.htm file in wled00/data.

"},{"location":"WLEDSR/My--device--is-not-working/","title":"It's Not Working","text":"

If you'd like some help with your device, these are the types of things we would be asking:

MAX4466/ESP32 Sampling results - Quiet room

MAX4466/ESP32 Sampling results - Talking

The other analog input options should provide something similar.

"},{"location":"WLEDSR/My--device--is-not-working/#udp-sound-sync-issues","title":"UDP Sound Sync Issues","text":"

We received a support request reporting that UDP sound synchronization will take down a Wi-Fi network. The challenge with troubleshooting WiFi is that you need to configure your packet sniffer in monitor mode, something which is very difficult to achieve with most workstations. As a result, we are unable to see a lot of Wi-Fi network traffic.

One setting to change on 'WiFi Setup' is to check on \"Disable WiFi sleep\" mode.

As for UDP support, this article may shed some light on the challenges:

https://superuser.com/questions/1287485/udp-broadcasting-not-working-on-some-routers

In the meantime, UDP Sound sync has been configured to transmit 50 packets per second.

"},{"location":"WLEDSR/News/","title":"News","text":"

What's possibly on the horizon (no dates given):

"},{"location":"WLEDSR/News/#may-15-2021","title":"May 15, 2021","text":"

We've since added several 2D routines to WLED and in the process have determined that our ESP32 binary now consumes about 98.5% of flash memory, or in oil industry terms. . . We have reached peak Flash. As a result, we're going to look carefully into ALL of the animations and see which ones consume the most flash and with the least coolness. In the meantime, we've updated SR WLED to support a very recent Master of 0.12.0, which has seen some changes/fixes since it was originally released. Special thanks to THATDONFC for keeping SR WLED in sync with Aircoookie's updates. It's not a small job.

"},{"location":"WLEDSR/News/#january-13-2021","title":"January 13, 2021","text":""},{"location":"WLEDSR/News/#november-5-2020","title":"November 5, 2020","text":""},{"location":"WLEDSR/News/#august-22-2020","title":"August 22, 2020","text":""},{"location":"WLEDSR/Noise-and-Spikes/","title":"Noise and Spikes","text":"

During the development of our sound reactive version of WLED, we've had several challenges with WiFi along with the ADC capability of the ESP devices.

"},{"location":"WLEDSR/Noise-and-Spikes/#esp8266","title":"ESP8266","text":"

After the code refactoring of WLED from .ino to .cpp files around April 2020, our ESP8266 code lost connection between the user interface and the ESP8266's web server. This eventually culimated in a re-write of a stripped down version of SR WLED dedicated just for the ESP8266. It included the UDP sound sync as a receiver (only), but supported none of the FFT or 2D functionality. This stripped down version seems to be stable, however that platform is now deprecated from further development.

"},{"location":"WLEDSR/Noise-and-Spikes/#esp32","title":"ESP32","text":"

Although the ESP32 did lose connection with the web server, it was nowhere near as bad as the ESP8266.

"},{"location":"WLEDSR/Noise-and-Spikes/#both-platforms","title":"Both platforms","text":"

On both platforms, we encountered significant spikes when using the analog ADC when the WiFi is active. There are numerous articles on this issue, along with various methods to reduce the noise. We've found that an I2S microphone, such as the INMP441 or ICS-43434 will provide a better response than any of the analog microphones or input methods that we support.

Here's some test results with the analog input, including strong spikes observed very frequently.

Here's some references:

Note: According to atomic14 in the above videos, the I2S microphones do not exhibit the issues found with the analog microphones.

"},{"location":"WLEDSR/Non-Reactive-Animations/","title":"Non-Reactive Animations","text":"

Note 1: Due to its limited capability, we have disabled 2D animations on the ESP8266 platform. Note 2: The 2D routines require a minimum of 4 pixels in both directions. If you see blinking red, your 2D settings don't match the requirements. (not required in latest dev) Note 3: As we continue to develop SR WLED, some animations may appear or disappear. It's still a work very much in progress. Some may only appear in the dev branch for now. Note 6: In dev branch, sliders have been renamed from FFT Low to Custom 1, FFT High to Custom 2 and FFT Custom to Custom 3.

See also Reactive animations

See List of effects and palettes for AC Animations.

See ScottrBaileys GIF visualizer for animations of the effects

Effect Description Sliders \u2699\ufe0f ARTI-FX Define your own effects, see here No controls (yet) Flow Stripe Strip with rotating colours. Speed: Controls a speed timer Intensity: Controls another timer Perlin Move Using Perlin Noise for movement. Speed: Speed of elementsIntensity: # of pixelsFFT Low: Fade rate Wavesins Beat waves and phase shifting. Looks OK in 2D'ish as well. Speed: SpeedIntensity: Varying brightnessFFT Low: Starting colourFFT High: Range of coloursFFT Custom: More fun to adjust 2D Colored Bursts Multiple lines. Speed: Speed of linesIntensity: Number of lines 2D DNA A very cool DNA like pattern. Select a palette. Speed: Scroll speedIntensity: Blur 2D DNA Spiral Spiraling DNA pattern. Speed: Speed.Intensity: Frequency 2D Drift A rotating caleidoscope. Speed: Speed of rotation.Intensity: Blur 2D Fire2012 Mark Kriegsman's fire routine. n/a 2D Firenoise Using Perlin Noise for fire. Speed: Yscale.Intensity: Scale 2D Frizzles Moving patterns. Speed: One thingIntensity: Another thing 2D Gameoflife Scrolling game of life. Speed: Speed Intensity: Starting grid 2D Hiphotic A moving plasma. Speed: One directionIntensity: Other direction 2D Lissajous A frequency based Lissajous pattern. Speed: Frequency of cosIntensity: Frequency of sin 2D Matrix The Matrix in 2D. Speed: Affects the speed of the movementIntensity: Number of lines 2D Metaballs A cool plasma type effect. n/a 2D Plasma A plasma effect. Speed: Affects the speed of the movementFFT Low: Shifts the coloursFFT High: Distance from the plasma 2D Plasma Ball A ball of plasma. Speed: Speed. Intensity: 2D Polar Lights The northern lights. Speed: Speed.Intensity: Frequency.FFT Low: Palette rotation 2D Pool Noise Looking at a pool. n/a 2D Pulser Travelling waves. Speed: Speed. Intensity: Blur 2D Sindots Moving/rotating pattern. Speed: Speed. Intensity: Length/size 2D Squared Swirl Boxes moving around. fft3: Blur amount 2D Sun radiation The sun! Doesn't support segments. Speed: VarianceIntensity: Brightness 2D Twister A large twister. Speed: Speed Intensity: Phases 2D Tartan tbd 2D Julia tbd 2D Game of life tbd 2D Black hole tbd 2D Noise tbd"},{"location":"WLEDSR/Non-Reactive-Animations/#2d-clock-overlay","title":"2D Clock Overlay","text":"

To configure, go to Time & Macros setting

Time setup: fill in required parameters

Clock: Clock overlay; Analog Clock, check Show 5min marks, uncheck the rest

"},{"location":"WLEDSR/Non-Reactive-Animations/#2d-animations","title":"2D Animations","text":"

Oh, and special thanks are in order for urish for creating wokwi, Elliot and his team for soulmatelights and Stepko and ldirko for some awesome 2D animations. With their approval, we were able to convert and publish several of their animations to use with WLED.

"},{"location":"WLEDSR/On-Lossy-Colours/","title":"On Lossy Colours","text":""},{"location":"WLEDSR/On-Lossy-Colours/#issue","title":"Issue","text":"

The following code moves the pixels down the line, but as it gets to the end, the intensity decreases significantly:

setPixelColor(i, getPixelColor(i-1));

"},{"location":"WLEDSR/On-Lossy-Colours/#explanation","title":"Explanation","text":"

getPixelColor() is lossy, whereas setPixelColor() perfectly sets the intended color. Unfortunately, the raw pixel memory buffer is also lossy, since it has to save the values scaled by master brightness. And unfortunately, if you do s = x\\*b /255, later doing x = s\\*255/b won't yield exactly the same result (thanks integer division). To solve this problem, we would need a secondary pixel data buffer.

See: https://github.com/Aircoookie/WLED/issues/820

"},{"location":"WLEDSR/On-Lossy-Colours/#workarounds","title":"Workarounds","text":"

As a workaround, you could allocate memory for each function on the fly as a double buffer and use that, or you could hard code an array. Either way, you need to double up on the memory requirements and that is extremely limited with the ESP8266 and not recommended for that platform.

"},{"location":"WLEDSR/On-Lossy-Colours/#allocate-memory","title":"Allocate memory","text":"

if (!SEGENV.allocateData(SEGLEN)) return mode_static();  // Allocation failed\nbyte* myVal = SEGENV.data;                               // Could also be an int or long or whatever.\n
In this case, we are using that byte defined array for some function, but NOT to store full color values. You could then refer to myVal[0] up through myVal[SEGLEN-1] within the routine for that function. You could also define a long, then allocate the memory for it, and then store your colors in the array until you need to transfer them to the NeoPixel buffer at the end of your routine. See the transfer code below.

One problem with dynamic memory allocation at the firmware level is that it can become segmented and fail.

"},{"location":"WLEDSR/On-Lossy-Colours/#hard-coded-array","title":"Hard-coded array","text":"

First off, I would encapsulate ALL of this with #ifndef statements because you can't guarantee memory available on an ESP8266. In FX.cpp, you would define globally:

#ifndef ESP8266\nuint32_t ledData[1500];  // Or whatever value.\n#endif\n
Similarly, you would encapsulate all functions and definitions that support that array. In the (encapsulated) animation, you would do the following:

uint16_t WS2812FX::mode_myMode(void) {\n\n#ifndef ESP8266\n\n  uint32_t* leds = ledData;\n\n// PERFORM ANIMATION MAGIC HERE!!\n\n  for (int i = SEGLEN; i > 0; i--) {   // You can shift LED's the FastLED way.\n    leds[i] = leds[i-1];\n  }\n\n  for (int i= 0; i < SEGLEN; i++) {    // Now send to the NeoPixelBus array\n    c.h = (leds[i] >> 16) & 0xFF;\n    c.s = (leds[i] >> 8) &0xFF;\n    c.v = leds[i] & 0xFF;\n    color = c;                         // Implicit conversion to RGB supplied by FastLED\n    setPixelColor(i, color.red, color.green, color.blue);\n  }\n#else\n// DO SOMETHING ELSE IF YOU WANT. Maybe a fade_out(32);\n#endif\n\n  return FRAMETIME;\n} // mode_myMode()\n
"},{"location":"WLEDSR/Other-Links/","title":"Other","text":""},{"location":"WLEDSR/Other-Links/#sr-wled-interfacing","title":"SR WLED interfacing","text":""},{"location":"WLEDSR/Other-Links/#fft-related","title":"FFT related","text":""},{"location":"WLEDSR/Other-Links/#audio-processing","title":"Audio processing","text":""},{"location":"WLEDSR/Other-Links/#audio-drivers","title":"audio drivers","text":""},{"location":"WLEDSR/Other-Links/#es8388","title":"ES8388","text":""},{"location":"WLEDSR/Persistent-Variables-and-WLED/","title":"Persistent Variables and WLED","text":""},{"location":"WLEDSR/Persistent-Variables-and-WLED/#introduction","title":"Introduction","text":"

Let's investigate persistent variables for the Arduino and how to use them, and then see how we can do so in WLED.

Normally, for a given Arduino sketch you can define variables as follows:

  uint8_t var1 = 5;                 // A persistent global variable that is defined once.\n\n  void setup() {\n    Serial.begin(115200);\n  }\n\n  void loop() {\n    routine1();\n  }\n\n  void routine1() {\n    uint8_t var2;                   // A non-persistent local variable.\n    static uint8_t var3;            // A persistent local variable.\n\n    Serial.print(var1); Serial.print(\"\\t\"); Serial.print(var2); Serial.print(\"\\t\"); Serial.println(var3);\n\n    var1 = 7;\n    var2 = 10;\n    var3 = 25;\n\n    delay(1000);\n  }\n

The first time you run through the loop, we'll see the following, where only var1 has been assigned a non-zero value:

  5    0     0\n

At the end of the first loop, all the variables were assigned values. The second time through the loop, var1 was already changed to 7 in the first loop, while var2 is non-persistent and has yet to have a value assigned in this loop. The variable var3 is a 'persistent' local variable, with a value assigned in the first pass of the loop. Output will be:

  7    0    25\n

So, we have global and local variables, as well as persistent and non-persistent ones. Local variables require the 'static' keyword in order for them to keep their values (or be persistent) between function calls, while ALL global variables are persistent.

"},{"location":"WLEDSR/Persistent-Variables-and-WLED/#enter-wled","title":"Enter WLED . . .","text":"

Although you CAN use the static keyword in a WLED animation to define a persistent variable, that variable will have the same value for ALL of the segments, and may not result in the desired properties. As a result, you may need to define a persistent variable unique to each SEGMENT.

WLED has a SEGMENT runtime structure that supports persistency. The only problem is that it has a limited number of pre-defined variables for generic use by animations (in FX.cpp). The readily available variables (as defined in FX.h) are:

uint16_t SEGENV.aux0;               // Available for your routine.\nuint16_t SEGENV.aux1                // Available for your routine.\nbyte* SEGENV.data;                  // Available for your routine.\n

SEGENV.aux0 and SEGENV.aux1 are both unsigned 16 bit values, which you can use as persistent variables in your routines and will be unique for each SEGMENT. The question is, what if you need:

At that point, you'll need to make use of that *byte SEGENV.data pointer and allocate memory for it and then redefine how it's used. Let's examine some methods to do so and review some of the animations in FX.cpp to do so. WLED has a method called SEGENT.allocateData() which allocates memory for your animation. Here's some examples of how to use that.

"},{"location":"WLEDSR/Persistent-Variables-and-WLED/#basic-memory-allocation","title":"Basic Memory Allocation","text":"

In its simplest form, the routine mode_dynamic() just performs a basic request to allocate space for the length of a given SEGMENT with:

` if (!SEGENV.allocateData(SEGLEN)) return mode_static(); // If it fails, WLED runs mode_static().

It doesn't make use of additional variables and is probably a good idea to implement on other animations, especially in a limited environment such as the ESP01 and with a considerable number of LED's.

"},{"location":"WLEDSR/Persistent-Variables-and-WLED/#an-array","title":"An Array","text":"

Next up is mode_multi_comet(), which reserves space for 8 uint16_t values for an array of comets.

  if (!SEGENV.allocateData(sizeof(uint16_t) * 8)) return mode_static(); //Allocates based on the size of 8 uint16_t variables\n\n  uint16_t* comets = reinterpret_cast<uint16_t*>(SEGENV.data);          // It then redefined that byte* pointer to uint16_t comets[16].\n\n  Now you can use things like:\n\n  for (int i=0; i<8; i++) {\n    comets[i] = 65535;          // Or other uint16_t value.\n  }\n
"},{"location":"WLEDSR/Persistent-Variables-and-WLED/#a-structure","title":"A Structure","text":"

Finally, we'll look into ripple_base(), which allocates persistent memory for a 'Ripple' structure. First off, we define the structure externally to the animation and call it 'ripple'.

  typedef struct Ripple {\n    int8_t state;\n    uint8_t color;\n    uint16_t pos;\n  } ripple;\n

From within the ripple_base() routine, we determine the number of ripples we want to support for each segment. In this case, we'll say:

` uint16_t maxRipples = 1 + (SEGLEN >> 2);

Next, we determine how much memory we need, where 'sizeof' returns number of bytes occupied by a variable of a given type.

` uint16_t dataSize = sizeof(ripple) * maxRipples;

Next, we allocate the memory, and then re-define it as our structure:

  if (!SEGENV.allocateData(dataSize)) return mode_static();\n  Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data);\n

Now, we can use our structure, up to maxRipples-1:

  for (uint16_t i = 0; i < maxRipples; i++) {\n    ripples[i].pos   = ???;  // uint16_t\n    ripples[i].state = ???;  // int8_t\n    ripples[i].color = ???;  // uint8_t\n  }\n
"},{"location":"WLEDSR/Persistent-Variables-and-WLED/#a-floating-point-variable","title":"A Floating Point Variable","text":"

As an exercise, let's just allocate a single floating point variable:

  if (!SEGENV.allocateData(sizeof(float))) return mode_static();\n  float* expAdj = reinterpret_cast<float*>(SEGENV.data);          // We then redefine that byte* pointer to a float.\n

We should now be able to use the persistent floating point variable 'expAdj' with our routine and it should work with ALL segments indepently of each other.

  expAdj = 1.2345;\n
"},{"location":"WLEDSR/Reactive-Animations/","title":"Sound Reactive Animations","text":"

Note 1: Effects beginning with \u266a (* in list below) are volume only.

Note 2: Effects beginning with \u266b (** in list below) use FFT (Fast Fourier Transforms) for frequency detection.

Note 3: We have also not added 2D animations to the ESP8266 platform. ESP8266 is depricated in SR WLED, so we recommend that you use ESP32.

Note 4: The 2D routines require a minimum of 4 pixels in both directions. If you see blinking red, your 2D settings don't match the requirements. (not required in latest dev)

Note 5: As we continue to develop SR WLED, some animations may appear or disappear. It's still a work very much in progress. Some may only appear in the dev branch for now.

Note 6: In dev branch, sliders have been renamed from FFT Low to Custom 1, FFT High to Custom 2 and FFT Custom to Custom 3.

See also Non reactive animations

See List of effects and palettes for AC Animations.

See ScottrBaileys GIF visualizer for animations of the effects

Effect Description Sliders * 2D Swirl Several blurred circles. Looks good with pink plasma palette. Supports AGC. Speed: Speed Intensity: SensitivityFFT Low: Blur * 2D Waverly Noise waves with some sound Speed: AmplificationIntensity: Sensitivity * Gravcenter Volume reactive vu-meter from center with gravity and perlin noise. Speed: Rate of fall Intensity: Sensitivity * Gravcentric Volume reactive vu-meter from center with gravity. Volume provides index to (time rotating) palette colour. Speed: Rate of fall Intensity: Sensitivity * Gravimeter Volume reactive vu-meter with gravity and perlin noise. Speed: Rate of fall Intensity: Sensitivity * Juggles Juggling balls. Speed: Yes Intensity: # of balls * Matripix Similar to Matrix. Speed: yes Intensity: Brightness * Midnoise Perlin noise emanating from center. Speed: Fade rate Intensity: Maximum length * Noisefire A perlin noise based volume reactive fire routine. n/a * Noisemeter Volume reactive vu-meter. Speed: Fade rate Intensity: Width * Pixels Random pixels. Speed: Fade rate Intensity: # of pixels * Pixelwave Pixels emanating from center. Speed: yes Intensity: Sensitivity * Plasmoid Sine wave based plasma. Intensity: # of pixels * Puddlepeak Blast coloured puddles randomly up and down the strand with the 'beat'. Speed: Adjust fade rate. Intensity: Size of puddles FFT High: 256 freq bin select on ESP32. FFT Custom: Volume comparator on ESP32 * Puddles Blast coloured puddles based on volume. Speed: Fade rate Intensity: Size of puddle * Ripple Peak Peak detection triggers ripples. Intensity: Max number of ripples. FFT High: 256 freq bin select on ESP32 FFT Custom: Volume comparator on ESP32 * Waterfall A volume AND FFT version of a Waterfall that has 'beat' support. Speed: Speed Intensity: Adjust colour ** 2D CenterBars A 16x16 spectral analysis routine emanating from the center Speed: Bar Speed Intensity: Ripple time FFT Custom1: Center horizontally FFT Custom2: Center vertically FFT Custom3: Color vertically ** 2D Funky Plank A 2D wall of reactivity running from bottom to top Speed: Scroll Speed FFT Custom1: Number of bands ** 2D GEQ A 16x16 graphic equalizer. Speed: Bar Speed Intensity: Ripple timeFFT Custom1: Number of bands ** Binmap Map bins 3-255 throughout the length of the LEDs. This does not work with UDP sync.Values are not normalized. Intensity: Max volume ** Blurz Flash an fftResult bin per frame and then blur/fade. Speed: Fade Rate Intensity: Blurring ** DJLight An effect emanating from the center to the edges. Speed: Speed ** Freqmap Map the loudest frequency throughout the length of the LED's. Speed: Fade rateIntensity: Starting colour ** Freqmatrix See below See below ** Freqpixels Random pixels coloured by frequency. Speed: Fade rateIntensity: Starting colour and number of pixels ** Freqwave See below See below ** Gravfreq VU Meter from center. Log of frequency is index to center colour. Speed: Rate of fallIntensity: Sensitivity ** Noisemove Using perlin noise as movement for different frequency bins. Speed: Speed of perlin movement Intensity: Fade rate ** Rocktaves Colours the same for each note between octaves, with sine wave going back and forth. Speed: n/aIntensity: n/a ** Waterfall FFT version of a Waterfall. Speed: Speed Intensity: Adjust colourFFT High: 256 freq bin select on ESP32 FFT Custom: Volume comparator on ESP32 ** DJ Light tbd ** 2D Akemi tbd"},{"location":"WLEDSR/Reactive-Animations/#slider-usage","title":"Slider Usage","text":"

Please see the brief slider descripion for each effect in the rightmost column above.

"},{"location":"WLEDSR/Reactive-Animations/#speedintensity","title":"Speed/Intensity","text":"

These typically reflect the value of their namesake. Intensity would typically be number of LED's lit, or brightness of the LED's

"},{"location":"WLEDSR/Reactive-Animations/#fft-sliders","title":"FFT Sliders","text":"

These may get renamed in the future and could be used for FFT routines OR for additional effect adjustments.

"},{"location":"WLEDSR/Reactive-Animations/#peak-detection","title":"Peak Detection","text":"

This is NOT beat detection, but rather samples that are louder than a the current average plus a slider adjustable value.

"},{"location":"WLEDSR/Reactive-Animations/#automatic-gain-control","title":"Automatic Gain Control","text":"

We are just beginning to add Automatic Gain Control to the routines, starting with 2D Swirl. This setting is only available on the LED Preferences page on the ESP32.

"},{"location":"WLEDSR/Reactive-Animations/#fft-routines","title":"FFT Routines","text":""},{"location":"WLEDSR/Reactive-Animations/#additional-effect-notes","title":"Additional effect notes","text":""},{"location":"WLEDSR/Reactive-Animations/#freqmatrix","title":"Freqmatrix","text":"

The temporal tail for this animation starts at the beginning of the Segment rather than in the center of the segment.

Sliders used:

Slider usage is described in the rightmost column for each effect. In general, the sliders are configured for:

  1. Speed: This determines the time delay before each pixel is moved down the line.
  2. Intensity: This determines how MUCH the sound input affects the selected effect.
  3. FFT Low: Can be an additional adjustment. Can also select low end of frequency bins if used by that effect.
  4. FFT High: Can be an additional adjustment. Can also select high end of frequency bins if used by that effect.
  5. FFT Custom: Can be an addiitional adjustment.
"},{"location":"WLEDSR/Reactive-Animations/#freqwave","title":"Freqwave","text":"

This effect maps the major frequencies from the incoming signal to colors in the HSV color space. From the low notes being mapped to red (0) to the high notes being mapped to blue (255) and everything in between. The band you are looking at can be restricted by the FFT Low and FFT High sliders. We are digitizing at 10240Hz, meaning the highest frequency bin that you can find is 5120Hz, which for most music is just fine.

Sliders used:

  1. Speed: This determines the time delay before each pixel is moved down the line.
  2. Intensity: This determines how MUCH the sound input affects the selected effect.
  3. FFT Low: The low cut off for the FFT bins. Values range from 0-100. Good values are from 0 to 10
  4. FFT High: High cut off for the FFT bins. Values range from 0-100. This is important because every type of music is different and what is considered a high note in one type of music is not the case in others.
  5. FFT Custom: This slider works similarly to a \"pre-amp\" for the input signal. The possible values for this slider are 1-10. A good starting point for this is around 2-3.
"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/","title":"Running Sound Reactive WLED","text":""},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#captive-portal","title":"Captive Portal","text":"

When you first connect to a WLED device in AP mode, there is some really annoying behavior on the captive portal implementation in Android. The captive portal is the limited browser you are forwarded to in order to login to a web site. What happens is that if you go into 'Effects', you can't scroll up. In order to get around that, click the three dots at the top right of the page, select 'Use Network as is', then open up Chrome and navigate to the site at 4.3.2.1.

"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#initial-sound-reactive-settings","title":"Initial Sound Reactive Settings","text":"

On the \"Sound Settings\" page, configure the Squelch for a value (default is 10) to reduce your background noise for volume reactive effects. Volume reactive effects start with a single '*'. Typically, values between 4 and 20 should suffice. The higher the number, the greater the background noise is suppressed.

Configure the Gain setting (default is 60) to change the \"perceived volume\" of the input signal. More info on Squelch and Gain here.

"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#initial-2d-settings-esp32-only","title":"Initial 2D Settings - ESP32 Only","text":"

When changing any values in the LED settings page, you'll need to update the 2D settings. If not using a 2D matrix, you can set them to 1 x or vice versa. If using a 2D matrix, configure these values for width x height. A value of less than 4 in either dimension will not work with some of the 2D animations.

The serpentine parameter configures whether the LED's are wired up in a continuous/serpentine layout or top to bottom and repeat.

"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#initial-udp-sync-settings","title":"Initial UDP Sync Settings","text":"

Devices can be configured as 'disabled', 'transmit' or 'receive' UDP sound. This is completely independent of the 'Sync' button, which synchronizes effects.

As a result, you can run multiple types of sound reactive animations when UDP Sound Sync is enabled. This feature provides a subset of the sound and FFT data to several 'slave' devices. As a result, some FFT enabled routines will not function in this mode. You must RESET the ESP32 after you enable/disable this on the Sync settings page.

"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#connect-to-wled","title":"Connect to WLED","text":"
  1. Open up settings on your phone or computer.
  2. Navigate to your Wi-Fi settings.
  3. Look for the WLED SSID, default is \"WLED-AP\".
  4. Enter the password, the default is \"wled1234\".
  5. Once connected, you should automatically be re-directed to your LED strip.
  6. This gets you to the limited captive portal 'browser'.
  7. If not, open up a browser and navigate to 4.3.2.1.
"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#configure-a-bootup-effects-sequence","title":"Configure a bootup effects sequence","text":"
  1. From the main screen, click on \"TO THE CONTROLS!\"
  2. Select the \"Effects\" tab.
  3. Select an effect mode, i.e. \"Bpm\".
  4. Adjust overall brightness, speed, and intensity/fade rate.
  5. Select the \"Colors\" tab.
  6. Select one of the palettes, such as \"Beach\".
  7. Select the \"Favorites\" tab.
  8. Select the \"Saving mode\" checkbox.
  9. Save to slot \"1\".
  10. Check the \"Preset\" cycle.
  11. Select the Config cog at the top right of the application display.
  12. Select \"LED Preference\".
  13. Check \"Set current preset cycle setting as boot default\" checkbox.
  14. Click on \"Save\" at the bottom of the screen.
"},{"location":"WLEDSR/Running-Sound-Reactive-WLED/#reset-the-device","title":"Reset the device","text":"
  1. Log in to the device. If you cannot log in, then you need to Reflash the device, which may default to AP mode.
  2. Select the Config cog at the top right of the application display.
  3. Select \"Security and Updates\".
  4. Check \"Factory reset\".
  5. Click on \"Save & reboot\".
  6. Reverts to the initial AP Mode and all other settings are gone.
"},{"location":"WLEDSR/Settings/","title":"Settings","text":""},{"location":"WLEDSR/Settings/#aircoookies-led-settings","title":"AirCoookie's LED settings","text":"

See WLED General Led Settings

"},{"location":"WLEDSR/Settings/#led-settings-for-sound-reactive-additions","title":"LED Settings for Sound Reactive Additions","text":"

See LED Preferences

"},{"location":"WLEDSR/Settings/#sound-reactive-settings","title":"Sound Reactive Settings","text":"

See Sound Settings

"},{"location":"WLEDSR/Squelch-and-Gain/","title":"Squelch and Gain","text":""},{"location":"WLEDSR/Squelch-and-Gain/#introduction","title":"Introduction","text":"

In order to accommodate a wide range of audio inputs, ambient environments and string lengths, we have added user configurable squelch (noise reduction/suppression) and gain controls on the LED settings page for the volume reactive animations.

"},{"location":"WLEDSR/Squelch-and-Gain/#squelch","title":"Squelch","text":"

Adjust this value on the LED Settings page so that the leds are only activated above a certain 'background noise' level.

"},{"location":"WLEDSR/Squelch-and-Gain/#gain","title":"Gain","text":"

Line-in signals are typically much lower than that of some of the microphones. Rather than use an auto gain function, you can manually adjust the gain from 1 to 255, which translate up to almost 6.0 gain.

In addition, the 'Intensity' slider can sometimes adjust an animation to simulate increased gain.

"},{"location":"WLEDSR/Squelch-and-Gain/#how-to","title":"How To","text":"

Here's a method to setup squelch and gain for your SR WLED Device.

  1. Start out with the routine '*Gravcenter' with default sliders in the middle.
  2. Go to the sound settings configuration page.
  3. Increase gain to a high value, let's say 234 (or higher) and set the squelch to '1' , AGC off, and save.
  4. Depending on your input, you should now see the led's flashing.
  5. In a quiet environment, increase and occasionally save the squelch incrementally until the led's are no longer flashing.
  6. Once that's done, make noise appropriate to your 'noisy' environment and number of led's. Then adjust/save the gain so that the led's are responding appropriately.
  7. Note that some of the animations allow further sensitivity adjustment with the 'Intensity' setting.
  8. Check out the 'Sound Reactive Animations' page to see what controls are available for each animation.
"},{"location":"WLEDSR/Squelch-and-Gain/#voltage-fluctuation","title":"Voltage Fluctuation","text":"

From faulty microphones to flaky wiring, to WiFi related issues, particularly in AP mode, getting reliable and spike free sound sampling with WLED and in particular analog sampling has been a challenge. Digital microphones such as the INMP441, the ICS-43434 provide the best results.

"},{"location":"WLEDSR/Testing/","title":"Testing","text":"

IMPORTANT NOTE:

When testing the UI, make sure to refresh your web browser. It may have cached incorrect information.

"},{"location":"WLEDSR/Testing/#compile","title":"Compile","text":""},{"location":"WLEDSR/Testing/#network","title":"Network","text":""},{"location":"WLEDSR/Testing/#colors","title":"Colors","text":""},{"location":"WLEDSR/Testing/#effects","title":"Effects","text":""},{"location":"WLEDSR/Testing/#segments","title":"Segments","text":""},{"location":"WLEDSR/Testing/#sound","title":"Sound","text":""},{"location":"WLEDSR/Testing/#2d","title":"2D","text":""},{"location":"WLEDSR/Testing/#udp-sound-sync","title":"UDP Sound Sync","text":""},{"location":"WLEDSR/Testing/#eeprom","title":"EEPROM","text":""},{"location":"WLEDSR/UDP-Sound-Sync/","title":"UDP Sound Sync","text":"

UDP Sound Sync is a feature to synchronize (share) the sound input of a 'master' device with one or more 'slave' devices. All devices must be running the same release of SR WLED, and they must be in the same local network. Sound Sync is not available in \"upstream\" WLED by Aircookie. Sound Sync is also different from direct LEDs control using protocols like E1.31, DMX, DDP or AdaLight.

UDP Sound Sync does not sync the actual animations, but rather transmits summary audio sampling information to several devices that still run their own animations locally. In a nutshell, it means that several devices can share a single microphone.

"},{"location":"WLEDSR/UDP-Sound-Sync/#setup","title":"Setup","text":"

Before configuring UDP Sound Sync, make sure you have gone into the WiFi Preferences and clicked on 'Disable WiFi sleep' at the bottom of the page. It has caused us innumerable problems in the past.

In order to configure UDP sound sync, the \u2018master\u2019 needs to be an ESP32 along with an audio input.

You would then to go the \u2018Sync Interfaces\u2019 page and configure the 'Audio Sync' at the bottom of the page. Transmit for the ESP32 and Receive for devices without an audio input (either ESP32's or ESP8266's). Make sure the UDP port is the same on all devices.

This does not sync the actual animations, but rather just the transmission of summary audio sampling information (as best we can).

In order to change the UDP Sync Mode (Disabled/Transmit/Receive), you need to power-cycle the ESP32/ESP8266.

"},{"location":"WLEDSR/UDP-Sound-Sync/#technical","title":"Technical","text":"

When an ESP32 is configured for audio transmission, it will connect to a UDP Multicast address, and begin sending a single UDP Multicast packet containing the data used to generate sound-reactive animations out to any other devices that are configured to receive on the same network. The following information is transmitted:

"},{"location":"WLEDSR/UDP-Sound-Sync/#v1-format-used-in-sr-wled-up-to-013x","title":"V1 format, used in SR WLED up to 0.13.x","text":"
#define UDP_SYNC_HEADER \"00001\"\nstruct audioSyncPacket {\n  char header[6] = UDP_SYNC_HEADER;\n  uint8_t myVals[32];     //  32 Bytes\n  int sampleAgc;          //  04 Bytes\n  int sampleRaw;          //  04 Bytes\n  float sampleAvg;        //  04 Bytes\n  bool samplePeak;        //  01 Bytes\n  uint8_t fftResult[16];  //  16 Bytes - FFT results, one byte per GEQ channel\n  double FFT_Magnitude;   //  08 Bytes\n  double FFT_MajorPeak;   //  08 Bytes\n};\n

UDP_SYNC_HEADER is a versioning number that's defined in audio_reactive.h

"},{"location":"WLEDSR/UDP-Sound-Sync/#v2-format-wled-version-0140-including-moonmodules-fork","title":"V2 Format - WLED version >= 0.14.0 (including MoonModules fork)","text":"
#define UDP_SYNC_HEADER_V2 \"00002\"\n// new \"V2\" AC 0.14.0 audiosync struct - 40 Bytes\nstruct audioSyncPacket_v2 {\n      char    header[6] = UDP_SYNC_HEADER_V2; // 06 bytes, last byte is '\\0' as string terminator.\n      float   sampleRaw;      //  04 Bytes  - either \"sampleRaw\" or \"rawSampleAgc\" depending on soundAgc setting\n      float   sampleSmth;     //  04 Bytes  - either \"sampleAvg\" or \"sampleAgc\" depending on soundAgc setting\n      uint8_t samplePeak;     //  01 Bytes  - 0 no peak; >=1 peak detected. In future, this will also provide peak Magnitude\n      uint8_t reserved1;      //  01 Bytes  - reserved for future extensions like loudness\n      uint8_t fftResult[16];  //  16 Bytes  - FFT results, one byte per GEQ channel\n      float  FFT_Magnitude;   //  04 Bytes  - magnitude of strongest peak in FFT\n      float  FFT_MajorPeak;   //  04 Bytes  - frequency of strongest peak in FFT\n};\n

The V2 format expects that AGC is performed by the sender, so there is no need to transmit \"AGC\" and \"non-AGC\" samples separately. To save bandwidth, the myvals[] array was removed, and all numbers are either float or uint8_t.

SR-WLED 0.13.3 still sends out V1 format, however it is able to receive and decode V2 format, too.

"},{"location":"WLEDSR/UDP-Sound-Sync/#what-else","title":"What else ?","text":"

You might want to take a look at this library, which allows to send and receive WLED Audio Sync data independent from WLED.

When an ESP32 or ESP8266 is configured to receive audio data from another device, the receiver will disable any onboard microphone sampling and FFT processing, in favor of audio data received from the network. Any time a UDP Multicast packet is received from a transmitter, it will be treated as a discrete microphone sample and stored in memory the same way it would be if it were a local microphone.

UDP Sound sync brought to you by @spedione on Discord.

Reference: https://github.com/Aircoookie/WLED/wiki/UDP-Realtime-Control

"},{"location":"WLEDSR/Using-my-PC-for-the-Sound/","title":"Using my PC for the Sound","text":"

Q. Is it possible to use my PC for the sound and without using the microphone, or any ADC pins on the board.

The sound reactive fork of WLED was designed as an all-in-one unit that doesn't require the intervention of a PC. You can setup a display and have it run completely independently. It supports your PC's analog line-out signal, several analog microphones, an INMP441 digital microphone, as well as UDP sound sync:

https://mm.kno.wled.ge/WLEDSR/UDP-Sound-Sync

To answer this question, there is not a direct, built in way, except for the line-out signal. Although we support UDP sound sync, someone would have to write a program for their OS of choice to capture the sound from the PC, perform FFT calculations, and UDP transmit the sampled data (the packet matching our sound reactive WLED data structure). That's a non-trivial course of action.

All that being said, there are a couple ways to achieve this:

For windows, there is WledSRServer (https://github.com/Victoare/SR-WLED-audio-server-win) which is a small application that is using the mentioned sound capture, FFT calculation and UDP packet sending mechanism.

There is also LedFx (as found at https://github.com/LedFx/LedFx) which is an another solution for this use case with a different approach. Since WLED supports UDP, DDP, and E1.31 DMX protocols, you can use the sound reactive LedFx running on your PC to control a WLED device. There's an excellent video on setting this environment up at https://www.youtube.com/watch?v=ipSfQdfX4fE.

LedFx will then directly control the LED's on your WLED device, although you can still revert to native WLED animations.

"},{"location":"WLEDSR/WLED-Programming-Notes/","title":"Introduction","text":"

This version of WLED contains sound reactive routines, which are prefaced with a * FX_NAME for volume reactive routines and ** FX_NAME for FFT routines. Each is controllable by the intensity and/or speed sliders. Some routines also include 3 dedicated FFT control sliders.

**Caveat: As our sound reactive fork of WLED evolves, some of this content may become out of date. We'll update as we become aware of any issues.

Contents:

Caveat: Some information on this page is in our 'dev' branch only and not yet ready for prime time.

"},{"location":"WLEDSR/WLED-Programming-Notes/#http-api-links","title":"HTTP API Links","text":"

I hope to work on an Android application in the future, so I'm keeping notes on the HTTP API. * https://tynick.com/blog/01-28-2020/controlling-wled-with-raspberry-pi-using-the-wled-api/ * https://github.com/Aircoookie/WLED/wiki/HTTP-request-API

"},{"location":"WLEDSR/WLED-Programming-Notes/#updating-fxh-line-numbers-will-vary","title":"Updating FX.h (line numbers will vary)","text":""},{"location":"WLEDSR/WLED-Programming-Notes/#updating-fxcpp","title":"Updating FX.cpp","text":"

Append the new function(s) and use current functions as templates. Cannot add any functions without accompanying index entry.

"},{"location":"WLEDSR/WLED-Programming-Notes/#wled-support-functions","title":"WLED Support Functions","text":""},{"location":"WLEDSR/WLED-Programming-Notes/#important-wled-variables","title":"Important WLED variables","text":""},{"location":"WLEDSR/WLED-Programming-Notes/#important-structures","title":"Important Structures","text":"