I have a setup that is equivalent to a guitar string with pickup, with signals of similar frequency range. I have a simple zero crossing detector with a comparator and then just count the interval between low-to-high transitions using a microcontroller. I got to wondering how accurately I could measure the frequency. If I wanted to measure it to several decimal places with certainty, what changes should I make? Is there a good resource on high precision zero crossing?

The output voltage from the coil is low (~3mV pp), so should I choose a comparator with lower input voltage offset? Or would it make more sense to add a preamp stage? How about propagation delay - if a comparator has delay of x for one transition, will it be x for every transition?

  • 6
    \$\begingroup\$ If the string resonates at one frequency only, then zero crossing will deliver usable results. If there are harmonics present, then they will mess with your zero crossing counter and you will get wrong results. \$\endgroup\$
    – JRE
    Nov 7, 2019 at 10:00
  • 2
    \$\begingroup\$ As @JRE noted, this won't really work for much beyond a pure (or strongly dominant) single frequency. A guitar string is certainly not a producer of such a tone, at least not generally. Frequency is usually measured through sampling and application of an FFT. This allows you to fully deconstruct the harmonic content of the waveform (within resolution), not just the fundamental. \$\endgroup\$
    – J...
    Nov 7, 2019 at 12:49
  • 1
    \$\begingroup\$ Either an fft or dft or similar, but at least there'll be plenty of options for real-time (minimum lag) processing. You can definitely make something like you have in mind with 'normal' hardware, but that would result in lower precision or higher lag. With an FPGA, I think you can work sufficiently fast not to run into those problems. It would in fact be overkill, but definitely get you going in the right direction. \$\endgroup\$
    – Mast
    Nov 7, 2019 at 14:19
  • 1
    \$\begingroup\$ What microcontroller are you using? \$\endgroup\$
    – J...
    Nov 7, 2019 at 15:18
  • 1
    \$\begingroup\$ @TrivialCase Kudos for using both of the the terms DFT and FFT correctly. Most people, including me, usually don't bother. :) \$\endgroup\$
    – pipe
    Nov 7, 2019 at 18:30

3 Answers 3


It would make sense to have an amplification (op-amp) and then a comparator with a positive and negative supply.

Concerning the digital part, it has a lot to do with the speed/type of your MCU and your code. There are many ways to improve accuracy at this level but it depends a lot on the MCU.

Now if you want to go hardcore, you can also sample the amplified output of the coil with an A/D and perform a Fourier Transform to get the main frequency and also all the sub-frequencies.

  • \$\begingroup\$ I considered this, it seems like the best way to guarantee higher accuracy, but I guess it's a big trade-off since precision ADCs can be very expensive \$\endgroup\$ Nov 7, 2019 at 14:03
  • 1
    \$\begingroup\$ The thing is you don't need a precision ADC but you need a fairly fast one. It's more about timing than absolute precision, since you have relative signals anyway. Some MCU like Pics can sample 10 bits at 1.1MSPS which should be plenty enough. The bottleneck might be more related to the processing since FFT is quite heavy. Perhaps send raw data through USB and then process it on a more powerful system would be a solution while keeping the embbeded part simple and cheap. \$\endgroup\$
    – Damien
    Nov 8, 2019 at 2:38

You'll likely want to measure the total of many zero crossings (and divide by 'many' before taking the reciprocal).. or average many measurements.. otherwise noise in the signal will unduly affect your measurement, and you don't need the answer that quickly.

You can measure easily to a couple hundred nanoseconds with a typical 8-bit micro (so 200ns in a 5kHz note would give you 3 digits) but that doesn't translate necessarily into results anywhere near that stable or accurate.


if a comparator has delay of x for one transition, will it be x for every transition?

Delay may vary depending on the amount of 'overdrive' (voltage beyond the comparison threshold). Here's a graph showing response of the LM397 to various overdrives:-

enter image description here

In this case the difference between 5mV and 50mV is 300ns, which corresponds to 0.03% of a 1kHz cycle.

If the signal amplitude is constant then the delay doesn't matter because it will be consistent from one cycle to the next. Delay is generally smaller with greater overdrive, so the effect of amplitude variation on delay can be minimized by making the signal much larger than necessary for detection.

Your 3mV signal is too low for reliable detection by most comparators, so you should amplify it to at least 100mV. If the amplitude varies greatly over time (eg. after plucking a guitar string) then you might have to use an AGC (Automatic Gain Control) circuit to maintain relatively constant amplitude at the comparator, though if the signal is clean and pure just applying more amplification may be enough.

To prevent noise and harmonics from causing 'false' zero crossings you should apply some hysteresis to the comparator, which makes it ignore small variations in the signal. Bandpass filtering the signal before detection will also help to remove noise.

After detection you have to decide how to get the 'several decimal places' of precision that you want. The simplest way is to just count pulses over a fixed time period long enough to get the desired precision. However at low audio frequencies the required 'gate' time is very long.

Measuring the time between cycles is much faster, but makes the result sensitive to variation between cycles. The simplest solution is to measure the time of several cycles and then divide by the number of cycles, which averages them. If your lowest frequency is eg. 50Hz then you can measure and average the periods of at least 50 cycles in 1 second.

At higher frequencies the resolution of the timer may become significant. If so then just switch to pulse counting mode. At 1kHz you have 3 digits past the decimal point with a 1 second 'gate' time.

  • \$\begingroup\$ Thanks! I had never seen AGC before \$\endgroup\$ Nov 7, 2019 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.