Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 96 additions & 22 deletions docs/advanced/mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,91 @@ hide:

WLED now has the ability to remap your LED strip programmatically.

### What is it?

# What is it?
This allows us to treat the WLED strip as if it is wired in any way - we can then use the mapping feature to address the strip in any order. This allows for matrix support, serpentine runs and such.

### How do we do it?
LED Maps replace and over-ride the older Gap system. **Note:** that if a `ledmap.json` file exists, the `2d-gaps.json` file will be ignored.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

over-ride => override (@coderabbitai please confirm)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@softhack007, confirmed. "Override" is the standard dictionary spelling — the hyphenated form "over-ride" is non-standard/archaic. The correction to override is appropriate here.


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:321-326
Timestamp: 2026-05-01T12:10:43.108Z
Learning: When documenting or advising about WLED licensing/distribution under EUPL-1.2, treat WLED build environment files such as platformio.ini and platformio_override.ini as part of the firmware source code: they are required to rebuild the firmware and must be shared with recipients when distributing a modified WLED build. In contrast, treat LittleFS runtime user data/config files (e.g., presets.json, cfg.json, ledmap.json, etc.) as runtime user data that are not subject to this source-code disclosure requirement. Ensure your documentation reflects this distinction consistently.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch FX_2Dfcn.cpp around line 21
curl -s "https://raw.githubusercontent.com/wled/WLED/49f653c621a859d1f0567d02d143b2e1a8eefab2/wled00/FX_2Dfcn.cpp" | head -60

echo "---SEPARATOR---"

# Fetch FX_fcn.cpp around line 2058
curl -s "https://raw.githubusercontent.com/wled/WLED/49f653c621a859d1f0567d02d143b2e1a8eefab2/wled00/FX_fcn.cpp" | awk 'NR>=2040 && NR<=2100'

Length of output: 5683


Let me also search for any references to 2d-gaps.json in the WLED codebase to verify if that file name is accurate.


🏁 Script executed:

#!/bin/bash
# Search for 2d-gaps.json in the WLED codebase via GitHub API
curl -s "https://api.github.com/search/code?q=2d-gaps+repo:wled/WLED" \
  -H "Accept: application/vnd.github.v3+json" | jq '.total_count, (.items[]? | {path: .path, name: .name})'

echo "---SEPARATOR---"

# Also check for any "gaps" related file loading logic
curl -s "https://raw.githubusercontent.com/wled/WLED/49f653c621a859d1f0567d02d143b2e1a8eefab2/wled00/FX_fcn.cpp" | grep -n -i "gap\|2d-gap" | head -30

Length of output: 90


@softhack007, after tracing through both source files, the statement is partially incorrect — specifically, the reference to 2d-gaps.json.

Findings

From FX_fcn.cpp (deserializeMap()):

The relevant logic is:

if (!isFile && n==0 && isMatrix) {
    // 2D panel support creates its own ledmap (on the fly) if a ledmap.json does not exist
    setUpMatrix();
    return false;
}
if (!isFile || ...) return false;

So the actual behavior is:

  • If ledmap.json (index 0, no suffix) does not exist and the device is in matrix mode → setUpMatrix() is called (panel-based mapping from UI/cfg.json)
  • If ledmap.json does exist → the file is loaded, and setUpMatrix() is skipped

From FX_2Dfcn.cpp (setUpMatrix()):

This function builds customMappingTable from the panel[] array (populated from UI configuration stored in cfg.json). There is no reference to any 2d-gaps.json file here or anywhere else.

GitHub code search for 2d-gaps in wled/WLED: returned zero results. The file 2d-gaps.json does not exist in the WLED codebase at all.

Summary of issues in the doc statement

Claim Verdict
"LED Maps replace and override the older Gap system" ✅ Directionally correct — ledmap.json takes precedence over setUpMatrix() (UI panel config)
"if a ledmap.json file exists, the 2d-gaps.json file will be ignored" 2d-gaps.json is a non-existent file name; the "Gap system" is actually the UI panel/matrix configuration (setUpMatrix()) stored in cfg.json

Suggested correction

The sentence should reference the actual "Gap" system — which is the 2D panel configuration set up via the UI (stored in cfg.json):

