Algorythm for neopixel sequence

Hi,

Am strugling to re-create an algorithm fora neopixel sequence similar to this one:
SequenceWithShades1

As I am strugling since a few days on it, I am asking if someone help with a fresh new idea for the structure of the "for" loops that needs to be stacked in.

Please share your tought. Thanks.

P

Please share your entire sketch. Don't forget to use code tags.

Also, don't rely only on a graphic to explain the sequence. Please put it in words also.

Explain what "stacking" means in the context of 'for' loops and why you think you need it.

You said, "similar to...". Then how different may it be?

If you use 'for' loops your pattern display will be blocking and nothing much else will get done.

Can you describe in words how you want the LEDs to behave?

Do you need 7 LEDs? The basic Arduino UNO/Nano only has 6 PWM (fading) outputs (3, 5, 6, 9, 10 and 11). Nevermind. Neopixels only need one pin.

Hi John, Thank for helping.

Here is a clearer explantion in text of the sequence to reproduce the effect of a slow left to right movement of 3 leds on an array of 7 sevens RGBW leds, using only the White from 0 to 255 in x steps (Number of steps and delay will be adjusted later).
first led slowly light on, and when at around 50% the next led starts increasing. and the previous start decreasing.

Hopefully it is easier to undersatnd this way.

Thank-you.

P.

I get the idea, but it can be interpreted variously. Please draw a timing diagram. For an example, show the brightness of 3 LEDs from 0% to 100% on the vertical axis, time on the horizontal. Because, it's not clear about the desired phase relationship.

Does it "wrap around", i.e. circular behaviour? Have you considered the non-linear effect of LED gamma?

Hi aarg,

Yes you are right, I think doing this table will help. Let me come back with it, it makes me ask myslef the right questions.

As per the non-linear effect of LED gamma? For now I didn't taught about it, but you are certainly right I should consider it. Adafruit has a Gamma correction table, Is it a good way of solving this issue ?

Thanks.

P

Hi here a table as a starting point. I undersatnd that every % has to be converted due to gamma effect. Let's say that in the table it is the "visible" percentage.

Movement is one way,up to down (led 0 to 6) and again.

Thanks.

P.

Just draw it once statically on the strip. Then with one call every time through loopjust shift the bits over by one. Copy one end, shift them all over by one, stuff the saved one on the beginning end. Done

This is how the Dragon fire was done.

-jim lee

Thank you, that is an excellent way to present it. Another really feasible idea that comes from this, is to embed the values in the table into a 2 dimensional array in the code. Then you just cycle through the rows, setting each LED to the value in the table. I see now that is rephrasing what was said by @jimLee above. Except, without bit shifting.

Secondly, you can do it algorithmically. Several steps are involved, but each value is no more than the result of the mathematical principle that you used to construct your table. You are constructing a model - look for commonalities... hey, the brightness profiles are all the same, only difference is the time offset. Well there is something you can work with mathematically. They're also linear, hint hint.

The visual effect of brightness will not be uniform (i.e. as linear as expected) as you may expect from the raw percentage illumination values in your table. I'm referring to gamma compensation. I used it and it made a huge improvement. But you can try and see.

Sorry, you asked about the Adafruit gamma compensation, but I'm not familiar with it. I use an optimized low level method that would just confuse the discussion now.

Actually, I cheat a little. I use colorObj for NeoPixels, TFTs, OLEDs, RGB LEDs etc. colorObj can be blended with other colors, like black, to make other or darker colors. etc. Also, this supplies color mappers as well. like map() functions for color.

Here's an example.

-jim lee

uint8_t led[7] = {0};   // brightness
int8_t change_flag[8] = {0};
change_flag[0] = 10;
led[0] = 10;

while(1) {
 for (i=0; i< 7; i++) {
  if (led[i] ) led[i] += change_flag[i];
  if ((led[i] == 50) && change_flag[i] > 0) 
       change_flag[i+1] = 10;
  if (led[i] == 100) change_flag[i] = -10;
}
  delay(50);
}

  
  

Hi @anon57585045, @jimLee and @b707,

Thanks for helping. I went with the solution of creation a 2D array (7x34) with the values and this short loop.

  while(1) {
    for (int t = 0 ; t < 34; t++){
      for (int i=0; i < 7; i++) {
        int gamma = pgm_read_byte(&gamma8[percent[i][t]]);
        strip.setPixelColor(curve1[i], 0,0,0, gamma ); //Using RGBW leds
      }
      strip.show();
      delay(200);
    }
  }

I could have put the gamma values in the array to simplify. For now, I work on the other parts of the project and I may optimize my code later.

Il will probably start two new topics regadring the Gamma corrections, and storing a 2D array with PROGMEM. Lets discuss soon.

Thank-you.

P.

That may not be really necessary, since it's for the same project. The normal forum protocol is to continue such topics in the same thread.

Most gamma correction uses exponentiation. Inverse gamma (i.e. correction) raises the input data to a power, for example, monitor gamma is usually 2.2. The idea I clicked to, is that 2.0 is close to 2.2, and if precise gamma is not required (for colour matching for example) then you can use the power 2.0 but that is a mathematical square. So I exploit the native integer multiplication on many processors (or accept the "pretty fast" inline code) to simply multiply the input byte by itself, and then scale it down to a byte again.

So in C it looks like

byte inputValue;
...
byte gammaCorrectedValue = (uint16_t)inputValue * inputValue / 256;

It's orders of magnitude faster than calling float routines.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.