kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.58k stars 343 forks source link

Changing position of the diode 0 #343

Closed chakjer closed 2 months ago

chakjer commented 8 months ago

Hi, I have 200 diodes in square room but 0 position is not in the corner. Is there a chance to shift the start diode left/right? I have tried to configure in 2 segments, but speed is different and effect is not continuously. I'm using WS2812FXT.

moose4lord commented 8 months ago

Issue #284 addresses a similar situation. You may be able to adapt the solution proposed there for use with WS2812FXT.

chakjer commented 8 months ago

Hi, Thx for hint. I tried to customShow for ws2812fxt.v1 and ws2812fxt.v2 but no transition effects but it is obvious. Next disabled in WS2812FXT in _show dest->Adafruit_NeoPixel::show(); and create function

void shiftLED(void)
{
  for (int i = 0; i < ws2812fx_p.getNumBytes(); i++)
  {
    ws2812fx_p.setPixelColor(i, ws2812fxt.dest->getPixelColor(ledMap[i]));
  }
  ws2812fx_p.Adafruit_NeoPixel::show();
}

and running after ws2812fxt.service(); but it doesn't work well. There is less brightness and effects are displayed twice, normal and shifted.

moose4lord commented 8 months ago

Hmmmm...I looked at this a little closer and it's not as easy as I first thought. There is no setCustomShow() function for the WS2812FXT class, so it's hard to replace the show() function with your own code. :(

All is not lost though, since we can write a custom service() function to accomplish the same thing. This is what I came up with using the ws2812fx_transitions example sketch as a base:

#include <WS2812FX.h>

#define LED_PIN 22
#define LED_COUNT 64
#define LED_OFFSET 20  // offset of the "first" LED 

// instantiate a ws2812fxt object to calc the transition animation and a
// ws2812fx object to do the LED offset translation and drive the LED strip
WS2812FXT ws2812fxt = WS2812FXT(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
WS2812FX  ws2812fx  = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// custom service() function to work around the lack of
// a setCustomShow() function in the WS2812FXT class
// (copied from the WS2812FXT class's service() and _show() functions)
void myService(void) {
  bool doShow = ws2812fxt.v1->service() || ws2812fxt.v2->service();
  if (doShow) {
    unsigned long now = millis();

    uint8_t *dest_p = ws2812fxt.dest->getPixels();
    uint8_t *vstart_p = ws2812fxt.transitionDirection ? ws2812fxt.v1->getPixels() : ws2812fxt.v2->getPixels();
    uint8_t *vstop_p = ws2812fxt.transitionDirection ? ws2812fxt.v2->getPixels() : ws2812fxt.v1->getPixels();
    uint16_t numBytes = ws2812fxt.dest->getNumBytes();

    if (now < ws2812fxt.transitionStartTime) {
      memmove(dest_p, vstart_p, numBytes);
    } else if (now > ws2812fxt.transitionStartTime + ws2812fxt.transitionDuration) {
      memmove(dest_p, vstop_p, numBytes);
    } else {
      uint8_t blendAmt = map(now, ws2812fxt.transitionStartTime, ws2812fxt.transitionStartTime + ws2812fxt.transitionDuration, 0, 255);
      ws2812fxt.dest->blend(dest_p, vstart_p, vstop_p, numBytes, blendAmt);
    }

    // copy the LED data from the ws2812fxt object to the ws2812fx object
    // (and do the LED offset translation)
    numBytes = ws2812fx.getNumBytes();
    uint16_t ledOffset = LED_OFFSET * ws2812fx.getNumBytesPerPixel();
    memmove(ws2812fx.getPixels() + ledOffset, ws2812fxt.dest->getPixels(), numBytes - ledOffset);
    memmove(ws2812fx.getPixels(), ws2812fxt.dest->getPixels() + numBytes - ledOffset, ledOffset);

    ws2812fx.Adafruit_NeoPixel::show();
  }
}

void setup() {
  ws2812fxt.init();
  ws2812fx.init();

  // setup the effects on the two virtual strips
  // note v1 and v2 are pointers, so you must use pointer syntax
  // (i.e. use ws2812fxt.v1->setMode(...), not ws2812fxt.v1.setMode(...))
  ws2812fxt.v1->setBrightness(32);
  ws2812fxt.v1->setSegment(0, 0, LED_COUNT - 1, FX_MODE_LARSON_SCANNER, BLUE, 4000);

  ws2812fxt.v2->setBrightness(32);
  ws2812fxt.v2->setSegment(0, 0, LED_COUNT - 1, FX_MODE_STATIC, GREEN, 1000);

  ws2812fxt.start();
  ws2812fx.start();
}

void loop() {
  myService();  // run the custom service() function

  // every ten seconds transition from v1 to v2 then back to v1
  static bool direction = true;
  static unsigned long timer = 10000;
  unsigned long now = millis();

  if (now > timer) {
    ws2812fxt.startTransition(5000, direction);  // transition duration = 5 seconds
    direction = !direction;                      // change the transition direction
    timer = now + 10000;                         // transition every ten seconds
  }
}
chakjer commented 8 months ago

Hi, It works, but there is some problem with effects. In my case leds are white. 1)FX_MODE_RAINBOW_CYCLE in both directions 2)FX_MODE_RUNNING_RANDOM, FX_MODE_MERRY_CHRISTMAS, FX_MODE_HALLOWEEN, FX_MODE_RUNNING_RANDOM2 in revers direction

It is not a problem for me i just disabled effect or direction but i want you let you know. Thx anyway for resolving problem.

moose4lord commented 8 months ago

That's odd. I tried the effects that were giving you a problem and they seem to work ok for me. If you paste a copy of the sketch that isn't working correctly for you, I can look into it further.

chakjer commented 8 months ago

Hi, My sketch esp32.zip

moose4lord commented 8 months ago

Yikes, there's a lot there. I don't use PlatformIO or PubSub, and don't have a development board with an SD card, so couldn't compile and run your sketch. If you can reproduce the issue you're seeing with my simpler example sketch, I'd be happy to look at it.

moose4lord commented 2 months ago

This issue seems stale, so I'm closing. Feel free to reopen if you think it needs more attention.