LED Maps replace and override the older Gap system. Note: If a ledmap.json file exists, any 2D panel/matrix configuration set up via the UI will be ignored and the LED map file will be used instead.


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:321-326
Timestamp: 2026-05-01T12:10:43.108Z
Learning: When documenting or advising about WLED licensing/distribution under EUPL-1.2, treat WLED build environment files such as platformio.ini and platformio_override.ini as part of the firmware source code: they are required to rebuild the firmware and must be shared with recipients when distributing a modified WLED build. In contrast, treat LittleFS runtime user data/config files (e.g., presets.json, cfg.json, ledmap.json, etc.) as runtime user data that are not subject to this source-code disclosure requirement. Ensure your documentation reflects this distinction consistently.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:304-310
Timestamp: 2026-05-01T12:15:59.568Z
Learning: In wled/WLED-Docs FAQ (docs/basics/faq.md), when softening definitive legal statements (e.g., "is not considered a derivative work"), prefer minimal hedge words like "generally" or "typically" rather than adding extra paragraphs or repeated legal disclaimers. The existing "Consult a Lawyer" admonition block at the top of the licensing section already covers the legal-advice caveat; do not duplicate it in-line.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:327-337
Timestamp: 2026-05-01T12:08:39.081Z
Learning: In WLED-Docs (wled/WLED-Docs), the FAQ under "Bundling WLED with custom hardware" is intentionally written as plain-language guidance for integrators, not as a legally precise document. Avoid suggesting overly exact legal language (e.g., "commit hash", "exact release tag") in this section; simple readable phrasing like "in the exact version you're shipping" is preferred by the maintainers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed with one correction: the file 2d-gaps.json is used when exiting in LittleFS. However it is applied together with the 2D panel configuration (order top/bottom or left/light, linear or serpentine).
If a ledmap.json (or ledmapx.json) is selected by the user, the complete 2D panel configuration is replaced by the layout described in the ledmap file.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@softhack007, thank you for the correction! I apologize for the confusion — my GitHub code search only scanned the C++ source files and didn't account for 2d-gaps.json being a runtime LittleFS file rather than a hardcoded source filename.

So to summarize the corrected understanding:

  • 2d-gaps.json does exist in LittleFS and is applied alongside the 2D panel configuration (top/bottom, left/right, linear/serpentine order)
  • Selecting a ledmap.json or ledmapX.json replaces the entire 2D panel configuration (including 2d-gaps.json) with the layout from the ledmap file

With that in mind, the original doc sentence is directionally correct. A slightly more precise revision might be:

LED Maps replace and override the older Gap system. Note: If a ledmap.json (or ledmapX.json) is selected, the complete 2D panel configuration — including any 2d-gaps.json — will be ignored and replaced by the layout described in the LED map file.


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:327-337
Timestamp: 2026-05-01T12:08:39.081Z
Learning: In WLED-Docs (wled/WLED-Docs), the FAQ under "Bundling WLED with custom hardware" is intentionally written as plain-language guidance for integrators, not as a legally precise document. Avoid suggesting overly exact legal language (e.g., "commit hash", "exact release tag") in this section; simple readable phrasing like "in the exact version you're shipping" is preferred by the maintainers.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:304-310
Timestamp: 2026-05-01T12:15:59.568Z
Learning: In wled/WLED-Docs FAQ (docs/basics/faq.md), when softening definitive legal statements (e.g., "is not considered a derivative work"), prefer minimal hedge words like "generally" or "typically" rather than adding extra paragraphs or repeated legal disclaimers. The existing "Consult a Lawyer" admonition block at the top of the licensing section already covers the legal-advice caveat; do not duplicate it in-line.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:321-326
Timestamp: 2026-05-01T12:10:43.108Z
Learning: When documenting or advising about WLED licensing/distribution under EUPL-1.2, treat WLED build environment files such as platformio.ini and platformio_override.ini as part of the firmware source code: they are required to rebuild the firmware and must be shared with recipients when distributing a modified WLED build. In contrast, treat LittleFS runtime user data/config files (e.g., presets.json, cfg.json, ledmap.json, etc.) as runtime user data that are not subject to this source-code disclosure requirement. Ensure your documentation reflects this distinction consistently.

Copy link
Copy Markdown
Member

