I would not use sin as it’s not easy to use.and I suspect processor intensive . but , maths wise ….
The sin function goes from 0-1 ,for 0-180deg (pi/2 for Arduino ) so you have a multiplier in front of it, say 255 to give 0-255 .
Y= 255sin(X)
But you want to go 20 to 255 so…
Y= 20+ 235sin(X) is the function you want , translating to non blocking is next … millis()?
Or to hell with it and ask google and modify output if need by scaling it using MAP Example
And @mancera1979's version in #18 is identical to @alto777's #17, if you apply a bit of high school algebra. The constants may not end up exactly, but the rearranging of the scaling and shifting is only that. Rearranging.
As for omitting the exp() function and driving it from the sine function directly, I cannot say what the OP sees or is going for.
You might as well suggest using exp() driven by a triangle wave.
Come on folks, this just isn't that hard. If @mastino2 is OK with performance using floats, trig, and exponential, then the "problem" has been solved by trivial math.
Of course, as many have pointed out, this is a horrendous solution in terms of computation efficiency. Many integer-based techniques exisit.
I only started looking closer when an easy problem didn't seem to be getting solved, then was solved by AI but presented without testing, then… I recognized*
0.36787944
as 2.71828^-1, and looked closer at the original. It then started to make some kind of sense…
*from old game played with "scientific" calculators.
Would be closer, has already perhaps been suggested and for whatever reason also steps away from using exp().
I have to say after all this time that using a never-decreasing argument for sin() seems odd, and I wnoder at what point that argument will begin to make no sense, or if will ever be a problem.
It does work for the first few seconds I've ever tested any of the solutions and "solutions".
It should be added to the "How to get the most..." sticky that n00bs should closely monitor their topics - not pose a question figuring to swing by sometime next week or so and otherwise effortlessly pick up a perfect, gift-boxed solution.
in my setup this line makes the led breathing most realistic.
Also the code from Koepel is very useful, I believe I will use heartbeat in my next project!
Many thanks one more time for all answers!
For understanding, deconstruct the expression into multiple components?
e.g.
// uint8_t pwmValue = 235* ((sin(2 * PI * currentMillis / 6000) + 1) / 2) + 20;
// is equivalent to
float phase_angle = 2 * PI * currentMillis / 6000 ; // Linear phase of 2 Pi radians in 6000 milliseconds (6 seconds per revolution)
float sine_wave = sin(phase_angle) ; // Generate sine wave in range -1 to 1 with 6 second period
float positive_sine = (sine_wave + 1)/2 ; // Sine wave in range 0 to 1 with 6 second period
float sine_20_to_255 = (255 - 20) * positive_sine + 20 ; // Sine wave in range 20 to 255 with 6 second period
uint8_t pwmValue = sine_20_to_255 ; // convert float to uint8_t