Slow fading from a function to a other

Hello,

I looking for a solution to slower get from a function to a other.
1st here my code :

void loop() {
  vin = analogRead(A2);
Calculate_Vout();
OCR1A = vout/2; // Output on PA6 with (it output vout/2 but cause vin is in 10 bit and output in 9bit).
}

void Calculate_Vout() {
  if ((vin > 0) && (vin < 246)) vout = vin/2;
  else if ((vin > 246) && (vin < 500)) vout = vin/3;
  else if ((vin > 500) && (vin < 800)) vout = vin/4;
  else vout = vin;
}

1st the code read the voltage on A2 (vin = analogRead(A2):wink: then we calculate vout in void Calculate_Vout(), that were i looking for way to jump slowly from one if to a other else if... because when we switch from one to a other, the output voltage did a fast jump that cause me trouble.
Is there any function that can do that ?

Thanks a lot

The last line seems to be a typo.
Consider that vin is something about 800...
If vin = 799 so the expression vin/4 will be used and result will be 199
but if we increase the vin just on 2 units - to 801 - in this case the last line of function give as vout = vin;, so result will be 801 - a four times more!

If we do not pay attention to this obvious mistake, then in order for there to be no jumps between the ranges, you need either more steps, for example, not only vout/2, vout/3 and vout/4, but also intermediate vout/1.5, vout/2.5 etc...
Or choose a continuous function. However, this is not a best solution always, because with the function the program will be larger and run slower.

Hello
Take view here. HTH.

You right, but all this value is just for sample to illustrate, i real use there is more complex formula and 7 step at this point from 0 to 1023, i just use this sample to have a clear look.

Of course there is possibility to add more else if between, but that will make a lot.

Thanks for help.

Hello,

Thanks a lot for the link, i will check that, at 1st look that must be what i need :wink:
Thanks a lot

Hello,

The Ramp library look to be what i need, but has anybody use them ? i am unable to make it work in my code and documentation is not clear to me.

Thanks a lot

I did not use it, but what could be difficult there? Did you try the examples, if any?
You not even need the library, use a simple linear interpolation between two points, this is taught in school...

I understand the interpolation, what i can't manage, is to integrate it in my code and get it to work.
I mean for this part of my code :

void Calculate_Vout() {
  if ((vin > 0) && (vin < 246)) vout = vin/2;
  else if ((vin > 246) && (vin < 500)) vout = vin/3;
  else if ((vin > 500) && (vin < 800)) vout = vin/4;
  else vout = vin;
}

Thanks

did you try?
Please show your code

If the relationship between vin and vout is completely linear, you could simply use map (retaining your original, not very pretty, program structure) - untested :

uint16_t vin ; 
uint16_t vout ;

void loop() {
  vin = analogRead(A2);
  Calculate_Vout();
  OCR1A = vout/2; // Output on PA6 with (it output vout/2 but cause vin is in 10 bit and output in 9bit).
}

void Calculate_Vout() {
  vout = map( vin, 0, 1023, 0, 255 ) ;
}

If it is not completely linear, then say what the formula should be or supply a mapping table, or hand draw a graph.

1st, thanks for help.
It is linear, but look, i add the comment in the code here to show what i need :

void Calculate_Vout() {
  if ((vin > 0) && (vin < 246)) vout = vin/2;
  else if ((vin > 246) && (vin < 500)) vout = vin/3;
  else if ((vin > 500) && (vin < 800)) vout = vin/4;
  >>> Here is where i need a smooth linear transition from the previous line to the next one <<<
  else vout = vin;
}

Thanks a lot

Look like there is no solution for that, i try so many different time...

If you want a smooth transition from one value to another, use a low-pass filter:

int calcVout(void)
{
    static float voutfloat = 0.0;
    static int vout = 0;
    const float coeff = 0.05;

    int vin = analogRea(A2);
    voutfloat += (vin - vout) * (coeff);
    vout = (int)voutfloat;
    return vout;
}

Making coeff larger (up to 1.0) will make the transition faster. At coeff = 1.0, no filtering takes place. Making coeff smaller will make the transition slower, and smoother. Typical values for coeff will generally be in the range of 0.01 to 0.1.

There are several solutions and it described above. But look to your data.
I wrote to you that your steps are wrong - but you do not pay attention.
At first, with each step, the slope decreases, and then sharply increases on the last step. It is difficult to make smooth transitions on such data. You seem to have mixed up the ratios

Wrong, i reply you about the step, that just sample step, in my final code there will be 7 different formula.

Thanks for help, i will try that way, that look to be more easy to add to my code, will let you know the result.
Thanks

...you didn't understand.... It's not about specific data.
In order to smooth your formulas, they must converge at common points. But your data is not like that. When you shift by one point, the value changes several times. There is no point in smoothing such data, your formulas are simply wrong.

That is why you failed to apply the interpolation to them.

To use interpolation, you must specify points, not these formulas. For example

vin    vout
0        0
245     120       // vin/2
500     166       // vin/3
800     200       // vin/4
1024    220

and then it will be very easy to add interpolation here.

This is a method for smoothing sequential measurements, and is unlikely to be suitable for tabular data.

Oh ok, i see now what you mean, sorry.
But that will not be possible (or at this point i don't know how), because my final formula use a variable, here the 2 first of the final formulas :

if ((vin > 0) && (vin < 246)) vout = vin;
else if ((vin > 246) && (vin < 288)) vout = (vin - (((10 * Multiplicator) * vin)) / 5000);
else if ((vin > 288) && (vin < 370)) vout = (vin - (((13 * Multiplicator) * vin)) / 5000);

There is the Multiplicator, that is added by the user, that change how intense the modification on Vout is.

Thanks

Is your Multiplication factor has values about zero? Otherwise your formulas will outputs a negative values.