Rewriting RPM computation logic

A project log for Adding BLE to a "dumb" treadmill

I have a Gold Gym 410 which is perfect for my purposes. But I always had an itch about tapping into speed and inclination data.

Enzo LombardiEnzo Lombardi 08/15/2022 at 18:440 Comments

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 %= 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) {
   // 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.