I wrote a version of this code ~25 years ago. I recently needed some RPM code for an AdaFruit Adalogger RP2040 and I was not not too excited about the examples I found. So I recreated the code and thought I would post it for others. I did not come across other code like this – maybe something similar is out there.
This is better way to measure RPM over a wider frequency range with good accuracy at both low speeds and high speeds. This code will measure from 60 RPM to over 1 million RPM on the AdaFruit AdaLogger RP2040 I tested it on.
The "counting pulses over a given time" method can work well enough for fast signals, but goes to pot for slow signals. It also has a jitter issue since the sample window is not synchronized with the incoming pulses.
The "time between edges" works well for slow signals, but has increasing quantization errors for fast signals.
This method is a hybrid that counts edges and measures average period between edges with microsecond-ish accuracy.
The idea is to have a given sample window. This window should be long enough to guarantee that at least two of your lowest RPM rising edges can be captured.
For instance, I want to capture 60 RPM with 4 PPR. The edge frequency is:
(60RPM/60)*4 = 1Hz*4 = 4Hz (250mS period)
To guarantee that I will capture at least two edges, I need to sample for at least 500 mS.
This algorithm captures the time (using "micros()", which may not be ideal) of the first rising edge (if there is one) within the sampling window, and any subsequent rising edges within the sampling window.
When the sampling window closes, the number of edges, first edge time and last edge time are captured for the foreground to decode:
If edge_count is 0 or 1 then the RPM is below what can be read within your sample window.
If edge count is 2 or more, the RPM can be calculated:
RPM= (captured_edge_count-1)*(60*1000000)/((captured_last_edge_uS-captured_first_edge_uS)\*PPR)
There can be some big numbers involved, so you might need some type casting.
Written / tested on the Adafruit AdaLogger RP2040
Peace.
-Baxsie