@softhack007 softhack007 May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai please add a learning: WLED has an on-device filesystem (LittleFS). This filesystem stores user configuration files (cfg.json, presets.json), and optional user files in JSON format like 2d-gaps.json, ledmap.json, ledmapX.json - these files are not stored in the main WLED repo. The filesystem can also be used for small additional files like .gif animations (image effect), or for extra files served by the embedded webserver (like pixelforge.htm.gz).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@softhack007, noted and added to long-term memory!


🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:321-326
Timestamp: 2026-05-01T12:10:43.108Z
Learning: When documenting or advising about WLED licensing/distribution under EUPL-1.2, treat WLED build environment files such as platformio.ini and platformio_override.ini as part of the firmware source code: they are required to rebuild the firmware and must be shared with recipients when distributing a modified WLED build. In contrast, treat LittleFS runtime user data/config files (e.g., presets.json, cfg.json, ledmap.json, etc.) as runtime user data that are not subject to this source-code disclosure requirement. Ensure your documentation reflects this distinction consistently.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:327-337
Timestamp: 2026-05-01T12:08:39.081Z
Learning: In WLED-Docs (wled/WLED-Docs), the FAQ under "Bundling WLED with custom hardware" is intentionally written as plain-language guidance for integrators, not as a legally precise document. Avoid suggesting overly exact legal language (e.g., "commit hash", "exact release tag") in this section; simple readable phrasing like "in the exact version you're shipping" is preferred by the maintainers.

Learnt from: softhack007
Repo: wled/WLED-Docs PR: 310
File: docs/basics/faq.md:304-310
Timestamp: 2026-05-01T12:15:59.568Z
Learning: In wled/WLED-Docs FAQ (docs/basics/faq.md), when softening definitive legal statements (e.g., "is not considered a derivative work"), prefer minimal hedge words like "generally" or "typically" rather than adding extra paragraphs or repeated legal disclaimers. The existing "Consult a Lawyer" admonition block at the top of the licensing section already covers the legal-advice caveat; do not duplicate it in-line.



# How do we do it?


## Create config file

Navigate to the edit page for your WLED device by adding `/edit` to its address - for example, https://my-led-device.local/edit
Use this edit page to create a file called `ledmap.json`.
Use this edit page to create a file called `ledmap1.json`, where `1` is incremented for each map you load on your controller.

**Note:** If the filename is `ledmap.json`, the config file ***will not load***; the filename must end in a number even if there's only one config file.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is untrue. ledmap.json is a default ledmap, loaded at boot or when "Default" is selected.



`ledmap.json` file needs to be a JSON formatted file with the the key being "map" and the value being an array of numbers representing the new order of pixels. The _position_ of values in the array is the "natural" order of LEDs and the value entered is the new position.
## Formatting

`ledmap1.json` file needs to be a JSON-formatted file with the key being `"map"` and the value being an array of numbers `[0,1,2,3...]` representing the new order of pixels. The _position_ of values in the array is the "natural" order of LEDs, with the number being the electrical position of a given LED on the linear strand.

The ArduinoJSON library is *****extremely***** white-space sensitive.
If your `ledmap.json` file is not working, check for white-spaces where they should not be. The LED positions are zero-indexed.
The ArduinoJSON library is *****extremely***** whitespace sensitive.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please substitute "ArduinoJSON" with "JSON parsing". Things have changed and ArduinoJSON is no longer responsible for ledmap handling.

If your `ledmap1.json` file is not working, check for white-spaces where they should not be.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The best way is to minimize ledmap file and pass it through JSON parser 1st.


***Note:*** In the examples below, additional whitespace is added for readability; however, the examples may not work when copied and pasted directly due to this whitespace sensitivity.

LED positions are zero-indexed. If you have 20 LEDs, your LED "addresses" will start at 0 and end at 19, but they do not need to be entered in order or completely, as demonstrated below.


## Additional configurations

Multiple maps are supported in the latest versions by using `ledmap`_x_`.json`, where _x_ is a number. Maps can be selected in your cfg.json using `{"ledmap":x,`... where `x` corresponds to the number in the filename, or in the main settings UI below segments, where any customised names will also be used in the selection list, see below.


