-
Notifications
You must be signed in to change notification settings - Fork 439
Update mapping.md - improve description of how LEDMAPs work, and how to use them #293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
1fcd34b
cdcb9f3
c532598
a7979b6
5a8ac3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ hide: | |
| # - toc | ||
| --- | ||
|
|
||
| WLED now has the ability to remap your LED strip programmatically. | ||
| WLED has the ability to remap your LED strip programmatically. | ||
|
|
||
| ### 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. | ||
|
|
@@ -24,6 +24,32 @@ Multiple maps are supported in the latest versions by using `ledmapx.json` where | |
|
|
||
| Use -1 in the map for gaps/blank/null LEDs. | ||
|
|
||
| The ledmap also allows defining the dimensions of a 2D matrix. | ||
|
gunjambi marked this conversation as resolved.
|
||
| In such case you do not need to set up 2D in settings. | ||
| By specifying the `width` and `height` fields, these dimensions are used as default matrix size when the ledmap is applied. | ||
|
|
||
| #### Mapping Requirements | ||
|
|
||
| Mapping is an advanced feature, and for the correct results the following requirements must be fulfilled: | ||
|
|
||
| * A same value must not appear multiple times in the mapping, except for -1. | ||
|
|
||
| Mapping works by reordering the physical LEDs. | ||
| When an effect is rendered, the effect sets colors of a LEDs. | ||
| For example, a rainbow effect might set first LED of the strip as Red, the second LED as Yellow and the third LED as Blue. | ||
| Let's denote these physical LEDS as `LED[0]`, `LED[1]` and `LED[2]`. | ||
| Mapping changes these indices to `LED[map[0]]`, `LED[map[1]]` and `LED[map[2]]`, and by setting a map of `[2, 1, 0]` we can reverse the order. | ||
| But if the mapping contained the same value multiple times, for example `map=[0, 0, 0]`, then the effect would set the | ||
| colors of the LEDs `LED[map[0]] = LED[0]`, `LED[map[1]] = LED[0]` and `LED[map[2]] = LED[0]`, i.e. we would be setting the value of `LED[0]` multiple times. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be nice, but unfortunately it does not work. Reason: ledmaps are many-to-1, so you can map 3 logical leds to the same physical led, or map 256 logical leds to a randomly picked 256 of 1024 physical leds . But you cannot send the same "logical" led pixel to multiple output pixels, if this is what you wanted to say. Your example
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My intention here was exactly that you cannot cannot map many-to-one. And the explanation is tries to explain that any logical led 1,2,3 all changes the physical led 0. One problem I suffered here is the lack of terminology. We all know what physical leds are, they are the physical leds on a strip. But what are the leds on the wled "canvas" the ones I can peek in UI? I avoided using "logical" as that is only used in code, and "virtual" is used for led grouping thing which is a separate feature. I feel I should draw a figure of the how the rendering pipelien works here, but I don't know the system well enough for it to be correct. My current understanding is:
Would this make it easier to understand and is this correct? This would have helped me, but I'm partial since I've already done the unhappy source code spelunking trying to fix my lights. The above pic is a draw.io diagram so feel free to edit it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gunjambi I like your idea with the figure 👍 a few ideas:
not sure all this extra info will make the drawing clearer - if this just add clutter, better to "keep it simple" Good point about terminology - I don't have a good solution for this, but maybe that's a good question to ask in our Discord sub-channel for documentation. Thanks for your effort 🥇 |
||
| In this case, the resulting color of the `LED[0]` will the last value set to it. | ||
|
|
||
|
Comment on lines
+35
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix grammar/capitalization errors in the core rule explanation. Several wording issues reduce clarity in a key section (e.g., Line 35 “A same value”, Line 38 “a LEDs”, Line 40 “LEDS”, Line 44 missing “be”). Suggested edit-* A same value must not appear multiple times in the mapping, except for -1.
+* The same value must not appear multiple times in the mapping, except for -1.
- Mapping works by reordering the physical LEDs.
- When an effect is rendered, the effect sets colors of a LEDs.
+ Mapping works by reordering the physical LEDs.
+ When an effect is rendered, the effect sets colors of the LEDs.
For example, a rainbow effect might set first LED of the strip as Red, the second LED as Yellow and the third LED as Blue.
- Let's denote these physical LEDS as `LED[0]`, `LED[1]` and `LED[2]`.
+ Let's denote these physical LEDs as `LED[0]`, `LED[1]` and `LED[2]`.
Mapping changes these indices to `LED[map[0]]`, `LED[map[1]]` and `LED[map[2]]`, and by setting a map of `[2, 1, 0]` we can reverse the order.
But if the mapping contained the same value multiple times, for example `map=[0, 0, 0]`, then the effect would set the
colors of the LEDs `LED[map[0]] = LED[0]`, `LED[map[1]] = LED[0]` and `LED[map[2]] = LED[0]`, i.e. we would be setting the value of `LED[0]` multiple times.
- In this case, the resulting color of the `LED[0]` will the last value set to it.
+ In this case, the resulting color of `LED[0]` will be the last value set to it.🤖 Prompt for AI Agents |
||
| * The ledmap should include a mapping for every physical led, that is to say, the length of the `map` array must be as long as the number of total LEDs in the system. | ||
|
|
||
| As described above, the mapping works by changing the LEDs from `LED[0], LED[1], LED[2]...` to `LED[map[0]], LED[map[1]], LED[map[2]]...`. | ||
| If the `map` array is shorter than the number of LEDs, the mapping is assumed to be `map[N] = N` for the missing elements. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now you contradict your previous (and incorrect) statement. This is the behaviour if ledmap is shorter than actual LEDs.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was intentional to first start with a strong statement. Every new user should set the whole mapping. |
||
| Note that the total number of LEDs in the system is the number of LEDs in the system, which may be larger than the product of the `width` and `height` fields. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs rewording. |
||
| Specifically if you use sacrificial leds, i.e. LEDs, that are not present in the mapping, you may need to add trailing `-1` elements to your `map`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sacrificial LEDs are not part of the ledmap. Sacrificial LEDs are part of a bus while ledmap belongs to a strip (WS2812FX class). Buses can overlap!!! See custom start indices.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know sacrificial leds are not part of the ledmap. That's why I wrote "sacrificial leds are not present in the mapping". Or is this a terminology question where sacrifical leds that are not in the beginning of a bus are called something else? Gaps? The thing is that I have a serpentine grid, and there is a special led between every column that is not part of the grid. What do I call it? If I had 48 separate busses, they would be sacrifical leds. But if I use ledmap they are something else?
Please expand on this? I'm missing how it's related to the mapping.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@gunjambi the point is, "sacrificial leds" should be part of the ledmap.json; you need to add them as a kind of "trailing strip" otherwise WLED cannot control them properly. So the ledmap should not end with "-1" for the sacrificial leds, but its better to append them. In your example, after the matrix map that skips sacrificial LEDs 5 and 11, append ",5, 11" as the last two positions. This allows to create an additional segment only for the sacrificial leds, and bring them to "black" in a controlled way. Edit: I did not test if you can create segments when a ledmap.json is active. In case it does not work (ledmap dimensions might force-override segment dimensions), then indeed you must set the trailing leds to
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think "sacrificial LEDs" is OK, because this term is already known to users. |
||
|
|
||
| ### 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. | ||
|
|
||
|
|
@@ -81,3 +107,23 @@ Note that if a `ledmap.json` file exists, the `2d-gaps.json` file will be ignore | |
| ``` | ||
|
|
||
|  | ||
|
|
||
| The following example demonstrates that when using sacrificial leds, you must include a mapping for all LEDs. | ||
|
|
||
| Here, we have a serpentine of LEDs in 5 columns and 3 rows, and a sacrifical led between each row (in positions 5 and 11). | ||
|
softhack007 marked this conversation as resolved.
Outdated
|
||
| Since the total number of LEDs in this system is 15 + 2 = 17, the `map` must also be 17 elements long. | ||
| We fill those elements with -1. | ||
|
|
||
| ```json | ||
| { | ||
| "map": [ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for nitpicking, but this example won't work with WLED 0.16, because the whitespace after https://github.com/wled/WLED/blob/787d8a7342a45d957eff0493d87c93fce247b46d/wled00/FX_fcn.cpp#L2012 To make it work, change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI: the new editor auto-formats ledmaps (and any other json file for that matter) when saving but not if a file is just uploaded.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DedeHai side-topic: does it mean that editing cfg.json or presets.json will automatically "pretty-format" the file? I think we can handle it in case of ledmap.json (did some tests in MM, found a simple solution), but pretty-printed cfg.json or presets.json might cause new problems with the parser. Also pretty-formatting will blow up the file size, and it might be too much for boards with small littleFS partitions.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only saw this now. it pretty prints in the editor but always saves as minified. |
||
| 0, 1, 2, 3, 4, | ||
| 10, 9, 8, 7, 6, | ||
| 12, 13, 14, 15, 16, | ||
|
|
||
| -1, -1 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| ], | ||
| "width": 5, | ||
| "height": 3 | ||
| } | ||
| ``` | ||
|
Comment on lines
+117
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Align with markdownlint MD046 code block style. Static analysis flags this new JSON example as fenced while MD046 expects indented style for this doc. 🧰 Tools🪛 markdownlint-cli2 (0.22.1)[warning] 117-117: Code block style (MD046, code-block-style) 🤖 Prompt for AI Agents
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@coderabbitai Please explain what needs to be changed - the example should still be shown in a "code example" style. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What MD046 is flagging
…which causes the linter to expect the "indented" style everywhere. The new JSON snippet uses fenced style ( What the "fix" would look likeConverting to indented style means replacing: with four-space-indented lines: Both render as a code block in the browser — the example would still look like a code example. However — this is a pre-existing inconsistencyThe document already has multiple fenced blocks (the serpentine example, the 4×3 grid, the ∞ shape — all use The most sensible resolution is one of:
Option 1 is the cleanest long-term fix and doesn't require touching any content. 🧠 Learnings used |
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai please suggest a possibly better wording instead of "programmatically"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@softhack007, here are a few alternatives, roughly from simplest to most descriptive:WLED has the ability to remap your LED strip in software.WLED has the ability to remap your LED strip via configuration.WLED has the ability to remap your LED strip using a mapping file.WLED has the ability to remap your LED strip without physical rewiring.WLED has the ability to remap your LED strip through software, without rewiring.My personal recommendation would be "without physical rewiring" — it immediately conveys the practical benefit to a hardware-oriented audience (no need to resolder or rearrange wires), and it doesn't assume any coding background. Alternatively, "using a mapping file" ties naturally to the very next paragraph that introduces
ledmap.json.🧠 Learnings used