Electronic – Identifying 40Hz frequency shift

frequencyfsk

I have a signal that is at 4 kHz. This signal shifts by 40 Hz depending on some user input. I like to detect this change in software as fast as I can. What should be the ADC frequency I should use?

I currently plan to sample at 40 kHz and use a window of 10 ms to do an FFT to find out this shift. But before I build the system, I like to get a second opinion.

Best Answer

To restate your problem, you have a input signal in the frequency range of 3960-4040 Hz, and want to determine this frequency on the fly. Many microcontrollers can do this quite simply.

The highest frequency of interest is 4.04 kHz, which has a period of 248 µs. That's a "long" time for even a small and cheap micro. At the other end, 1/3.96kHz = 253 µs, so you want to determine the period of the signal over a range of 5 µs. You didn't say what resolution you want, so let's say 1 part in 50, which means you can get what you want if you can measure the period down to 100 ns.

This is all quite doable in many microcontrollers, which have the ability to take a snapshot of a free running timer on a particular edge of a input signal. On 8 bit PICs, this is one of the things the CCP (Compare, Capture, Pulse-width modulation) module can do. On 16 bit PICs it's called the "Input Capture" module. Either way, you end up with a 16 bit timer snapshot every cycle of your incoming signal.

To determine the period of the previous cycle, simply do a unsigned subtract of the new capture value minus the previous. This works whether the timer wrapped around during that cycle or not, as long as the period doesn't exceed the timer's wrap time. If you clock the timer at 10 MHz, then you will get values from 2475 to 2525, with the subtract yielding the period in units of 100 ns.

You don't say what you want the freqency for, but perhaps you can use this period directly. If you really need frequency (think about it carefully, you may not), then you do the divide. Even with the micro only running at 10 MHz, you have over 2000 instruction cycles per input cycle, which is plenty for a divide. On a 16 bit PIC, you can do the divide in hardware in only 18 cycles.

Either way, I'd do a little low pass filtering on the measured periods before doing any other processing. This will make your system less susceptible to jitter and can even reduce the quantization noise a bit. Keep in mind that a band-limited 3960-4040 Hz signal can't change its frequency that fast. Apparent changes in frequency above some limit are guaranteed to be noise.