I'm designing a device that will have an IR photodiode connected to a low power microcontroller's ADC pin. At times, another device will be transmitting a 48KHz square wave, and I'd like to be able to detect when that is the case entirely in software, as well as being able to detect individual high and low transitions.

My understanding is that a PLL is the correct solution to this problem. However, I have extremely limited DSP knowledge, so I have a fuzzy idea at best on how to actually implement this in software, and much of the documentation available goes well over my head with a lot of domain specific terminology. This is further complicated by the low power nature of the microcontroller - I have limited processor cycles available, and thus I'd like to sample as infrequently as possible while still reliably locking on to the signal. If it helps, the sampling timer can be adjusted to match the observed frequency of the input signal.

Can anyone suggest an approach to this that is as straightforward and understandable as possible, while also minimizing CPU resources consumed?

  • $\begingroup$ Will the amplitude of the pulses be known roughly a priori? That is, could you decide upon a threshold value ahead of time to discriminate the high and low values? Do you expect significant noise? $\endgroup$ – Jason R Oct 26 '12 at 0:56
  • $\begingroup$ @JasonR It's receiving IR control signals via an IR photodiode. I can certainly set a minimum threshold for the signal, but there will be a lot of DC bias, and yes, a lot of noise on other frequencies. $\endgroup$ – Nick Johnson Oct 26 '12 at 8:06
  • $\begingroup$ @NickJohnson What kind of MCU are you using? ADC conversions can take a while depending on the chip. Why not solve this in hardware? Or use a 48kHz IR receiver instead of diode? electronics.stackexchange.com can help btw. $\endgroup$ – geometrikal Oct 31 '12 at 12:07
  • $\begingroup$ @geometrikal You're right, the MCU I was planning on using can't sample fast enough - but I can use a slower carrier wave. I wanted to use a discrete sensor so I could also use it as a background light sensor, but I've since decided on another approach. $\endgroup$ – Nick Johnson Oct 31 '12 at 13:01

One partial answer to my own question is to use the Goertzel algorithm instead of a PLL. The Goertzel algorithm makes it possible to trivially determine the power of a particular frequency; it won't provide the phase, however.

The Goertzel algorithm can be implemented quite trivially using a multiplication and two additions per sample; the sampling rate need only be a minimum of twice the frequency of the signal to be detected. Determining the amplitude of the signal from the Goertzel algorithm's output requires four more multiplies and two more additions.

Since the multiplication in the main part of the Goertzel algorithm is by a constant factor of 2 * cos(2 * pi * w), where w is the number of samples per cycle, one multiplication can be eliminated entirely by sampling at 6 times the target frequency, making 2 * cos(2 * pi * 1/6) = 1.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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