
Rewriting RPM computation logic
a day ago • 0 commentsI 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
08/05/2022 at 18:02 • 0 commentsQuick 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.

First cut at RPM calculation algorithm
08/05/2022 at 16:46 • 0 commentsSo the Reed Switch worked as expected, no brainer of course.
I put together some code to compute the RPMs and display them on the Seeeduino Extender OLED display. If I display the result in RPMs, the output seems to be reasonably right, but if I divide further the fluctuation is bigger. Time to debug.
Current code is here, I am suspecting something is wrong with the 5ms forced delay in the IRQ.