# Code to smoothly fade position between LEDs (I can't get my head around it)

I have a ring of 14 WS2812B LEDs (think NeoPixel ring, but DIY). I am trying to write code so that a single “glow” can be at any point of the ring and have a variable width, and the LED at the middle of the glow will be brighter than the ones each side of it. I’ve tried multiple things but I just can’t get one that works.

To add to this, 14 LEDs isn’t very much so I want to make sure that the centrepoint of the glow can be between LEDs so there’s never a sharp change as the glow moves slowly around the ring (the movement I’ll approach later).

Just to further explain - the output would be something like this…

 Glow centre 5th LED
0   0   0  64 128 255 128  64   0   0 . . .

Glow centre 5.5th LED
0   0   0  32  64 200 200  64  32   0 . . .


In addition, it must wrap smoothly between the last and the first LED.

In my (unsuccessful) code I’ve mostly tried having the glow centre expressed as a uint8_t between 0 and 255 in the hope that I can use the rollover between 255 and 0 to make things simpler.

I’ve tried a sine wave limited to one period by if statements, an approximated linear smoothing, and even polynomials, but they all have funky artifacts and/or don’t loop. For the purpose of working it out I’m working in floating points (I can optimise later).

So basically…any suggestions? Or previous work that might help (I have tried googling)?

rory-m: So basically....any suggestions? Or previous work that might help (I have tried googling)?

I suggest posting the code you have right now. Oftentimes OPs post only part of a bigger whole. A picture or drawing of your circuit would help to visualize the setup. Hand drawn is the fastest.

I've seen a similar effect with a function called colorWave, except that it's a rainbow. It uses a sinusoidal waveform. Also, have you looked at the code for cylonBounce? It uses a single color that passes up and down the strip.

so I want to make sure that the centrepoint of the glow can be between LEDs so there's never a sharp change as the glow moves slowly around the ring

So make the number of LEDs you are lighting up an odd number.

Have your centre LED the colour you want and the ones either side half the brightness and the ones either side of that a quarter as bright and so on until you have as many LEDs on as you want.

surveyranger:
I suggest posting the code you have right now.

With

uint8_t gW = 73; //width, 0 to 255 (255 is full circle). //73 is 4 leds
uint8_t gC = 50; //centre up to 255.


I’ve tried

  double calculatedBrightness;

for (uint8_t p = 0; p<14; p++) {

calculatedBrightness =    300.0 / ( pow(  (1.1 / w) * ( x - s )         ,2) + 1.0 )
+ 300.0 / ( pow(  (1.1 / w) * ( x - s ) +256.0  ,2) + 1.0 )
+ 300.0 / ( pow(  (1.1 / w) * ( x - s ) -256.0  ,2) + 1.0 );

//for reference, this is the equation in https://www.desmos.com/calculator/kreo2ssqj8
//    y=\frac{300}{\left(0.008w\left(x-s\right)\right)^2+1}+\frac{300}{\left(0.008w\left(\left(x-s\right)-512\right)\right)^2+1}+\frac{300}{\left(0.008w\left(\left(x-s\right)-256\right)\right)^2+1}-50

pixels.setPixelColor(p,pixels.gamma32(pixels.ColorHSV(gH, gS, int(calculatedBrightness))));

}


and

  for (uint8_t p = 0; p<14; p++) {
uint8_t proximity; //proximity of LED to centre
uint8_t pixelPos;
pixelPos = p * 255 / 14; //this is the absolute position of the pixel around the circle
proximity = min( gC-pixelPos, pixelPos-gC );
if ( proximity > (gW * 2 )) { //double the portion intended to be bright
//do nothing
} else if ( proximity < (gW / 2) ) { //the central half of the portion intended to be bright
pixels.setPixelColor(p,pixels.gamma32(pixels.ColorHSV(gH, gS, 255)));
} else  { //wider than the central half, narrower than double the width.
//i.e. gW/2 < proximity < gW *2
pixels.setPixelColor(p,pixels.gamma32(pixels.ColorHSV(gH, gS, 255-128 * proximity)));
}
}


And a sinusoidal one that I’d have to rewrite I think. surveyranger - thanks, I’ll check out your references.

Grumpy_Mike:
Have your centre LED the colour you want and the ones either side half the brightness and the ones either side of that a quarter as bright and so on until you have as many LEDs on as you want.

Thanks, but this doesn’t solve the problem of when I want to move the glow over by half an LED…

