diff --git a/wled00/FX.h b/wled00/FX.h index 44c57d07..589a7005 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -24,6 +24,8 @@ Modified for WLED */ +#include "wled.h" + #ifndef WS2812FX_h #define WS2812FX_h @@ -847,7 +849,11 @@ class WS2812FX { void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend), - startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot); + startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot), + deserializeMap(void); + + uint16_t* customMappingTable = nullptr; + uint16_t customMappingSize = 0; uint32_t _lastPaletteChange = 0; uint32_t _lastShow = 0; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 8c1681a3..aef500ce 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -27,27 +27,26 @@ #include "FX.h" #include "palettes.h" -//enable custom per-LED mapping. This can allow for better effects on matrices or special displays -//#define WLED_CUSTOM_LED_MAPPING - -#ifdef WLED_CUSTOM_LED_MAPPING -//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs. -const uint16_t customMappingTable[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, - 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}; - -//another example. Switches direction every 5 LEDs. -/*const uint16_t customMappingTable[] = { - 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};*/ - -const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example -#endif - #ifndef PWM_INDEX #define PWM_INDEX 0 #endif +/* + Custom per-LED mapping has moved! + + Create a file "ledmap.json" using the edit page. + + this is just an example (30 LEDs). It will first set all even, then all uneven LEDs. + {"map":[ + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]} + + another example. Switches direction every 5 LEDs. + {"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] +*/ + void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return; @@ -63,6 +62,8 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) _lengthRaw += LED_SKIP_AMOUNT; } + deserializeMap(); + bus->Begin((NeoPixelType)ty, _lengthRaw); _segments[0].start = 0; @@ -189,9 +190,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) int16_t indexSet = realIndex + (reversed ? -j : j); int16_t indexSetRev = indexSet; if (reverseMode) indexSetRev = REV(indexSet); - #ifdef WLED_CUSTOM_LED_MAPPING if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; - #endif if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) { bus->SetPixelColor(indexSet + skip, col); 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) } } else { //live data, etc. if (reverseMode) i = REV(i); - #ifdef WLED_CUSTOM_LED_MAPPING if (i < customMappingSize) i = customMappingTable[i]; - #endif bus->SetPixelColor(i + skip, col); } if (skip && i == 0) { @@ -482,9 +479,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) { i = realPixelIndex(i); - #ifdef WLED_CUSTOM_LED_MAPPING if (i < customMappingSize) i = customMappingTable[i]; - #endif if (_skipFirstMode) i += LED_SKIP_AMOUNT; @@ -1006,6 +1001,31 @@ void WS2812FX::setRgbwPwm(void) { void WS2812FX::setRgbwPwm() {} #endif +//load custom mapping table from JSON file +void WS2812FX::deserializeMap(void) { + if (!WLED_FS.exists("/ledmap.json")) return; + DynamicJsonDocument doc(JSON_BUFFER_SIZE); // full sized buffer for larger maps + + DEBUG_PRINTLN(F("Reading LED map from /ledmap.json...")); + + if (!readObjectFromFile("/ledmap.json", nullptr, &doc)) return; //if file does not exist just exit + + if (customMappingTable != nullptr) { + delete[] customMappingTable; + customMappingTable = nullptr; + customMappingSize = 0; + } + + JsonArray map = doc[F("map")]; + if (!map.isNull() && map.size()) { // not an empty map + customMappingSize = map.size(); + customMappingTable = new uint16_t[customMappingSize]; + for (uint16_t i=0; i