Multiple maps are supported in the latest versions by using `ledmapx.json` where x is a number. Maps can be selected in a preset using `{"ledmap":x,...`.
## Complicated maps

Use -1 in the map for gaps/blank/null LEDs.
LEDs can be mapped in the "map" array in any order, including out-of-order, allowing you to map custom and complex shapes using `-1` in the map for gaps/blank/null LEDs. In addition, not all LEDs in a segment need to be mapped in the map; you can leave out extra LEDs if they're not required.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 translates to 65535 but any number above actual LED count will provide similar result - placeholder for skipped LED.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for sake of "keep it simple", I think we can still tell users that "-1" is the best way.


### Examples
In the below example (formatted multiple ways), we remap a strip of four LEDs from a physical order of 0 1 2 3 into a new order of 0 2 1 3.

{"map":[0,2,1,3]}
# Examples

{"map":[
0,2,1,3
]}

{"map":[
0,2,
1,3
]}
## Formatting options for `"map"`

In the examples below (formatted multiple ways), we remap a strip of four LEDs from a physical order of 0 1 2 3 into a new order of 0 2 1 3.


### Single line
```json
{"map":[0,2,1,3]}
```


### Multi-line object, single line array
```json
{"map":[
0,2,1,3
]}
```


### Multi-line array, helpful in visualising 2D matrices
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2D ledmap requires "width" and "height" keys. If omitted, the resulting ledmap is 1D and WLED will refuse to provide 2D support. Please include that info if you are suggesting to split lines for 2D.

```json
{"map":[
0,2,
1,3
]}
```


## 1D reordering example

This is another example that switches direction every 5 LEDs.
It could be formatted any of the three ways demonstrated above.
It could be formatted in any of the three ways demonstrated above.

```json
{"map":[0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14,
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]}
```

The following example shows how to create a `ledmap.json` for LEDs arranged in a two-dimensional grid intead of a one-dimensional string.

## 2D Matrix reordering

The following example shows how to create a `ledmap1.json` for LEDs arranged in a two-dimensional grid instead of a one-dimensional string. Notice the addition of the `width` and `height` keys and how they correspond to how the map array itself is formatted. This isn't required, but it is helpful to do.

Here, we have a serpentine of LEDs in 4 columns and 3 rows:
```json
Expand All @@ -64,8 +108,18 @@ Here, we have a serpentine of LEDs in 4 columns and 3 rows:

![wiring diagram of the 4x3 mapping](mapping/mapping_4x3.png)

A more complex example of 16 LEDs arrange in a double figure `∞` shape. This includes some missing LEDs showing up as `-1`.
Note that if a `ledmap.json` file exists, the `2d-gaps.json` file will be ignored.
A basic matrix map like the one above can also be quickly configured in the UI as a Gap, but if you need more control, this is a good starting point. As noted above, if an `ledmap.json` file exists, the `2d-gaps.json` file will be ignored.

Also, while we've written it here as a multi-line array with the same number of lines as the height and the same number of entries per line as the width, you could still format it as a single-line file, as below; they are functionally the same.

```json
{"map":[0,1,2,3,7,6,5,4,8,9,10,11],"width": 4,"height":3}
```


## Mapping complex shapes using -1's for spacing

A more complex example of 16 LEDs arranged in a double figure `∞` shape. This includes some empty space represented as `-1`.
```json
{"map":
[
Expand All @@ -81,3 +135,23 @@ Note that if a `ledmap.json` file exists, the `2d-gaps.json` file will be ignore
```

![wiring diagram of the double ∞ shape mapping](mapping/mapping_infinity_shape.png)


## Naming your maps for easier use

In addition, you can name your map configs in the UI by adding an "n" key to the config.

```json
{"n": "Double infinity map.",
"map":
[
-1, -1, 14, -1, 12, -1, 10, -1, -1,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the preceding lines there was a warning about spaces and in this example, there are plenty of spaces present. Please avoid contradicting information.

-1, 15, -1, 13, -1, 11, -1, 9, -1,
0, -1, -1, -1, -1, -1, -1, -1, 8,
-1, 1, -1, 3, -1, 5, -1, 7, -1,
-1, -1, 2, -1, 4, -1, 6, -1, -1
],
"width": 9,
"height": 5
}
```