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, ...
// ------------------------------------------------------------------
// SMOOTHING WITH INTEGER VARIABLES (CSHARP)
// ------------------------------------------------------------------
Int32 Storage;
Int32 SmoothingINT(Int32 NewValue, Int32 Divisor)
{
Int32 AvgValue;
// ------------------------- Compute the output averaged value
AvgValue = Storage / Divisor;
// ------------------------- Add to storage the delta (New - Old)
Storage += NewValue - AvgValue;
// -------------------------
return AvgValue;
}
Or
' -------------------------------------------------------------------
' SMOOTHING WITH INTEGER VARIABLES (VbNet)
' -------------------------------------------------------------------
Function SmoothingINT(ByVal NewValue As Int32, ByVal Divisor Int32) As Int32
Dim AvgValue As Int32
Static Storage As Int32
' -------------------------- Compute the output averaged value
AvgValue = Storage \ Divisor
' -------------------------- Add to storage the delta (New - Old)
Storage += NewValue - AvgValue
' --------------------------
Return AvgValue
End Function