From 030833f94223f84701e4bfdcd147a7ab70f424e5 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Thu, 25 Aug 2022 21:57:43 +0200 Subject: [PATCH] Global MISO pin. Virtual strip expansion for 2D. --- wled00/FX.cpp | 89 +-- wled00/FX.h | 9 +- wled00/FX_fcn.cpp | 50 +- wled00/cfg.cpp | 7 +- wled00/const.h | 6 + wled00/data/index.js | 2 +- wled00/html_ui.h | 1568 +++++++++++++++++++++--------------------- wled00/set.cpp | 12 +- wled00/wled.h | 3 +- wled00/xml.cpp | 1 + 10 files changed, 895 insertions(+), 852 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index b9754697..4c08b9f3 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2796,59 +2796,68 @@ typedef struct Ball { */ uint16_t mode_bouncing_balls(void) { //allocate segment data - uint16_t maxNumBalls = 16; + const uint16_t strips = SEGMENT.map1D2D == M12_pBar ? SEGMENT.nrOfVStrips() : 1; + const size_t maxNumBalls = 16; uint16_t dataSize = sizeof(ball) * maxNumBalls; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed Ball* balls = reinterpret_cast(SEGENV.data); - - // number of balls based on intensity setting to max of 7 (cycles colors) - // non-chosen color is a random color - uint16_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1); - - float gravity = -9.81; // standard value of gravity - float impactVelocityStart = sqrt( -2 * gravity); - unsigned long time = millis(); + SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1)); - if (SEGENV.call == 0) { - for (size_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = time; - } - - bool hasCol2 = SEGCOLOR(2); - SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); - - for (size_t i = 0; i < numBalls; i++) { - float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-SEGMENT.speed)*8/256 +1); - float timeSec = timeSinceLastBounce/1000.0f; - balls[i].height = 0.5 * gravity * (timeSec * timeSec) + balls[i].impactVelocity * timeSec; // avoid use pow(x, 2) - its extremely slow ! + // virtualStrip idea by @ewowi (Ewoud Wijma) + struct virtualStrip { + static void runStrip(size_t stripNr, Ball* balls) { + // number of balls based on intensity setting to max of 7 (cycles colors) + // non-chosen color is a random color + uint16_t numBalls = (SEGMENT.intensity * (maxNumBalls - 1)) / 255 + 1; // minimum 1 ball + const float gravity = -9.81; // standard value of gravity + const bool hasCol2 = SEGCOLOR(2); + const unsigned long time = millis(); - if (balls[i].height < 0) { //start bounce - balls[i].height = 0; - //damping for better effect using multiple balls - float dampening = 0.90 - 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 (SEGENV.call == 0) { + for (size_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = time; + } + + for (size_t i = 0; i < numBalls; i++) { + float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-SEGMENT.speed)/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].impactVelocity < 0.015) { - balls[i].impactVelocity = impactVelocityStart; + 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 = sqrt(-2 * 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 * (SEGLEN - 1)); + SEGMENT.setPixelColor(pos | int((stripNr+1)<<16), color); // encode virtual strip into index } } - - 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); - } + }; - uint16_t pos = roundf(balls[i].height * (SEGLEN - 1)); - SEGMENT.setPixelColor(pos, color); - } + for (int stripNr=0; stripNr>16; // hack to allow running on virtual strips (2D segment columns/rows) + i &= 0xFFFF; + if (i >= virtualLength() || i<0) return; // if pixel would fall out of segment just exit #ifndef WLED_DISABLE_2D @@ -444,16 +457,17 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) // use all available pixels as a long strip setPixelColorXY(i % vW, i / vW, col); break; - case M12_VerticalBar: - // expand 1D effect vertically - for (int y = 0; y < vH; y++) setPixelColorXY(i, y, col); + case M12_pBar: + // expand 1D effect vertically or have it play on virtual strips + if (vStrip>0) setPixelColorXY(vStrip - 1, vH - i - 1, col); + else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col); break; - case M12_Circle: + case M12_pArc: // expand in circular fashion from center if (i==0) setPixelColorXY(0, 0, col); else { - float step = HALF_PI / (2.5f*i); + float step = HALF_PI / (2.85f*i); for (float rad = 0.0f; rad <= HALF_PI+step/2; rad += step) { // may want to try float version as well (with or without antialiasing) int x = roundf(sin_t(rad) * i); @@ -462,7 +476,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) } } break; - case M12_Block: + case M12_pCorner: for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col); for (int y = 0; y < i; y++) setPixelColorXY(i, y, col); break; @@ -547,8 +561,11 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) } } -uint32_t Segment::getPixelColor(uint16_t i) +uint32_t Segment::getPixelColor(int i) { + uint8_t vStrip = i>>16; + i &= 0xFFFF; + #ifndef WLED_DISABLE_2D if (is2D()) { // if this does not work use strip.isMatrix uint16_t vH = virtualHeight(); // segment height in logical pixels @@ -557,11 +574,12 @@ uint32_t Segment::getPixelColor(uint16_t i) case M12_Pixels: return getPixelColorXY(i % vW, i / vW); break; - case M12_VerticalBar: - return getPixelColorXY(i, 0); + case M12_pBar: + if (vStrip>0) return getPixelColorXY(vStrip - 1, vH - i -1); + else return getPixelColorXY(0, vH - i -1); break; - case M12_Circle: - case M12_Block: + case M12_pArc: + case M12_pCorner: // use longest dimension return vW>vH ? getPixelColorXY(i, 0) : getPixelColorXY(0, i); break; diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 6ee4a191..d1ec845b 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -283,11 +283,13 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonArray hw_if_spi = hw[F("if")][F("spi-pin")]; CJSON(spi_mosi, hw_if_spi[0]); CJSON(spi_sclk, hw_if_spi[1]); - PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_sclk, true } }; - if (spi_mosi >= 0 && spi_sclk >= 0 && pinManager.allocateMultiplePins(spi, 2, PinOwner::HW_SPI)) { + CJSON(spi_miso, hw_if_spi[2]); + PinManagerPinType spi[3] = { { spi_mosi, true }, { spi_miso, true }, { spi_sclk, true } }; + if (spi_mosi >= 0 && spi_sclk >= 0 && pinManager.allocateMultiplePins(spi, 3, PinOwner::HW_SPI)) { // do not initialise bus here } else { spi_mosi = -1; + spi_miso = -1; spi_sclk = -1; } @@ -746,6 +748,7 @@ void serializeConfig() { JsonArray hw_if_spi = hw_if.createNestedArray("spi-pin"); hw_if_spi.add(spi_mosi); hw_if_spi.add(spi_sclk); + hw_if_spi.add(spi_miso); //JsonObject hw_status = hw.createNestedObject("status"); //hw_status["pin"] = -1; diff --git a/wled00/const.h b/wled00/const.h index d3953cd8..377e7b35 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -384,6 +384,9 @@ #if defined(ESP8266) && defined(HW_PIN_DATASPI) #undef HW_PIN_DATASPI #endif +#if defined(ESP8266) && defined(HW_PIN_MISOSPI) + #undef HW_PIN_MISOSPI +#endif #if defined(ESP8266) && defined(HW_PIN_CSSPI) #undef HW_PIN_CSSPI #endif @@ -394,6 +397,9 @@ #ifndef HW_PIN_DATASPI #define HW_PIN_DATASPI MOSI #endif +#ifndef HW_PIN_MISOSPI + #define HW_PIN_MISOSPI MISO +#endif #ifndef HW_PIN_CSSPI #define HW_PIN_CSSPI SS #endif diff --git a/wled00/data/index.js b/wled00/data/index.js index 949dd4af..d9e3c3c6 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -714,7 +714,7 @@ function populateSegments(s) } let map2D = `
Expand 1D FX