• ### Rewriting RPM computation logic

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.

• ### RPM math

Quick math to determine the RPM range.

The pulley driving the belt has a diameter of 44mm.

That puts the number of RPMs at 10mph to a bit shy of 2000.
Which means that four digits are enough to accomodate the RPMs at unit precision.

2000 RPMs is also 33.3 RPSs. Which gives a period of 30 milliseconds at maximum speed.