The method FilterOnePole::input(float) starts with these statements:
long time = micros();
ElapsedUS = float(time - LastUS); // cast to float here, for math
When micros() reaches 231, which happens roughly 35.8 minutes after the program starts, time becomes a large negative number, and the subtraction time - LastUS overflows.
In C and C++, arithmetic overflow of signed integral types is undefined behavior. This means the program is incorrect, and anything can happen, including (but not limited to) the subtraction giving the expected result. Just for illustration, here is a recent example of the kind of surprises you can get with integer overflows.
The same bug is present in FilterTwoPole.cpp and in FilterDerivative.cpp.
The fix is very simple: all variables holding timestamps (LastUS, LastTimeUS, thisUS, time and now) should be declared unsigned long. This is the type returned by micros(), and it is not a coincidence that it is the right type for timing calculations. Unlike signed integers, the arithmetics on unsigned integers are specified by the C and C++ standards to be done modulo MAX(type)+1. This guarantees that the subtraction will yield the correct result even across a micros() rollover.
The method
FilterOnePole::input(float)starts with these statements:When
micros()reaches 231, which happens roughly 35.8 minutes after the program starts,timebecomes a large negative number, and the subtractiontime - LastUSoverflows.In C and C++, arithmetic overflow of signed integral types is undefined behavior. This means the program is incorrect, and anything can happen, including (but not limited to) the subtraction giving the expected result. Just for illustration, here is a recent example of the kind of surprises you can get with integer overflows.
The same bug is present in FilterTwoPole.cpp and in FilterDerivative.cpp.
The fix is very simple: all variables holding timestamps (
LastUS,LastTimeUS,thisUS,timeandnow) should be declaredunsigned long. This is the type returned bymicros(), and it is not a coincidence that it is the right type for timing calculations. Unlike signed integers, the arithmetics on unsigned integers are specified by the C and C++ standards to be done modulo MAX(type)+1. This guarantees that the subtraction will yield the correct result even across amicros()rollover.