FM demodulation

Status
Not open for further replies.

colinza

Member
Hi Teensiers

So there's a bunch of modules for FM modulation but none for demodulation. Actually none for any sort of demodulation.

As I'm still a big noob when it comes to this topic of DSP I was wondering if anyone had suggestions or advice about this.

What I'm working with is a direct conversion receiver with a 20khz IF pushed straight into the Teensy analog port. From spending several days reading the easiest way to do this without I/Q is to just pass the signal through a Biquad highpass filter with a ~15khz corner, which results in an AM signal.

From there it needs to become an audio signal, but I'm not entirely sure what to do there. So far I put together the most simplistic module here https://github.com/calston/x-uhf/blob/master/controller/AM_demod.cpp which just emulates a diode detector circuit kinda. Now I need to remove all the other frequency information, or am I lost? I guess I can just do a rolling average window and reconstruct like that or is there some fancy way people use FIR/IIR filters?

Throwing my dead simple abs() straight out to a speaker through the DAC actually does work, the audio quality is just really crummy.

I would really like to get a something in a single block that I can contribute back to the Audio library because the other examples of FM demodulation for Teensy I've been able to find are either built around very old versions of the library or are based on I/Q signals from off the shelf receiver hardware.
 
Thanks

That seems to be the same problem though, unless theres an efficient way to just generate the I/Q signals from the raw input?
 
Hi Colin,

I would recommend Whiteley (2011) and the thesis by Andras Retzler which both provide excellent explanations on FM demodulation and also ready-to-use C code!

You will find the links here:

https://github.com/DD4WH/Teensy-ConvolutionSDR/wiki/Links-&-Resources

You can make I & Q signals out of your DC receiver signal if you multiply the signal with a local oscillator (LO) with 0 degree phase shift and with 90 degrees phase shift respectively. Then treat these signals as I & Q. For FM, just calculate the phase shift with arctan et voilá: demodulated audio. [the multiplication also translates your signal from your IF 20kHz to baseband, which makes things much easier then ! (LO frequency has to be 20kHz)]

A coded example for FM demodulation is in the Teensy Convolution SDR code which you will also find under the link above.

In practice, FM demodulation is a little more complex, but not complicated! However, if you would like to demodulate wideband FM radio, you need more bandwidth in your signal (at least 192kHz, so higher sample rate is needed). For narrowband FM, its perfectly OK to use the 44k1 sample rate.

Also have a look at the Teensy SDR code by Rich Heslip, he coded a Teensy receiver for the Teensy 3.2 and by using mainly the audio lib blocks.

A modified version of that code can be found here (however, as far as I remember, this does not have FM demodulation):

https://github.com/DD4WH/Teensy-SDR-Rx

Have fun with the Teensy!

Frank DD4WH
 
This will probably work well with the audio shield, but probably not so much with the analog input pins on Teensy.

What I'm working with is a direct conversion receiver with a 20khz IF pushed straight into the Teensy analog port. From spending several days reading the easiest way to do this without I/Q is to just pass the signal through a Biquad highpass filter with a ~15khz corner, which results in an AM signal.

When using the analog pins on Teensy, there's no analog low pass filtering. Unless you add an analog filter, any signal above 22 kHz will alias. Implementing a 15 kHz low pass filter with the audio library isn't going to do much good if all that higher frequency stuff has already aliased onto the lower frequency area.

The SGTL5000 chip on the audio shield does very effectively filter away signals above about 21 kHz. NXP doesn't publish much info about this in their datasheet, but I can tell you I've personally tested with a function generator applying a full scale sine wave. It starts rapidly attenuating around 21 kHz and when you get past about 24 kHz there's almost no effect. The SGTL5000 probably has a sigma-delta converter inside. What it's oversampling ratio might be isn't documented, but 32 or 64 are probably good guesses. What sort of decimation filter is inside the SGTL5000 is also unknown. But I can tell you from experience watching numbers scrolling in the serial monitor as a sweep the signal generator, it's very effective.
 
When using the analog pins on Teensy, there's no analog low pass filtering. Unless you add an analog filter, any signal above 22 kHz will alias. Implementing a 15 kHz low pass filter with the audio library isn't going to do much good if all that higher frequency stuff has already aliased onto the lower frequency area.
.

Yes I definitely did pass the input signal through a 20khz filter because there's so much other junk coming from the SA612, and then bias it up to 500mV with an opamp after decoupling.
 
Hi Colin,

I would recommend Whiteley (2011) and the thesis by Andras Retzler which both provide excellent explanations on FM demodulation and also ready-to-use C code!

You will find the links here:

https://github.com/DD4WH/Teensy-ConvolutionSDR/wiki/Links-&-Resources

You can make I & Q signals out of your DC receiver signal if you multiply the signal with a local oscillator (LO) with 0 degree phase shift and with 90 degrees phase shift respectively. Then treat these signals as I & Q. For FM, just calculate the phase shift with arctan et voilá: demodulated audio. [the multiplication also translates your signal from your IF 20kHz to baseband, which makes things much easier then ! (LO frequency has to be 20kHz)]

Thanks very much for this Frank! Very useful info
 
Status
Not open for further replies.
Back
Top