High latency for frequencies with FreqMeasure Library and Arduino Uno

I have made a sketch using the FreqMeasure Library with Arduino Uno to read frequencies from a GB-212 square waves generator. The library show good results but for low frequencies, mainly under 100 Hz or 200 Hz the latency is high for my project (over 1000 ml or what is the same 1 sec). To solve this problem I have changed my sketch and now for frequencies under 100Hz I’m only counting 5 times before calculate the frequency, and for frequencies > 100Hz maintain the 30 mediations before get the frequency. Here is the table with my results:

Count of measurements: 5 for Frec <= 100Hz and 30 for > 100Hz
Freq generator GB-212 (Hz) CPU clock cycles
20,00 799515,00
30,00 533973,00
50,00 320335,00
70,00 228667,00
90,00 177715,00
100,00 159980,00

I think the frequency calculations are quite accurate and latency acceptable. My question is, There are a better way to get good result with low latency? Something more efficient, or any kind of configuration in the library ? Any answer will be welcome…….


Perhaps a Kalman filter on the individual periods would do the job, scarily complex though, you probably want to adapt the number of cycles used according to the result:

If the result changes dramatically, back off to a single cycle estimate, then 2 cycles, then 4, then 8, 16 etc, so that the estimate becomes more and more accurate for a stable value.

The criterion for "dramatic" change becomes more sensitive as you wind up the accuracy I think.

As a suggestion, you could make the latency itself a constant and used in the measurement method. For 0.01% precision, you need to measure over a time period (interval) of 40ms (40,000µs) since the precision of the microsecond timer is 4µs. You shouldn't need any library to do this ... its as simple as using a button debouncer. Here, you would use an interrupt and count input pulses (rising edges for example). The first rising edge would reset the counter and measurement timer. As rising edges come in, the counter increments and the expired time is checked. If the expired time >= 40ms, then the frequency is calculated knowing the pulse count and elapsed time. These are instantly reset and ready for the next measurement.

With this method, you would always have 1 part in 10,000 precision over the 20Hz to 2kHz range. Below 25Hz the input count will remain at 1, but will automatically increase as required for higher frequencies.

For 1 part in 2500 (0.04%) you would only have 10ms latency.