Smoothing algorithm using integer arithmetic
The following code was taken from an Arduino tutorial on smoothing:
int smooth(int data, float filterVal, float smoothedVal) {
if (filterVal > 1) {
filterVal = .99;
}
else if (filterVal <= 0) {
filterVal = 0;
}
smoothedVal = (data * (1 - filterVal)) + (smoothedVal * filterVal);
return (int)smoothedVal;
}
The following statement, took from the same tutorial, got me thinking:
This function can easily be rewritten with all-integer math, if you need more speed or want to avoid floats.
Fact is I do want to avoid floats and increase speed, but I wonder: how to convert this to integer arithmetic? Bit-banging solutions are a bonus ;o)
A simple technique is scaling up by multiplying the input value with for example 10000
and putting that result in an int
, do the calculations in int
, and then scale the output back into a float
by dividing with the same factor.
In your function you then also need scale up everything with that same factor.
The choice of factor depends on the possible ranges of the values; you want to avoid overflow at the high end, and inaccuracy at the low end. If you think about it, the factor determines where you put the decimal point: fixed point, instead of floating point.
The factor can be anything, it does not have to be 100
, 1000
, and so on, but 627
is fine too.
If you go down this route, you want to convert as much of your code to int
, because the conversions described above of course also take time.
To illustrate my point, the following could be it:
#define FACTOR 10000 // Example value.
int smooth(int data, int filterVal, int smoothedVal)
{
if (filterVal > FACTOR)
{
filterVal = FACTOR - 100;
}
else if (filterVal <= 0)
{
filterVal = 0;
}
smoothedVal = (data * (FACTOR - filterVal)) + (smoothedVal * filterVal);
return smoothedVal;
}
You may need/want to check for overflow, ...