I am quite unhappy with the RPM computation logic as it seems to be prone to fluctuations.
So I decided to see what happens if I actually count the number of ticks happened in the last second and multiply for 60. Or whatever timespan it takes so I can multiply by 15. It seemed too complicated until it hit me: I can use a circular buffer to record all "ticks" timestamps and when I want to compute the RPMs go over the array and count the ones that are within the last second. Pseudo code:
#define MAX_RPMS 3000
#define BUFFER_SIZE (MAX_RPMS / 15)
uint64_t timestamps[BUFFER_SIZE]
uint16_t index = 0;
void tick() {
timestamps[index] = millis();
++index;
index %= MAX_RPMS;
}
uint_16t getRPMs() {
uint64_t cutoff = millis() - (60000/15);
uint16_t result = 0;
// can be optimized by going backward from index
// but not worth here.
for(int i=0; i < BUFFER_SIZE; i++) {
if (timestamp[i] > cutoff) {
++result;
}
}
// minor optimization. I couldn't resist
return (result << 4) - result;
}
This code has also the proper side effect of returning 0 if the last tick was over a second older vs. using a different timing mechanism to zero the result.
If this works in a satisfying manner, next step will be add some crude BLE code.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.