The Practical Side of Calculating Frequency
People overcomplicate this. At its core, frequency is just a count of how many times something repeats in a given window of time. That's it. The rest is implementation detail. For a basic periodic signal—think a clean sine wave or a square wave from a function generator—the most straightforward method is zero-crossing detection. You record the signal, find the points where it crosses zero going from negative to positive, measure the time between those crossings, and divide one by that interval to get hertz. Simple. Reliable. Works perfectly until real-world conditions intrude. The formula is f = 1/T, where T is the period measured in seconds. If your period is 0.02 seconds, your frequency is 50 Hz. That's the entire thing for a pure tone.
Where it gets messy is when your signal isn't clean. I spent three days last year debugging a vibration sensor reading that was consistently 8% off from the reference accelerometer. The hardware was fine. The issue was mechanical noise—background vibration at roughly 3x the fundamental frequency was creating tiny wiggles around each zero-crossing point, causing the crossing detection algorithm to trigger multiple times per actual cycle. My workaround was to apply a narrow bandpass filter centered on the expected frequency range before running the zero-crossing detector. That cut the processing time from about 2 minutes per sample to roughly 45 seconds and eliminated the false triggers entirely. The filter I ended up using was a second-order Butterworth with a bandwidth of about ±5 Hz around the target frequency. For anything more complex than a single-tone signal, you move into the frequency domain. Fast Fourier Transform is the standard approach here. You feed your time-domain samples into an FFT routine, and the output gives you a spectrum showing amplitude at each frequency bin. The bin with the highest magnitude is your dominant frequency. This is what you'd use for audio analysis, power system monitoring, or any situation where multiple frequencies are present simultaneously. A few things beginners consistently get wrong about FFT-based frequency calculation. First, the frequency resolution of your FFT is determined by your sampling rate divided by your number of points. If you're sampling at 44,100 Hz with 1024 points, your resolution is about 43 Hz per bin. That means two tones 20 Hz apart could easily get blurred into a single broad peak. You need either a longer sample window or a higher sampling rate to resolve closely spaced frequencies properly. I've seen people try to use a 256-point FFT and then complain they can't distinguish between 1000 Hz and 1050 Hz. It's not the algorithm's fault.
Second, spectral leakage is a real problem if you don't apply a proper window function before transforming. A rectangular window—the default in many libraries—assumes your signal starts and ends at zero and is perfectly periodic within your capture window. It almost never is. That discontinuity at the edges creates artificial frequency components that spread across your spectrum. Hanning or Hamming windows are the standard fixes, though they do trade off some frequency resolution for reduced leakage. You pick your poison based on what matters more for your application. There's also the goertzel algorithm, which most people don't know about but should. It's computationally cheaper than a full FFT when you only need to detect one or two specific frequencies. If you're building a DTMF tone decoder or monitoring a single motor's rotational frequency, the goertzel algorithm will give you the same result with roughly a tenth of the processing overhead. I switched one of our embedded systems from FFT to goertzel and dropped the CPU load from about 18% to under 3% on that particular task. For statistical frequency—counting how often a particular value appears in a dataset—the math is even simpler. Frequency equals the count of occurrences divided by the total number of observations. If you rolled a die 600 times and got a three exactly 102 times, the relative frequency is 102/600 = 0.17. This is descriptive statistics at its most basic level. People sometimes confuse this with probability, but they're related concepts, not the same thing. Frequency is what you observe. Probability is what you predict.
Get the Full Details

One edge case worth noting: when dealing with very low frequencies, zero-crossing detection becomes unreliable because a single noisy cycle can throw off your period measurement significantly. In those situations, autocorrelation is more robust. You correlate your signal with a delayed version of itself, and the delay at which the correlation peaks corresponds to the period. It's slower to compute than zero-crossing detection but handles noise much better. I use this approach for measuring heart rate from a noisy PPG sensor signal where the fundamental frequency is under 2 Hz and the signal-to-noise ratio is barely above 3 dB. The biggest bottleneck I encounter in practice isn't the math—it's getting clean data into the calculator. Sampling rate selection, anti-aliasing filtering, and proper ground isolation matter more than which algorithm you choose. A well-sampled signal analyzed with a basic method will outperform a poorly sampled signal fed into the most sophisticated FFT available. Spend your time on the front end.