From 58394fefdd72138315c62de95a9ca70746ad3708 Mon Sep 17 00:00:00 2001 From: Ewoud Date: Fri, 11 Aug 2023 21:45:02 +0200 Subject: [PATCH] FastLed dynamic ! multi pin allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AppEffects: - move call++ and gHue ++ from AppModLeds to effect loop - all effects loops call superclass loop - Ripples3DEffect: use interval parameter - add credentials - BouncingBalls1D (WIP) AppLedsV: - remove NUM_LEDS_FastLed (now dynamic 🎉) - rename LedsV::ledsP to LedsV::ledsPhysical (to distinguish between global ledsP (which is a pointer to LedsV::ledsPhysical) AppModLedFixGen - add pinList variable (csv of pins) - generateChFun: pinList csv to array of pins - generateChFun: use pinList to generate pin numbers in ledfix.json AppModLeds: - remove DATA_PIN (now dynamic 🎉) - remove dataPin variable - add BouncingBalls effect - move FastLed.addLeds from setup to loop.doMap - doMap: for all Leds pins, decode startLed and nrOfLeds and call FastLED.addLeds for each pin (dynamic pin allocation!). --- src/App/AppEffects.h | 116 +++++++++++++++++++++++++++++++++++++- src/App/AppLedsV.cpp | 11 ++-- src/App/AppLedsV.h | 8 +-- src/App/AppModLedFixGen.h | 56 +++++++++++------- src/App/AppModLeds.h | 102 ++++++++++++++++++++++++++------- 5 files changed, 241 insertions(+), 52 deletions(-) diff --git a/src/App/AppEffects.h b/src/App/AppEffects.h index bb98a61c..2fb28f6b 100644 --- a/src/App/AppEffects.h +++ b/src/App/AppEffects.h @@ -15,8 +15,16 @@ static unsigned long call = 0; class Effect { public: virtual const char * name() { return nullptr;} + virtual void setup() {} - virtual void loop() {} + + virtual void loop() { + call++; + + // do some periodic updates + EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow + } + virtual bool controls(JsonObject parentVar) {return false;} }; @@ -27,6 +35,7 @@ class RainbowEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // FastLED's built-in rainbow generator fill_rainbow( ledsP, LedsV::nrOfLedsP, gHue, 7); } @@ -39,6 +48,7 @@ class RainbowWithGlitterEffect:public RainbowEffect { } void setup() {} void loop() { + Effect::loop(); // built-in FastLED rainbow, plus some random sparkly glitter RainbowEffect::loop(); addGlitter(80); @@ -58,6 +68,7 @@ class SinelonEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 20); int pos = beatsin16( 13, 0, LedsV::nrOfLedsV-1 ); @@ -74,6 +85,7 @@ class RunningEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 70); //physical leds // int pos0 = (call-1)%ledsV.nrOfLeds; @@ -90,6 +102,7 @@ class ConfettiEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // random colored speckles that blink in and fade smoothly fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 10); int pos = random16(LedsV::nrOfLedsP); @@ -104,6 +117,7 @@ class BPMEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; @@ -124,6 +138,7 @@ class JuggleEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); // eight colored dots, weaving in and out of sync with each other fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 20); uint8_t dothue = 0; @@ -141,7 +156,10 @@ class Ripples3DEffect: public Effect { } void setup() {} void loop() { - float ripple_interval = 1.3;// * (SEGMENT.intensity/128.0); + Effect::loop(); + uint8_t interval = mdl->getValue("interval"); + + float ripple_interval = 1.3 * (interval/128.0); fill_solid(ledsP, LedsV::nrOfLedsP, CRGB::Black); // fill(CRGB::Black); @@ -159,6 +177,10 @@ class Ripples3DEffect: public Effect { } } } + bool controls(JsonObject parentVar) { + ui->initSlider(parentVar, "interval", 128, false); + return true; + } }; class SphereMove3DEffect: public Effect { @@ -168,6 +190,7 @@ class SphereMove3DEffect: public Effect { } void setup() {} void loop() { + Effect::loop(); uint16_t origin_x, origin_y, origin_z, d; float diameter; @@ -206,6 +229,7 @@ uint16_t XY( uint8_t x, uint8_t y) { return x + y * LedsV::widthV; } +//Frizzles2D inspired by WLED, Stepko, Andrew Tuline, https://editor.soulmatelights.com/gallery/640-color-frizzles class Frizzles2D: public Effect { public: const char * name() { @@ -217,6 +241,7 @@ class Frizzles2D: public Effect { } void loop() { + Effect::loop(); fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 16); CRGBPalette16 palette = PartyColors_p; @@ -245,6 +270,7 @@ class Lines2D: public Effect { void setup() {} void loop() { + Effect::loop(); fadeToBlackBy( ledsP, LedsV::nrOfLedsP, 100); CRGBPalette16 palette = PartyColors_p; @@ -271,6 +297,7 @@ uint8_t gamma8(uint8_t b) { //we do nothing with gamma for now return b; } +//DistortionWaves2D inspired by WLED, ldirko, https://editor.soulmatelights.com/gallery/1089-distorsion-waves class DistortionWaves2D: public Effect { public: const char * name() { @@ -282,6 +309,7 @@ class DistortionWaves2D: public Effect { } void loop() { + Effect::loop(); const uint16_t cols = LedsV::widthV; const uint16_t rows = LedsV::widthV; @@ -331,7 +359,89 @@ class DistortionWaves2D: public Effect { ui->initSlider(parentVar, "scale", 128, false); return true; } -}; // Frizzles2D +}; // DistortionWaves2D + + +//BouncingBalls1D inspired by WLED +//each needs 12 bytes +typedef struct Ball { + unsigned long lastBounceTime; + float impactVelocity; + float height; +} ball; + +#define maxNumBalls 16 + +class BouncingBalls1D: public Effect { +public: + Ball balls[maxNumBalls]; + + const char * name() { + return "Bouncing Balls 1D"; + } + + void setup() { + for (size_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = millis(); + } + + void loop() { + Effect::loop(); + + uint8_t grav = mdl->getValue("gravity"); + uint8_t nrOfBalls = mdl->getValue("nrOfBalls"); + + // number of balls based on intensity setting to max of 7 (cycles colors) + // non-chosen color is a random color + uint16_t numBalls = (grav * (maxNumBalls - 1)) / 255 + 1; // minimum 1 ball + const float gravity = -9.81f; // standard value of gravity + // const bool hasCol2 = SEGCOLOR(2); + const unsigned long time = millis(); + + for (size_t i = 0; i < numBalls; i++) { + float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-grav)/64 +1); + float timeSec = timeSinceLastBounce/1000.0f; + balls[i].height = (0.5f * gravity * timeSec + balls[i].impactVelocity) * timeSec; // avoid use pow(x, 2) - its extremely slow ! + + if (balls[i].height <= 0.0f) { + balls[i].height = 0.0f; + //damping for better effect using multiple balls + float dampening = 0.9f - float(i)/float(numBalls * numBalls); // avoid use pow(x, 2) - its extremely slow ! + balls[i].impactVelocity = dampening * balls[i].impactVelocity; + balls[i].lastBounceTime = time; + + if (balls[i].impactVelocity < 0.015f) { + float impactVelocityStart = sqrtf(-2.0f * gravity) * random8(5,11)/10.0f; // randomize impact velocity + balls[i].impactVelocity = impactVelocityStart; + } + } else if (balls[i].height > 1.0f) { + continue; // do not draw OOB ball + } + + // uint32_t color = SEGCOLOR(0); + // if (SEGMENT.palette) { + // color = SEGMENT.color_wheel(i*(256/MAX(numBalls, 8))); + // } + // else if (hasCol2) { + // color = SEGCOLOR(i % NUM_COLORS); + // } + int pos = roundf(balls[i].height * (LedsV::nrOfLedsV - 1)); + + CRGBPalette16 palette = PartyColors_p; + + CRGB color = ColorFromPalette(palette, i*(256/max(numBalls, (uint16_t)8)), 255); + + ledsV[pos] = color; + // if (SEGLEN<32) SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index + // else SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color); + } //nrOfBalls + } + + bool controls(JsonObject parentVar) { + ui->initSlider(parentVar, "gravity", 128, false); + ui->initSlider(parentVar, "nrOfBalls", 128, false); + return true; + } +}; // DistortionWaves2D static std::vector effects; \ No newline at end of file diff --git a/src/App/AppLedsV.cpp b/src/App/AppLedsV.cpp index 7f0fb288..e17b20af 100644 --- a/src/App/AppLedsV.cpp +++ b/src/App/AppLedsV.cpp @@ -144,12 +144,11 @@ void LedsV::ledFixProjectAndMap() { } //if 1D-3D else { char details[32] = ""; - print->fFormat(details, sizeof(details), "%d-%d", prevLeds, mappingTableLedCounter - 1); + print->fFormat(details, sizeof(details), "%d-%d", prevLeds, mappingTableLedCounter - 1); //careful: AppModLeds:loop uses this to assign to FastLed print->print("pins %d: %s (%d)\n", currPin, details); pins->allocatePin(currPin, "Leds", details); prevLeds = mappingTableLedCounter; - } }); //create the right type, otherwise crash @@ -215,11 +214,11 @@ void LedsV::setPixelColor(int indexV, CRGB color) { if (indexV >= mappingTable.size()) return; for (uint16_t indexP:mappingTable[indexV]) { if (indexP < NUM_LEDS_Preview) - ledsP[indexP] = color; + ledsPhysical[indexP] = color; } } else //no projection - ledsP[projectionNr==p_Random?random(nrOfLedsP):indexV] = color; + ledsPhysical[projectionNr==p_Random?random(nrOfLedsP):indexV] = color; } CRGB LedsV::getPixelColor(int indexV) { @@ -227,10 +226,10 @@ CRGB LedsV::getPixelColor(int indexV) { if (indexV >= mappingTable.size()) return CRGB::Black; if (!mappingTable[indexV].size() || mappingTable[indexV][0] > NUM_LEDS_Preview) return CRGB::Black; - return ledsP[mappingTable[indexV][0]]; //any would do as they are all the same + return ledsPhysical[mappingTable[indexV][0]]; //any would do as they are all the same } else //no projection - return ledsP[indexV]; + return ledsPhysical[indexV]; } // LedsV& operator+=(const CRGB color) { diff --git a/src/App/AppLedsV.h b/src/App/AppLedsV.h index 264bef58..926f1e53 100644 --- a/src/App/AppLedsV.h +++ b/src/App/AppLedsV.h @@ -12,7 +12,6 @@ #include #include "ArduinoJson.h" -#define NUM_LEDS_FastLed 1024 #define NUM_LEDS_Preview 4096 //keep them global for the time being as FastLed effects refer to them and want to keep that code as unchanged as possible @@ -34,7 +33,7 @@ class LedsV { public: // CRGB *leds = nullptr; - CRGB ledsP[NUM_LEDS_Preview]; + CRGB ledsPhysical[NUM_LEDS_Preview]; // if (!leds) // leds = (CRGB*)calloc(nrOfLeds, sizeof(CRGB)); // else @@ -60,7 +59,7 @@ class LedsV { void ledFixProjectAndMap(); - uint16_t indexVLocal = 0; + uint16_t indexVLocal = 0; //set in operator[], used by operator= // ledsV[indexV] stores indexV locally LedsV& operator[](uint16_t indexV); @@ -100,6 +99,7 @@ class LedsV { static uint16_t mappingTableLedCounter; }; +//Global vars! //after header split they all needs to be static otherwise multiple definition link error static LedsV ledsV = LedsV(); //virtual leds -static CRGB *ledsP = ledsV.ledsP; //physical leds, used by FastLed in particular \ No newline at end of file +static CRGB *ledsP = ledsV.ledsPhysical; //physical leds, used by FastLed in particular diff --git a/src/App/AppModLedFixGen.h b/src/App/AppModLedFixGen.h index 9618f307..9cbd30cf 100644 --- a/src/App/AppModLedFixGen.h +++ b/src/App/AppModLedFixGen.h @@ -117,16 +117,16 @@ class AppModLedFixGen:public Module { select.add("3DCube"); //7 select.add("3DGlobe"); //8 }, [](JsonObject var) { //chFun - ledFixGenChFun(var); }); //ledFixGen + ui->initText(parentVar, "pinList", "16", false, [](JsonObject var) { //uiFun + web->addResponse(var["id"], "comment", "One or more e.g. 12,13"); + }); + ui->initButton(parentVar, "generate", nullptr, false, [](JsonObject var) { //uiFun - // web->addResponse(var["id"], "comment", "All but model.json"); }, [](JsonObject var) { - generateChFun(var); - }); print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); @@ -212,8 +212,26 @@ class AppModLedFixGen:public Module { char sep[3]=""; char sep2[3]=""; - uint8_t pin = 10; + uint8_t pinList[9] = {255,255,255,255,255,255,255,255,255}; + uint8_t sizeOfPins = 0; + if (!mdl->getValue("pinList").isNull()) { + print->print( "pinlist %s\n",mdl->getValue("pinList").as()); + char str[32]; + strcpy(str, mdl->getValue("pinList").as()); + const char s[2] = ","; + char *token; + /* get the first token */ + token = strtok(str, s); + /* walk through other tokens */ + while( token != NULL ) + { + print->print( " %s(%d) %d\n", token, atoi(token), sizeOfPins ); + pinList[sizeOfPins++] = atoi(token); + token = strtok(NULL, s); + } + } + uint8_t pinNr = 0; float ringDiam; GenFix genFix; @@ -227,7 +245,7 @@ class AppModLedFixGen:public Module { genFix.writeHeader(); - genFix.writef(",\"outputs\":[{\"pin\":10,\"leds\":["); + genFix.writef(",\"outputs\":[{\"pin\":%d,\"leds\":[", pinList[(pinNr++)%sizeOfPins]); strcpy(sep, ""); for (int i=0; igetValue("in2out"); @@ -324,28 +342,28 @@ class AppModLedFixGen:public Module { strcpy(sep,""); //first pin (red) - genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pin++);strcpy(sep, ","); + genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pinList[(pinNr++)%sizeOfPins]);strcpy(sep, ","); strcpy(sep2,""); y = 15; for (int x = 53; x >= 0; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 11; for (int x = 9; x <= 51; x++) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 7; for (int x = 40; x >= 11; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} genFix.writef("]}"); //second pin (green) - genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pin++);strcpy(sep, ","); + genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pinList[(pinNr++)%sizeOfPins]);strcpy(sep, ","); strcpy(sep2,""); y = 14; for (int x = 53; x >= 0; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 10; for (int x = 9; x <= 51; x++) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 6; for (int x = 39; x >= 12; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} genFix.writef("]}"); //third pin (blue) - genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pin++);strcpy(sep, ","); + genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pinList[(pinNr++)%sizeOfPins]);strcpy(sep, ","); strcpy(sep2,""); y = 13; for (int x = 52; x >= 1; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 9; for (int x = 10; x <= 50; x++) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 5; for (int x = 39; x >= 14; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} genFix.writef("]}"); //fourth pin (yellow) - genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pin++);strcpy(sep, ","); + genFix.writef("%s{\"pin\":%d,\"leds\":[", sep, pinList[(pinNr++)%sizeOfPins]);strcpy(sep, ","); strcpy(sep2,""); y = 12; for (int x = 52; x >= 3; x--) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} y = 8; for (int x = 10; x <= 48; x++) {genFix.writef("%s[%d,%d]", sep2, x,y); strcpy(sep2, ",");} @@ -371,7 +389,7 @@ class AppModLedFixGen:public Module { genFix.writeName("3DCone%02d", nrOfRings); genFix.writeHeader(); - genFix.writef(",\"outputs\":[{\"pin\":10,\"leds\":["); + genFix.writef(",\"outputs\":[{\"pin\":%d,\"leds\":[", pinList[(pinNr++)%sizeOfPins]); strcpy(sep, ""); in2out = mdl->getValue("in2out"); @@ -405,7 +423,7 @@ class AppModLedFixGen:public Module { //front and back for (uint8_t z = 0; z #include "FastLED.h" -#define DATA_PIN 16 - //https://github.com/FastLED/FastLED/blob/master/examples/DemoReel100/DemoReel100.ino //https://blog.ja-ke.tech/2019/06/02/neopixel-performance.html @@ -29,7 +27,7 @@ class AppModLeds:public Module { public: unsigned long frameMillis = 0; unsigned long frameCounter = 0; - bool newFrame = false; + bool newFrame = false; //for other modules (DDP) //need to make these static as they are called in lambda functions static uint16_t fps; @@ -171,7 +169,7 @@ class AppModLeds:public Module { char details[32] = ""; print->fFormat(details, sizeof(details), "P:%d V:%d", LedsV::nrOfLedsP, LedsV::nrOfLedsV); web->addResponse(var["id"], "value", details); - web->addResponseV(var["id"], "comment", "Max %d (%d by FastLed)", NUM_LEDS_Preview, NUM_LEDS_FastLed); + web->addResponseV(var["id"], "comment", "Max %d", NUM_LEDS_Preview); }); ui->initNumber(parentVar, "fps", fps, false, [](JsonObject var) { //uiFun @@ -185,12 +183,6 @@ class AppModLeds:public Module { web->addResponse(var["id"], "comment", "Depends on how much leds fastled has configured"); }); - ui->initNumber(parentVar, "dataPin", DATA_PIN, false, [](JsonObject var) { //uiFun - web->addResponseV(var["id"], "comment", "Not implemented yet (fixed to %d)", DATA_PIN); - }, [](JsonObject var) { //chFun - print->print("Set data pin to %d\n", var["value"].as()); - }); - effects.push_back(new RainbowEffect); effects.push_back(new RainbowWithGlitterEffect); effects.push_back(new SinelonEffect); @@ -203,9 +195,7 @@ class AppModLeds:public Module { effects.push_back(new Frizzles2D); effects.push_back(new Lines2D); effects.push_back(new DistortionWaves2D); - - // FastLED.addLeds(leds, 1); - FastLED.addLeds(ledsP, NUM_LEDS_FastLed); + effects.push_back(new BouncingBalls1D); #ifdef USERMOD_E131 e131mod->addWatch(1, "bri", 256); @@ -218,6 +208,7 @@ class AppModLeds:public Module { void loop() { // Module::loop(); + //set new frame if (millis() - frameMillis >= 1000.0/fps) { frameMillis = millis(); @@ -226,30 +217,101 @@ class AppModLeds:public Module { Effect* effect = effects[mdl->getValue("fx")]; effect->loop(); - // yield(); FastLED.show(); frameCounter++; - call++; } else { newFrame = false; } + + //update ui if (millis() - secondMillis >= 1000) { secondMillis = millis(); mdl->setValueV("realFps", "%lu /s", frameCounter); frameCounter = 0; } - if (millis() - lastMappingMillis >= 1000 && doMap) { //not more then once per second (for E131) + //update projection + if (millis() - lastMappingMillis >= 1000 && doMap) { //not more then once per second (for E131) lastMappingMillis = millis(); doMap = false; ledsV.ledFixProjectAndMap(); - } - // do some periodic updates - EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow - } + uint8_t pinNr=0; + for (PinObject pinObject:SysModPins::pinObjects) { + if (strcmp(pinObject.owner, "Leds")== 0) { + //dirty trick to decode nrOfLedsPerPin + char * after = strtok((char *)pinObject.details, "-"); + if (after != NULL ) { + char * before; + before = after; + after = strtok(NULL, " "); + uint16_t nrOfLeds = atoi(after) - atoi(before) + 1; + uint16_t startLed = atoi(before); + print->print("FastLED.addLeds new %d: %d-%d\n", pinNr, startLed, nrOfLeds); + + //commented pins: error: static assertion failed: Invalid pin specified + switch (pinNr) { + case 0: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 1: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 2: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 3: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 4: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 5: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 6: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 7: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 8: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 9: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 10: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 11: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 12: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 13: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 14: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 15: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 16: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 17: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 18: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 19: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 20: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 21: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 22: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 23: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 24: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 25: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 26: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 27: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 28: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 29: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 30: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 31: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 32: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + case 33: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 34: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 35: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 36: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 37: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 38: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 39: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 40: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 41: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 42: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 43: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 44: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 45: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 46: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 47: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 48: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 49: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + // case 50: FastLED.addLeds(ledsP, startLed, nrOfLeds); break; + default: print->print("FastLedPin assignment: pin not supported %d\n", pinNr); + } + } + } + pinNr++; + } + } + } //loop };