dc42, thanks for your link.
I don’t know if I understand your code right, but it contains 2 things that I don’t like:
“delay(sampleTime);” would block the execution of code? My program will do more things than measuring frequency.
You can easily change it to be non-blocking. Just replace function readFrequency by 2 functions:
numPulses = 0; // prime the system to start a new reading
attachInterrupt(0, isr, RISING); // enable the interrupt
return (numPulses < 3) ? 0 : (1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime);
Then call startCounter to start the frequency measurement, and call getFrequency a suitable amount of time later in blink-without-delay style to stop the measurement and return the frequency.
Also if I am measuring a 100khz signal the ISP would be executed 100000 times and waste a lot of CPU?
If you use a gate time of 1 second, then yes. But to measure 100kHz, you can use a much shorter gate time. For example, if you measure over 1ms then you are measuring 100 cycles, and the error due to the inaccuracy of the micros function is reduced by a factor of 100.
btw another cause of inaccuracy with both your code and mine is that the servicing of the interrupt from the first or last pulse may be delayed because of another interrupt already executing (e.g. the timer 0 interrupt or the hardware serial interrupt). With my code, once again the error will be reduced by a factor of the number of cycles counted.