How to make delay() - custom wipe effect

Hello, I want to write a filter similar to wipe. But whose behavior will be something like this:

for ( int i = 0; i < SEGLEN; i++)
{
  SEGMENT.setPixelColor(index, WHITE);
  delay(x)
}
delay(10000)
for ( int i = SEGLEN; i > 0; i--)
{
  SEGMENT.setPixelColor(index, BLACK);
  delay(x)
}

I know delay is a bad solution, I just wrote this to make the example easier. I’m looking at the color_wipe sample code. but I can’t figure out how this delay is done. Additionally, I would like it to happen when the segment is turned on. It will be turned on for 10 seconds and then turned off in the for loop

how to use variables for this:

SEGMENT.speed
SEGMENT.intensity

to control the speed of the for loop (but not the middle pause). I would also like the animation to be as smooth as possible and the LEDs to light up gradually, as in the case of wipe

Will this solution be ok:

uint16_t delayTimeFor = 500
uint16_t delayTime = 10000

for ( int i = 0; i < SEGLEN; i++)
{
  SEGMENT.setPixelColor(index, WHITE);
  
  unsigned long startTime = millis();
  while (millis() - startTime < delayTimeFor) 
  {
  
  }

}

unsigned long startTime2 = millis();
while (millis() - startTime2 < delayTime) 
{

}

for ( int i = SEGLEN; i > 0; i--)
{
  SEGMENT.setPixelColor(index, BLACK);
  unsigned long startTime3 = millis();
  while (millis() - startTime3 < delayTimeFor) 
  {
  
  }
}

I would like to make something nicer based on the variables I wrote about above.
Additionally, can you explain to me what the characters after the effect name represent:

static const char _data_FX_MODE_COLOR_WIPE[] PROGMEM = "Wipe@!,!;!,!;!";

I noticed that it corresponds to the available functions in the web panel, but I can’t figure out which character corresponds to what

did <ou read the Modification and Coustom effect page
as of you used delay in your EXAMPLE i guess not
please refer to
https://kno.wled.ge/advanced/custom-features/

I’m not an expert, but I have written an effect.
The basic idea is that WLED will call your effect, and you look at the variables from the UI such as SEGMENT.speed, etc. and you are responsible for deciding what to do.

Concretely, this is done by remembering the last ‘time’ (typically in SEGENV.step) and comparing the current ‘time’, where ‘time’ is some function of strip.now, and then based on that, make any changes to the pixels accordingly, and return. It seems that usually all pixels are set on every call to the effect, which is probably a good idea, and might be necessary (but I haven’t confirmed).

There is no spinning in a loop waiting for a future time; you look at the time difference from last time the function was entered, do whatever, and return.
Its best to study some simple existing effect, like blink/strobe.

Did you read everything I wrote or just the first sentence? I know can’t use delay(), I even wrote below how I want to replace it - but it’s not a very nice solution

Thank you, you gave me some knowledge about wled variables

I did that and unfortunately it doesn’t work :frowning_face:

uint16_t stairs(void)
{
  uint32_t mainColor = SEGCOLOR(0);
  uint32_t secondColor = SEGCOLOR(1);

  uint32_t startTime = millis();
  uint16_t ledIndex = 0;
  uint16_t elapsedTime = 0;
  uint16_t waitTime = 1000;

  while (ledIndex < SEGLEN)
  {
    if (millis() - startTime >= waitTime)
    {
      SEGMENT.setPixelColor(ledIndex, mainColor);
      ledIndex++;
      startTime = millis();
    }
  }

  return FRAMETIME;
}

I guess I need to look into it more to understand what and why.

Why not just use wipe in a preset and a playlist?

Adjust the duration of the wipe preset in the playlist till it matches your desired time at whatever speed/intensity you had set. If you want them to stay ON after all LEDs are lit add a solid preset as your 2nd item in the playlist.

So, you need to (1) remember when you’ve finished the forward wipe, then (2) when you are called 10,000 milliseconds after that, you start again (3) with the led_index at the end of the segment and proceeding backwards. A simple way fof doing (3) is to generate led_index as before, and then map it to its reverse (SEGLEN - led_index). For (1), there are variables SEGENV.aux0 etc. for you to use.

It’s a pretty straightforward programming exercise. I think you are off to the right start; Good luck.

I program in C++, but in this project I feel like a child in a fog.

Based on color wipe, I managed to write an effect that turns on the LEDs in sequence. And unfortunately I can’t move on…

now I have written this (at the beginning I turn off the entire LED strip especially because the rest of the steps are missing):

uint16_t stairs(void)
{
  uint32_t mainColor = SEGCOLOR(0);
  uint32_t secondColor = SEGCOLOR(1);

  SEGMENT.fill(secondColor);

  uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150;
  uint32_t perc = strip.now % cycleTime;
  uint16_t prog = (perc * 65535) / cycleTime;
  uint16_t ledIndex = (prog * SEGLEN) >> 15;

  for (int i = 0; i < SEGLEN; i++)
  {
    if (i < ledIndex)
    {
      SEGMENT.setPixelColor(i, mainColor);
    }
  }

  return FRAMETIME;
}
static const char _data_FX_MODE_STAIRS[] PROGMEM = "Stairs@!,!;!,!;!";

what I’m missing is that after turning on the entire LED strip, it must be turned on for 10 seconds and turn off in the same way, LED after LED in the opposite direction

Savvy.
Thats what id do

1 Like