but this doesn't solve the problem of when I want to move the glow over by half an LED...

So what problem is this then?

Where did you read in the How to use this forum that it is a great idea to post snippets, in fact I recall it saying you should post all the code.

double - is exactly the same as float in Arduino land.

//for reference, this is the equation in https://www.desmos.com/calculator/kreo2ssqj8

It might be but what on earth has that calculation got to do with what you are trying to do.

I'm following the rules exactly by posting a snippet rather than the whole 350 lines of code.

I also tried to follow the rules by explaining what I'm trying to do and what I've tried in the first post; I don't think you really get what I'm trying to do as your suggestion wouldn't achieve it.

I'm trying to make sure that I can have the centre of the glow at (for example) the 5th pixel, or in between the 5th and 6th, or three quarters of the way to the 6th, and the total light output from all the LEDs will be equal each time. Kind-of like antialiasing.

The comment referencing the equation is to do with a route I took to [edit: try to] achieve that, if you plot that equation with y being brightness you would have seen what I meant. That comment was pasted from my code and was mostly for my benefit.

I also tried to follow the rules by explaining what I'm trying to do and what I've tried in the first post;

No you said:-

I am trying to write code so that a single "glow" can be at any point of the ring and have a variable width, and the LED at the middle of the glow will be brighter than the ones each side of it.

Nothing in there about anti aliasing or moving the center of the glow by a fractional pixel number.

I'm following the rules exactly by posting a snippet rather than the whole 350 lines of code.

Where does it say that? The only reference to the word snippet in the whole page said:-

Sometimes we can diagnose an issue with just a snippet of code, but more often than not, the complete code will reveal to us problems that can't be found with just a snippet. If you can't post the complete code, schematics, or other parts of your project (due to any number of issues), then you may find that we won't be of much help.

if you plot that equation with y being brightness you would have seen what I meant.

I can imagine the results of a polynomial being plotted for brightness and I can assure you that it makes no sens.

Grumpy Mike, I could easily have predicted that your reply would try to pick apart my message rather than actually trying to help with my initial question. I provided more information about what I was trying to do - why are you arguing with me about what I did or didn't say?

Arduino.cc should be a safe and forgiving environment for newbies to learn. I haven't been through all of your fifty-four thousand posts but in the ones I've read there is a pattern of you telling people they're posting wrong, offering terse solutions and replies without going into detail (which will leave newbies more confused), and picking peoples messages apart rather than trying to help them with their initial problems.

I don't think you realise the negative effect you have on people who are trying to learn and are asking for help. I know that I feel alienated and put off by your messages and I'm not coming back here because I might get argumentative and impatient replies again.

You're hurting this community. Have you thought about going somewhere like slashdot instead?

@rory-m: are you complaining about the free advice you're getting from a knowledgeable and experienced engineer?

I just want to be clear.

Grumpy Mike, I could easily have predicted that your reply would try to pick apart my message rather than actually trying to help with my initial question.

I did help with your initial question. It turns out you were not telling the full story but you pretended that you had supplied all the details. I pointed this out. Do you consider I should not point out things that are correct and those that are not?

I provided more information about what I was trying to do - why are you arguing with me about what I did or didn't say?

Because what you didn't say completely changes the question.

've read there is a pattern of you telling people they're posting wrong,

Yes not posting in code tags is a problem here. Most of the time a first timer is at worst told to read the instructions but from me he is always offered some sort of help.

offering terse solutions and replies without going into detail

What is wrong with terse? I am dyslexic and I have learned over the years to make words count and be precise things. It is something you have to do in engineering. I am aware that a few people find my style offensive, it is for them that I chose my online name.

People here are at all sorts of levels. A self description of a newbee can apply to someone who has had an Arduino for one day to one year, it is quite a spread. I consistently say that if you don't understand anything about my replies then please ask specifically about what you don't understand. It makes little sense launching into a full "first day with an Arduino" answer when you do not know the level they are at.

picking peoples messages apart rather than trying to help them with their initial problems.

Only by understanding their problems can you hope to be able to solve them. Most people have to be asked about specific aspects of their question before a full picture appears. This is because they are not skilled at asking questions in an unambiguous way. I get many response which say "I now realise I have not been clear with what I asked". Then we can get down to solving it.

I don't think you realise the negative effect you have on people who are trying to learn and are asking for help.

Well just glance over at my Kama count, people don't click on those for nothing.

You're hurting this community.

That is not an opinion that most people share.