Skip to content

Commit d56ab6c

Browse files
authored
Merge pull request wled#1738 from blazoncek/dynamic-led-map
Dynamic LED map creation from JSON file
2 parents f7114fc + 2f7be34 commit d56ab6c

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

wled00/FX.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
Modified for WLED
2525
*/
2626

27+
#include "wled.h"
28+
2729
#ifndef WS2812FX_h
2830
#define WS2812FX_h
2931

@@ -847,7 +849,11 @@ class WS2812FX {
847849

848850
void
849851
blendPixelColor(uint16_t n, uint32_t color, uint8_t blend),
850-
startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot);
852+
startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot),
853+
deserializeMap(void);
854+
855+
uint16_t* customMappingTable = nullptr;
856+
uint16_t customMappingSize = 0;
851857

852858
uint32_t _lastPaletteChange = 0;
853859
uint32_t _lastShow = 0;

wled00/FX_fcn.cpp

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,25 @@
2727
#include "FX.h"
2828
#include "palettes.h"
2929

30-
//enable custom per-LED mapping. This can allow for better effects on matrices or special displays
31-
//#define WLED_CUSTOM_LED_MAPPING
30+
#ifndef PWM_INDEX
31+
#define PWM_INDEX 0
32+
#endif
3233

33-
#ifdef WLED_CUSTOM_LED_MAPPING
34-
//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs.
35-
const uint16_t customMappingTable[] = {
36-
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
37-
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29};
34+
/*
35+
Custom per-LED mapping has moved!
3836
39-
//another example. Switches direction every 5 LEDs.
40-
/*const uint16_t customMappingTable[] = {
41-
0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14,
42-
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};*/
37+
Create a file "ledmap.json" using the edit page.
4338
44-
const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example
45-
#endif
39+
this is just an example (30 LEDs). It will first set all even, then all uneven LEDs.
40+
{"map":[
41+
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
42+
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]}
4643
47-
#ifndef PWM_INDEX
48-
#define PWM_INDEX 0
49-
#endif
44+
another example. Switches direction every 5 LEDs.
45+
{"map":[
46+
0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14,
47+
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]
48+
*/
5049

5150
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
5251
{
@@ -63,6 +62,8 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
6362
_lengthRaw += LED_SKIP_AMOUNT;
6463
}
6564

65+
deserializeMap();
66+
6667
bus->Begin((NeoPixelType)ty, _lengthRaw);
6768

6869
_segments[0].start = 0;
@@ -189,9 +190,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
189190
int16_t indexSet = realIndex + (reversed ? -j : j);
190191
int16_t indexSetRev = indexSet;
191192
if (reverseMode) indexSetRev = REV(indexSet);
192-
#ifdef WLED_CUSTOM_LED_MAPPING
193193
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
194-
#endif
195194
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) {
196195
bus->SetPixelColor(indexSet + skip, col);
197196
if (IS_MIRROR) { //set the corresponding mirrored pixel
@@ -205,9 +204,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
205204
}
206205
} else { //live data, etc.
207206
if (reverseMode) i = REV(i);
208-
#ifdef WLED_CUSTOM_LED_MAPPING
209207
if (i < customMappingSize) i = customMappingTable[i];
210-
#endif
211208
bus->SetPixelColor(i + skip, col);
212209
}
213210
if (skip && i == 0) {
@@ -482,9 +479,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
482479
{
483480
i = realPixelIndex(i);
484481

485-
#ifdef WLED_CUSTOM_LED_MAPPING
486482
if (i < customMappingSize) i = customMappingTable[i];
487-
#endif
488483

489484
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
490485

@@ -1006,6 +1001,31 @@ void WS2812FX::setRgbwPwm(void) {
10061001
void WS2812FX::setRgbwPwm() {}
10071002
#endif
10081003

1004+
//load custom mapping table from JSON file
1005+
void WS2812FX::deserializeMap(void) {
1006+
if (!WLED_FS.exists("/ledmap.json")) return;
1007+
DynamicJsonDocument doc(JSON_BUFFER_SIZE); // full sized buffer for larger maps
1008+
1009+
DEBUG_PRINTLN(F("Reading LED map from /ledmap.json..."));
1010+
1011+
if (!readObjectFromFile("/ledmap.json", nullptr, &doc)) return; //if file does not exist just exit
1012+
1013+
if (customMappingTable != nullptr) {
1014+
delete[] customMappingTable;
1015+
customMappingTable = nullptr;
1016+
customMappingSize = 0;
1017+
}
1018+
1019+
JsonArray map = doc[F("map")];
1020+
if (!map.isNull() && map.size()) { // not an empty map
1021+
customMappingSize = map.size();
1022+
customMappingTable = new uint16_t[customMappingSize];
1023+
for (uint16_t i=0; i<customMappingSize; i++) {
1024+
customMappingTable[i] = (uint16_t) map[i];
1025+
}
1026+
}
1027+
}
1028+
10091029
//gamma 2.8 lookup table used for color correction
10101030
byte gammaT[] = {
10111031
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0 commit comments

Comments
 (0)