I'm after help adapting some code to run in a circular pattern.

gplus
(Danny Evans) #1

I’m after help adapting some code to run in a circular pattern.

I’m keen to get this wonderful sketch( https://gist.github.com/kriegsman/964de772d64c502760e5) from Mark Kriegsman adapted so that when a light strip is arranged in a circle the tail of the pattern will match the start, so there is a constant flowing circle of colours without a harsh break/start point.

I hope I’ve made it clear what I’m trying to achieve. Any help would be much appreciated.

(JP Roy) #2

Here’s a small function that I actually used to produce exactly that effect on a clock I built back in 2014.
See the following link for a video of the function at work (around 30 seconds into the video)…

There are probably more efficient ways of doing this but this definitely works 100%. I hope it gives you some ideas…
void rainbow (){

 for(int i = 419; i >= 0; i--) {                       // The number of LEDs on the clock section to have a circular seamless rainbow
  int val = i;                                         // Start with 419, count down to 0 to produce a clockwise rainbow motion
  for (int led = 0; led < NUM_LEDS; led++) {           // Write a different hue value to each of the 555 leds (Including the pendulum section)
      val = val++ % 420;                               // Step up the val for each subsequent led but maintains it within a range of 0-419
      byte hue = map (val, 0, 419, 0, 255);            // Maps the val to a range of 0-255 that is used by the CHSV function of the FastLED library
      leds[led] = CHSV(hue, 255, LED_MAX_BRIGHTNESS);  // 2nd parameter is the 'Saturation'; 255 => full saturation
  }
  FastLED.show();
}

}

(Jeremy Spencer) #3

The easiest is this
void rainbow()
{
fill_rainbow( LedsLeft, NUM_LEDS, gHue ++, (255/NUM_LEDS));
FastLED.delay(20);
}

It gives an effect like this https://goo.gl/photos/hg8NZfMHmQQBf5XP9

(Jeremy Spencer) #4

And to actually answer your question, if you add
nblend( leds[0],leds[NUM_LEDS-1],64);
at the very end of the pride function, it smooths the transition from the first to last led and keeps the circle intact.

(Jeremy Spencer) #5

Playing with it a little more, if you declare hue8 as a global variable rather an a local one, and move the extra nblend function so that it immediately follows the original one, it looks better

(Jeremy Spencer) #6

And for my final attempt at this…

Declare these variables

uint8_t hue8;
uint8_t sat8;
uint8_t brightdepth;
uint16_t brightnessthetainc16;
uint8_t msmultiplier;

uint16_t hue16;
uint16_t hueinc16;
uint16_t ms;
uint16_t deltams;
uint16_t brightnesstheta16;
uint16_t b16;
uint16_t bri16;
uint8_t bri8;

And use this loop

void pride()
{
static uint16_t sPseudotime = 0;
static uint16_t sLastMillis = 0;
static uint16_t sHue16 = 0;

sat8 = beatsin88( 87, 220, 250);
brightdepth = beatsin88( 341, 96, 224);
brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
msmultiplier = beatsin88(147, 23, 60);

hue16 = sHue16;//gHue * 256;
hueinc16 = beatsin88(113, 1, 3000);

ms = millis();
deltams = ms - sLastMillis ;
sLastMillis = ms;
sPseudotime += deltams * msmultiplier;
sHue16 += deltams * beatsin88( 400, 5, 9);
brightnesstheta16 = sPseudotime;

for ( uint16_t i = 0 ; i < NUM_LEDS; i++) {
hue16 += hueinc16;
hue8 = hue16 / 256;

brightnesstheta16  += brightnessthetainc16;
b16 = sin16( brightnesstheta16  ) + 32768;

bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
bri8 += (255 - brightdepth);

CRGB newcolor = CHSV( hue8, sat8, bri8);

uint16_t pixelnumber = i;
pixelnumber = (NUM_LEDS - 1) - pixelnumber;
nblend( leds[pixelnumber], newcolor, 64);
nblend( leds[0], leds[NUM_LEDS - 1], 64);

}
}

(Danny Evans) #7

Thank you so much. I’ll give it a go and report back.