Skip to content

Commit 2544d2e

Browse files
committed
Dynamic LED map creation from JSON file /ledmap.json in format {"map":[4,3,2,1,...]}.
Used for rearranging LEDs (matrices, awkward placement, ...)
1 parent f7114fc commit 2544d2e

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

wled00/FX_fcn.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,50 @@
2828
#include "palettes.h"
2929

3030
//enable custom per-LED mapping. This can allow for better effects on matrices or special displays
31-
//#define WLED_CUSTOM_LED_MAPPING
32-
33-
#ifdef WLED_CUSTOM_LED_MAPPING
31+
/*
3432
//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs.
3533
const uint16_t customMappingTable[] = {
3634
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
3735
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29};
3836
3937
//another example. Switches direction every 5 LEDs.
40-
/*const uint16_t customMappingTable[] = {
38+
const uint16_t customMappingTable[] = {
4139
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};*/
40+
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};
4341
4442
const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example
45-
#endif
43+
*/
44+
uint16_t* customMappingTable = nullptr;
45+
uint16_t customMappingSize = 0;
4646

4747
#ifndef PWM_INDEX
4848
#define PWM_INDEX 0
4949
#endif
5050

51+
void WS2812FX::deserializeMap(void) {
52+
DynamicJsonDocument doc(JSON_BUFFER_SIZE); // full sized buffer for larger maps
53+
54+
DEBUG_PRINTLN(F("Reading LED map from /ledmap.json..."));
55+
56+
if (!readObjectFromFile("/ledmap.json", nullptr, &doc)) return; //if file does not exist just exit
57+
58+
if (customMappingTable != nullptr) {
59+
delete[] customMappingTable;
60+
customMappingTable = nullptr;
61+
customMappingSize = 0;
62+
}
63+
64+
JsonArray map = doc[F("map")];
65+
if (!map.isNull() && map.size()) { // not an empty map
66+
customMappingSize = map.size();
67+
customMappingTable = new uint16_t[customMappingSize];
68+
for (uint16_t i=0; i<customMappingSize; i++) {
69+
customMappingTable[i] = (uint16_t) map[i];
70+
}
71+
}
72+
}
73+
74+
5175
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
5276
{
5377
if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return;
@@ -63,6 +87,8 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
6387
_lengthRaw += LED_SKIP_AMOUNT;
6488
}
6589

90+
deserializeMap();
91+
6692
bus->Begin((NeoPixelType)ty, _lengthRaw);
6793

6894
_segments[0].start = 0;
@@ -189,9 +215,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
189215
int16_t indexSet = realIndex + (reversed ? -j : j);
190216
int16_t indexSetRev = indexSet;
191217
if (reverseMode) indexSetRev = REV(indexSet);
192-
#ifdef WLED_CUSTOM_LED_MAPPING
193218
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
194-
#endif
195219
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) {
196220
bus->SetPixelColor(indexSet + skip, col);
197221
if (IS_MIRROR) { //set the corresponding mirrored pixel
@@ -205,9 +229,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
205229
}
206230
} else { //live data, etc.
207231
if (reverseMode) i = REV(i);
208-
#ifdef WLED_CUSTOM_LED_MAPPING
209232
if (i < customMappingSize) i = customMappingTable[i];
210-
#endif
211233
bus->SetPixelColor(i + skip, col);
212234
}
213235
if (skip && i == 0) {
@@ -482,9 +504,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
482504
{
483505
i = realPixelIndex(i);
484506

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

489509
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
490510

0 commit comments

Comments
 (0)