FM demod using PLL

Started by lightmetal November 10, 2003
I am looking for an example of using a software pll for demod of FM. 
I tried the other fm demod routines (arctan, differentiator) and think
there could be an improvement using a software pll.

I found some matlab code posted by Tom ? that works on his data
(generated by matlab) but fails on mine.  I think it has something to
do with the hz/volt or modulation index.  I am also not exactly sure
of my Fc but it should be very close to 12khz.

If I use the matlab signal processing toolbox "demod" on my data (or
the data generated in Tom's matlab code) it looks fine and outperforms
the other routines.  The only thing I can tell from the spectrum is
that in Tom's matlab code, the carrier Fc is much more prominent as
you would find with a low modulation index compared to my data where
you can't find the carrier.

block diagram, C, matlab or sharc assembler examples or pointers would
be great.  I looked at Frerking but haven't been able to get his to
work either.  The matlab simulink PLL blocks that I tried are very
cryptic also.

thanks

lightmetal wrote:

> I am looking for an example of using a software pll for demod of FM. > I tried the other fm demod routines (arctan, differentiator) and think > there could be an improvement using a software pll. > > I found some matlab code posted by Tom ? that works on his data > (generated by matlab) but fails on mine. I think it has something to > do with the hz/volt or modulation index. I am also not exactly sure > of my Fc but it should be very close to 12khz. > > If I use the matlab signal processing toolbox "demod" on my data (or > the data generated in Tom's matlab code) it looks fine and outperforms > the other routines. The only thing I can tell from the spectrum is > that in Tom's matlab code, the carrier Fc is much more prominent as > you would find with a low modulation index compared to my data where > you can't find the carrier. > > block diagram, C, matlab or sharc assembler examples or pointers would > be great. I looked at Frerking but haven't been able to get his to > work either. The matlab simulink PLL blocks that I tried are very > cryptic also. > > thanks
The only thing I can suggest is this - a PLL will not demodulate FM if the deviation is unrealistic. eg if the depth of modulation is from dc though fc up to 2fc for instance. When you say it does not work what actually happens? Does it demodulate the FM but the output is distorted? What sort of baseband signal do you have?eg sine,square etc You have to know the carrier frequency as the VCO has to be set to this frequency.If it is not centred properly there will be a dc offset on the phase detector output which will give no end of problems. Maybe you should tweek the VCO setup frequency (fset in my Matlab code) until it locks in that case. The Matlab code is quite closs to a real PLL except it has a sinusoidal VCO (which can be changed to a square wave). As it is type II (an initial Bode plot roll off of -12dB/decade - at low frequencies) then the tracking is optimal provided you watch the stability. The span ratio should be 10 mostly and this gives a good phase margin (57 degrees or there abouts) Tom

lightmetal wrote:

> I am looking for an example of using a software pll for demod of FM. > I tried the other fm demod routines (arctan, differentiator) and think > there could be an improvement using a software pll. > > I found some matlab code posted by Tom ? that works on his data > (generated by matlab) but fails on mine. I think it has something to > do with the hz/volt or modulation index. I am also not exactly sure > of my Fc but it should be very close to 12khz. > > If I use the matlab signal processing toolbox "demod" on my data (or > the data generated in Tom's matlab code) it looks fine and outperforms > the other routines. The only thing I can tell from the spectrum is > that in Tom's matlab code, the carrier Fc is much more prominent as > you would find with a low modulation index compared to my data where > you can't find the carrier. > > block diagram, C, matlab or sharc assembler examples or pointers would > be great. I looked at Frerking but haven't been able to get his to > work either. The matlab simulink PLL blocks that I tried are very > cryptic also. > > thanks
I too have been Frerking about at this for some time... Tom
Tom, thanks for responding.

I modified your code, tweaked just about everything, and no luck.  The
signal is not demod'ed at all.  The source signal is a noisy 400hz
tone at ~12k carrier (I/Q), it looks like two humps on each side of
12k prior to demod.  No center carrier spike at 12k. It demod's great
with the signal processing toolbox demod command and other simulink
demod models like arctan, dif, etc.

I can't get it to demod with any pll routines.

After passing through your code and the simulink fm passband demod
block, it looks like one hump (fm sideband) was translated to zero so
the signal is nothing but harmonics.  (Come to think of it, I should
be able to tell the carrier offset from the harmonic frequency after
translation?)

It was recorded from my dsp radio and the carrier could be off +/-
200hz.  Since I can't find the carrier spike at around 12k, I can't
fft the data to see exactly where I should fset the vco.  The orignal
data was recorded and I'm not sure of the deviation, but it sounded
fine in narrow FM mode so it can't be that great.  I am using a 48khz
fs.

FM has been kicking my ass for months now.  I have three FM routines
working but they aren't quite what I want compared to my AM, ISB, LSB,
etc which look textbook perfect.

I can re-record the data and lock the carrier more closely but my fm
signal generator is only so stable.

The part I struggle with is in simulink, the FM passband modulator
output has a clean carrier signal in the fft compared to real signals
that I generate that have the typical two humps with a carrier null
between.

What am I missing?

Thanks again.






> The only thing I can suggest is this - a PLL will not demodulate FM if the > deviation is unrealistic. eg if the depth of modulation is from dc though > fc up to 2fc for instance. When you say it does not work what actually > happens? > Does it demodulate the FM but the output is distorted? What sort of > baseband signal do you have?eg sine,square etc You have to know the > carrier frequency as the VCO has to be set to this frequency.If it is not > centred properly there will be a dc offset on the phase detector output > which will give no end of problems. > Maybe you should tweek the VCO setup frequency (fset in my Matlab code) > until it locks in that case. > The Matlab code is quite closs to a real PLL except it has a sinusoidal > VCO (which can be changed to a square wave). As it is type II (an initial > Bode plot roll off of -12dB/decade - at low frequencies) then the tracking > is optimal provided you watch the stability. The span ratio should be 10 > mostly and this gives a good phase margin (57 degrees or there abouts) > > > > > > Tom

lightmetal wrote:

> Tom, thanks for responding. > > I modified your code, tweaked just about everything, and no luck. The > signal is not demod'ed at all. The source signal is a noisy 400hz > tone at ~12k carrier (I/Q), it looks like two humps on each side of > 12k prior to demod. No center carrier spike at 12k. It demod's great > with the signal processing toolbox demod command and other simulink > demod models like arctan, dif, etc. > > I can't get it to demod with any pll routines. > > After passing through your code and the simulink fm passband demod > block, it looks like one hump (fm sideband) was translated to zero so > the signal is nothing but harmonics. (Come to think of it, I should > be able to tell the carrier offset from the harmonic frequency after > translation?) > > It was recorded from my dsp radio and the carrier could be off +/- > 200hz. Since I can't find the carrier spike at around 12k, I can't > fft the data to see exactly where I should fset the vco. The orignal > data was recorded and I'm not sure of the deviation, but it sounded > fine in narrow FM mode so it can't be that great. I am using a 48khz > fs. > > FM has been kicking my ass for months now. I have three FM routines > working but they aren't quite what I want compared to my AM, ISB, LSB, > etc which look textbook perfect. > > I can re-record the data and lock the carrier more closely but my fm > signal generator is only so stable. > > The part I struggle with is in simulink, the FM passband modulator > output has a clean carrier signal in the fft compared to real signals > that I generate that have the typical two humps with a carrier null > between. > > What am I missing? > > Thanks again. > > > The only thing I can suggest is this - a PLL will not demodulate FM if the > > deviation is unrealistic. eg if the depth of modulation is from dc though > > fc up to 2fc for instance. When you say it does not work what actually > > happens? > > Does it demodulate the FM but the output is distorted? What sort of > > baseband signal do you have?eg sine,square etc You have to know the > > carrier frequency as the VCO has to be set to this frequency.If it is not > > centred properly there will be a dc offset on the phase detector output > > which will give no end of problems. > > Maybe you should tweek the VCO setup frequency (fset in my Matlab code) > > until it locks in that case. > > The Matlab code is quite closs to a real PLL except it has a sinusoidal > > VCO (which can be changed to a square wave). As it is type II (an initial > > Bode plot roll off of -12dB/decade - at low frequencies) then the tracking > > is optimal provided you watch the stability. The span ratio should be 10 > > mostly and this gives a good phase margin (57 degrees or there abouts) > > > > > > > > > > > > Tom
I suppose I now have to ask how you are generating the FM. A PLL will not lock if there is no power at the carrier which is what you are suggesting. The same goes for double sideband supressed carrier - where you first have to square the signal and lock onto 2fc instead of fc. For test purposes I normally just used two bench oscillators - one with a sweep input.Feed the modulating signal into the second oscillator which is set to your carrier frequency. This is tried and tested. Another thing you can do is this - just feed a carrier signal (unmodulated) into the PLL - the output (of the filter) should be zero or there abouts when locked. If you then slowly sweep the signal - manually upwards or downwards the demodulated signal should show a slowly moving dc signal moving either upwards or downwards in potential depending on whether you are + or - the carrier frequency ie you are FMing by hand slowly. The PLL should definately lock into that. Another check with a single carrier is to look at the VCO output - it should be in quadrature when locked - easy to see for a single unmodulated carrier of course. If this is not the case then it will not work. Finally and most importantly the PLL I have has a multiplier as a phase detector. This means that if the amplitude of the FM signal is too big (or too small) the loop gain of the PLL gets increased or decreased and can cause instability. You can see this if you draw an open loop Bode plot. At present it is set up for unity amplitude. In a real PLL there is usually a hard limiter before the phase detector (not a good idea at low SNRs by the way - it can make things worse!). Hope this helps Tom

Tom wrote:

> lightmetal wrote: > > > Tom, thanks for responding. > > > > I modified your code, tweaked just about everything, and no luck. The > > signal is not demod'ed at all. The source signal is a noisy 400hz > > tone at ~12k carrier (I/Q), it looks like two humps on each side of > > 12k prior to demod. No center carrier spike at 12k. It demod's great > > with the signal processing toolbox demod command and other simulink > > demod models like arctan, dif, etc. > > > > I can't get it to demod with any pll routines. > > > > After passing through your code and the simulink fm passband demod > > block, it looks like one hump (fm sideband) was translated to zero so > > the signal is nothing but harmonics. (Come to think of it, I should > > be able to tell the carrier offset from the harmonic frequency after > > translation?) > > > > It was recorded from my dsp radio and the carrier could be off +/- > > 200hz. Since I can't find the carrier spike at around 12k, I can't > > fft the data to see exactly where I should fset the vco. The orignal > > data was recorded and I'm not sure of the deviation, but it sounded > > fine in narrow FM mode so it can't be that great. I am using a 48khz > > fs. > > > > FM has been kicking my ass for months now. I have three FM routines > > working but they aren't quite what I want compared to my AM, ISB, LSB, > > etc which look textbook perfect. > > > > I can re-record the data and lock the carrier more closely but my fm > > signal generator is only so stable. > > > > The part I struggle with is in simulink, the FM passband modulator > > output has a clean carrier signal in the fft compared to real signals > > that I generate that have the typical two humps with a carrier null > > between. > > > > What am I missing? > > > > Thanks again. > > > > > The only thing I can suggest is this - a PLL will not demodulate FM if the > > > deviation is unrealistic. eg if the depth of modulation is from dc though > > > fc up to 2fc for instance. When you say it does not work what actually > > > happens? > > > Does it demodulate the FM but the output is distorted? What sort of > > > baseband signal do you have?eg sine,square etc You have to know the > > > carrier frequency as the VCO has to be set to this frequency.If it is not > > > centred properly there will be a dc offset on the phase detector output > > > which will give no end of problems. > > > Maybe you should tweek the VCO setup frequency (fset in my Matlab code) > > > until it locks in that case. > > > The Matlab code is quite closs to a real PLL except it has a sinusoidal > > > VCO (which can be changed to a square wave). As it is type II (an initial > > > Bode plot roll off of -12dB/decade - at low frequencies) then the tracking > > > is optimal provided you watch the stability. The span ratio should be 10 > > > mostly and this gives a good phase margin (57 degrees or there abouts) > > > > > > > > > > > > > > > > > > Tom > > I suppose I now have to ask how you are generating the FM. A PLL will not lock > if there is no power at the carrier which is what you are suggesting. The same > goes for double sideband supressed carrier - where you first have to square the > signal and lock onto 2fc instead of fc. For test purposes I normally just used > two bench oscillators - one with a sweep input.Feed the modulating signal into > the second oscillator which is set to your carrier frequency. This is tried and > tested. Another thing you can do is this - just feed a carrier signal > (unmodulated) into the PLL - the output (of the filter) should be zero or there > abouts when locked. If you then slowly sweep the signal - manually upwards or > downwards the demodulated signal should show a slowly moving dc signal moving > either upwards or downwards in potential depending on whether you are + or - the > carrier frequency ie you are FMing by hand slowly. The PLL should definately > lock into that. Another check with a single carrier is to look at the VCO output > - it should be in quadrature when locked - easy to see for a single unmodulated > carrier of course. If this is not the case then it will not work. > > Finally and most importantly the PLL I have has a multiplier as a phase > detector. This means that if the amplitude of the FM signal is too big (or too > small) the loop gain of the PLL gets increased or decreased and can cause > instability. You can see this if you draw an open loop Bode plot. At present it > is set up for unity amplitude. In a real PLL there is usually a hard limiter > before the phase detector (not a good idea at low SNRs by the way - it can make > things worse!). > > Hope this helps > > Tom
Anotehr issue (though I don't hink this is your problem here) is sampling. Unlike in ordinary DSP where you can sample at twice the highest frequency of interest, for a PLL you need to follow the 10:1 rule ie sample 10 times faster. For a 12kHz carrier you would require a unity gain bandwdth of nominally 2*12kHz/10 = 2.4kHz. Sampling ten times higher than this is 24kHz or greater which is fine for you as you sample at 48kHz.A PLL is of course a closed loop system and when sampled it has an inherent one step delay which eats into the phase margin - hence the 10:1 rule in control systems and 2:1 in DSP! Tom
Tom,

I am using an FM signal generator and downconverting the signal to
12k.  I don't know what the modulation index is but the signal looks
like it occupies +/- 3k or so.

I am sure that if I run the carrier only (I tested this but not with
your pll) and sweep it as you suggest, the pll will track it.

The problem as I see it is when I use the 400hz tone modulation from
the signal generator the 12khz nulls due to the modulation.  I
recorded some FM two-way voice signals and they follow the same rule,
though since the PL tone is present, they also null with no voice
input.

So I would think I need to recover the carrier as an average of the
+/- excursions from 12k unless I am reading this wrong.

If I understand it correctly, when you generate data with matlab, you
are adding or subtracting the phase of the modulation (times the
index) to the 12k signal and then taking the cos of the result.  This
makes sense but doesn't look the same as real data on an fft plot.  It
might be that the real signal has a multiplicity of sidebands out to
the IF filter?

I am missing something since I know PLL's lock to FM voice signals.
Tom,  I forgot to mention that my data gives like results to setting
the parm delf in your code to > 2500.   Changing spanp in your code
cleans it up using your input but not mine.  I need to look at it
closer to see what is going wrong.
lightmetal wrote:

   ...

> I am missing something since I know PLL's lock to FM voice signals.
Why not? Analog PLLs demodulate voice just fine. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������

lightmetal wrote:

> Tom, > > I am using an FM signal generator and downconverting the signal to > 12k. I don't know what the modulation index is but the signal looks > like it occupies +/- 3k or so. > > I am sure that if I run the carrier only (I tested this but not with > your pll) and sweep it as you suggest, the pll will track it. > > The problem as I see it is when I use the 400hz tone modulation from > the signal generator the 12khz nulls due to the modulation. I > recorded some FM two-way voice signals and they follow the same rule, > though since the PL tone is present, they also null with no voice > input. > > So I would think I need to recover the carrier as an average of the > +/- excursions from 12k unless I am reading this wrong. > > If I understand it correctly, when you generate data with matlab, you > are adding or subtracting the phase of the modulation (times the > index) to the 12k signal and then taking the cos of the result. This > makes sense but doesn't look the same as real data on an fft plot. It > might be that the real signal has a multiplicity of sidebands out to > the IF filter? > > I am missing something since I know PLL's lock to FM voice signals.
When you say the 12kHz nulls does it sweep up and down from a centre frequency od 12kHz? ie set the modulating frequency to something really small - say 2HZ - if possible. If there is no sign of the carrier then that woudl explain why the PLL cannot lock. When you down-convert maybe the IF filter is set at the wrong centre frequency. In any case you can do a test by FMing a carrier at 12kHz and skip the down convertor - do it direct as a test. Maybe I can ask you a few questions. I have read a little bit about sofware radio. Just how much of it is software? Is the front end still hardware ie the RF amp, down convertor etc? How do you do the tuned circuit if you want an AM radio for instance (well I suppose I can guess). Tom