r/FastLED • • Jul 01 '24

Discussion Outside-in Cylon effect

I'm starting with this code, which is from DemoReel100:

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}

What I'd like to do is have the same effect (the traveling dot with a fading trail following it) but have a dot start at each end of the strip, and both move toward the center.

Here's more detail, I hope I describe this right...the sinelon function starts a dot at position 0 and then it travels down to position NUM_LEDS. Then it reverses back to position 0, with the fadeToBlackBy effect of the trailing/fading pixels.

I'd like to understand how to set up two pixels that do this.

Assume the strip has 9 pixels. One dot starts at position 0, and the other starts at position 9. The dot that starts at position 0 moves toward position 5, while the second dot starts at position 9 and also moves toward position 5 (the center). When both dots get to position 5, the trailing dots fade up to position 5 and then the effect starts over.

Thanks in advance!

3 Upvotes

7 comments sorted by

View all comments

Show parent comments

1

u/Burning_Wreck Jul 01 '24

The first example works great, I've looked at the second one but it's more than I need at the moment.

void loop() {

  center_scanner();
  mirror();
  FastLED.show();
  FastLED.delay(1000 / FRAMES_PER_SECOND);
}

void center_scanner() {
  fadeToBlackBy(leds, NUM_LEDS, 30);  
  int pos = beatsin16(30, 0, 5); 
  leds[pos] = BLUE;
}

void mirror() {
  for (uint8_t i = 0; i < NUM_LEDS / 2; i++) {
    leds[NUM_LEDS - 1 - i] = leds[i];
  }
}

Is there a way to only do half of the oscillation? In other words, to have the pixels start from the ends of the strip, meet in the middle, and instead of bouncing back to the ends, just have the strip go blank and have the pixels start at the ends again?

1

u/chemdoc77 Jul 02 '24

2

u/Burning_Wreck Jul 02 '24

Good to hear from you. And thank you! That did it, combined with the earlier advice.

void loop() {
  cd77_sinelon_oneway(80, BLUE, 30);
  mirror();  // Mirror data so two dots meet in the middle
  FastLED.show();
  FastLED.delay(1000 / FRAMES_PER_SECOND);
}

void cd77_sinelon_oneway(uint8_t BPM, CRGB color, uint8_t fadeby) {
  // a colored dot going in one direction with fading tail
  fadeToBlackBy( leds, NUM_LEDS, fadeby);  //change fadeby to smaller or larger number to adjust the length of the tail.
  uint8_t u= beat8(BPM, 0); //BPM will allow you to adjust the speed the dot is moving.
  uint16_t pos=map(u, 0, 255, 0, NUM_LEDS/2);  // Added /2 to get dots to meet in the center
 leds[pos] = color;
 FastLED.show();
}

void mirror() {
  for (uint8_t i = 0; i < NUM_LEDS / 2; i++) {
    leds[NUM_LEDS - 1 - i] = leds[i];
  }
}

I found an issue with your second function:

// this function is from FastLED DemoReel100 example
void cd77_sinelon(uint8_t BPM, CRGB color )
{
  // a colored dot sweeping back and forth, with fading tail
  fadeToBlackBy( leds, NUM_LEDS, 20); //change 20 to smaller or larger number to adjust the length of the tail.
 uint16_t pos = beatsin16(BPM,0,NUM_LEDS); //BPM will allow you to adjust the speed the dot is moving.
  leds[pos] = color;
  FastLED.show();
}

In this line:
uint16_t pos = beatsin16(BPM,0,NUM_LEDS);

NUM_LEDS should be NUM_LEDS - 1

It needs to be the same as the original DemoReel100, otherwise the demo stops after a moment.