Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using segment runtime in custom mode #349

Closed
kaysond opened this issue Mar 12, 2024 · 4 comments
Closed

Using segment runtime in custom mode #349

kaysond opened this issue Mar 12, 2024 · 4 comments

Comments

@kaysond
Copy link

kaysond commented Mar 12, 2024

I'm trying to create a custom mode that is the same as breath, except it does it once as one color, then switches to another color, repeat. So my first attempt is to essentially copy mode_breathbut grab segment info from the public segment/runtime getters. Unfortunately, I get a static dim color, and no animation. It seems like counter_mode_step is getting reset by something, but I couldn't figure out what.

What am I doing wrong here? Or maybe there's an entirely better way entirely to do this? TIA.

bool alternate = false;

uint16_t alternating_breath(void)
{
  WS2812FX::Segment *seg = ws2812fx.getSegment();
  WS2812FX::Segment_runtime *seg_rt = ws2812fx.getSegmentRuntime();
  int lum = seg_rt->counter_mode_step;
  if (lum > 255)
    lum = 511 - lum; // lum = 15 -> 255 -> 15

  uint16_t delay;
  if (lum == 15)
    delay = 970; // 970 pause before each breath
  else if (lum <= 25)
    delay = 38; // 19
  else if (lum <= 50)
    delay = 36; // 18
  else if (lum <= 75)
    delay = 28; // 14
  else if (lum <= 100)
    delay = 20; // 10
  else if (lum <= 125)
    delay = 14; // 7
  else if (lum <= 150)
    delay = 11; // 5
  else
    delay = 10; // 4

  ws2812fx.setBrightness(lum);
  for (uint16_t i = seg->start; i < seg->stop; i++)
  {
    if (alternate)
      ws2812fx.setPixelColor(i, seg->colors[1]);
    else
      ws2812fx.setPixelColor(i, seg->colors[0]);
  }

  seg_rt->counter_mode_step += 2;
  if (seg_rt->counter_mode_step > (512 - 15))
  {
    seg_rt->counter_mode_step = 15;
    seg_rt->aux_param2 |= CYCLE;
  }
  return delay;
}
@moose4lord
Copy link
Collaborator

Hmmmm...I don't see where you're blending colors to create the fading effect in your code. Like this line in the WS2812FX::mode_breath(void) function:

uint32_t color =  color_blend(_seg->colors[1], _seg->colors[0], lum);

I would take a different tack. Instead of creating a custom effect, I think I'd use the isCycle() function to detect the end of the breath animation cycle and change color at that point in time. Like this:

void loop() {
  ws2812fx.service();

  if(ws2812fx.getMode() == FX_MODE_BREATH) {
    if(ws2812fx.isCycle()) {  // if end of breath cycle, change color
      uint32_t newColor = ws2812fx.color_wheel(ws2812fx.random8());  // some random color
      ws2812fx.setColor(newColor);
    }
  }
}

@kaysond
Copy link
Author

kaysond commented Mar 12, 2024

I don't see where you're blending colors

I was wondering why that was there... I thought its a one-color effect so I just set the one color and dimmed using setBrightness, assuming that color_blend effectively does the same thing if the second color is 0.

I think I'd use the isCycle()

I don't think that will quite work the way I want because it'll instantly swap between the two colors at the end of the cycle, right? Because there's the pause in breath. I want to make it fade to nothing before switching colors so there's no instant color switch.

@moose4lord
Copy link
Collaborator

One thing you can do if you want to fade to black is to turn on Gamma Correction. when you setup the segment. Gamma correction will skew dim colors dimmer and bright colors brighter. Very dIm colors will be black. It's a bit of a hack, but might give you want you want.

ws2812fx.setSegment(0,  0,  LED_COUNT - 1, FX_MODE_BREATH, RED, 1000, GAMMA);

Otherwise, I think you're right, you'll have to develop a custom effect.

@kaysond
Copy link
Author

kaysond commented Mar 14, 2024

So the gamma didn't work, but turns out my issue was that I didn't know you have to do both setCustomMode() and setMode(FX_MODE_CUSTOM). Now I've got it working!

@kaysond kaysond closed this as completed Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants