19

I'm not sure if this is a math or Mathematica question, but I'm posting it here because I'm interested in possible Mathematica tools/functions to solve the problem.

I'm stuck. I want to simulate the effect of a EMP (ElectroMagnetic Pulse) disturbance on an FM signal. Here's my code:

f1[t_] := Sin[t]; (* baseband signal *)
f2[t_] := Sin[15 t]; (* carrier *)
f3[t_] := Sin[15 t + 8 f1[t]] ; (* antenna signal *)
f4[t_] := UnitTriangle[2 (t - 4)]; (* lightning EMP *)
f5[t_] := f3[t] + f4[t]; (* received signal *)
Plot[{f5[t], f1[t]}, {t, 0, 20}]

which results in this plot:

enter image description here

So far so good, but here I am stuck. I want to demodulate the received signal to see the effect of the EMP on my baseband signal, and I don't know how to do this. The signal is there, I can see it (and hear it when I listen to the radio).

I prefer a continuous-time solution, because that's what my radio also works in, but if necessary a discrete-time solution is also welcome.

stevenvh
  • 6,866
  • 5
  • 41
  • 64
  • 2
    perhaps [dsp.se] would be a better location... – rm -rf Sep 05 '12 at 06:57
  • It seems to be more suited to dsp.SE, yes; I'd migrate it there if you ask... – J. M.'s missing motivation Sep 05 '12 at 06:59
  • @R.M. - Oh, I didn't know we have that as well, thanks for the tip. BTW, nothing Mathematica can do for this? Those Signal Processing guys tend to do everything digitally... – stevenvh Sep 05 '12 at 06:59
  • @J.M. - Same question as I asked R.M.: nothing Mathematica can do for this? If not, please migrate. Thanks. – stevenvh Sep 05 '12 at 07:02
  • FM demodulation can be done in Mathematica, but as far as I know, there are no functions or packages for signal processing in general (I wish there was as much support for it as there is for other fields). You can't easily cook up FIR/IIR filters, for instance. If you want a starting point, the equivalent function in MATLAB is fmdemod (if you have the communications toolbox). Since the question is rather conceptual, I'd recommend migrating to [dsp.se]. I'm sure you know enough Mathematica to implement it yourself:) – rm -rf Sep 05 '12 at 07:18
  • Maybe hold it for some time to give a chance to other people to look at it and if no answer comes then transfer? – Vitaliy Kaurov Sep 05 '12 at 07:24
  • Since @R.M. brought it up: those with MATLAB might want to take a look at the M-file for fmdemod() and think about how to adapt the algorithm there to Mathematica... – J. M.'s missing motivation Sep 05 '12 at 07:49
  • Do you need to separate EMP from the rest or carrier from the rest? – Vitaliy Kaurov Sep 06 '12 at 04:59
  • @Vitaliy - I want to demodulate the signal as received, so including the spike, but without taking any particular action towards it, so I can see how it affects the base signal. – stevenvh Sep 06 '12 at 06:11
  • @stevenvh, Check out my edit below and tell me if that works. – kale Sep 06 '12 at 21:09

1 Answers1

20

Here is my port of fmmod/fmdemod from MATLAB to Mathematica.

First off, I know very very little about signal processing, but I have verified that this function gives the same answers as the MATLAB function.

  1. fmmod: uses the message signal x to modulate the carrier frequency fc (Hz) and sample frequency fs (Hz), where fs > 2*fc. freqdev (Hz) is the frequency deviation of the modulated signal.

    fmmod[x_, fc_, fs_, freqdev_] := Module[{t1, intx}, If[fs < 2*fc, Return[$Failed]];
    t1 = Range[0, ConstantArray[#2 - 1, #1] & @@ Dimensions[x]/fs, 1/fs];
    intx = Accumulate[x]/fs;
    Cos[2*Pi*fc*t1 + 2*Pi*freqdev*intx] // Transpose];
    
  2. fmdemod: demodulates the FM modulated signal y at the carrier frequency fc (Hz). y and fc have sample frequency fs (Hz). freqdev is the frequency deviation (Hz) of the modulated signal. I'm still fighting with this algorithm. Mainly the unwrap function. Maybe someone can help.

Hope this helps somewhat.

EDIT: Okay, I've had a little more time to stew on this. Sadly, I can't get a working continuous function with MATLAB's method (using the Hilbert transform). Here is a discrete fmdemod procedure that returns a demodulated signal. This uses J. M.'s discrete Hilbert transform found here. I also found an Unwrap function here.

For your example, let's define a couple necessary functions first.

hilbert[data_?VectorQ] := Block[{n, e},
   e = Boole[EvenQ[n = Length[data]]];
   InverseFourier[PadRight[
      ArrayPad[ConstantArray[2, Quotient[n, 2] - e], {1, e}, 1], 
      n] Fourier[data, FourierParameters -> {1, -1}], 
    FourierParameters -> {1, -1}]] /; And @@ Thread[Im[data] == 0]

UnwrapPhase[data_?VectorQ, tol_: Pi, inc_: 2 Pi] := 
 FixedPoint[# + 
    inc*FoldList[Plus, 0., 
      Sign[Chop[ListCorrelate[{1, -1}, #], tol] ] ] &, data]

UnwrapPhase[list : {{_, _} ..}] := 
 Transpose[{list[[All, 1]], UnwrapPhase[list[[All, -1]]]}]

Now to the main function:

fmdemod[y_, fc_, fs_, freqdev_, iniphase_] := Module[{t1, yq},
   t1 = Range[0, (Length[y] - 1)/fs, 1/fs];
   yq = hilbert[y]*Exp[-I*2 Pi*fc*t1 - iniphase];
   (Prepend[Differences[UnwrapPhase[Arg[yq]]], 0]*fs)/(2 Pi*freqdev)];

So using:

f1[t_] := Sin[t]; (* baseband signal *)
f2[t_] := Sin[15 t]; (* carrier *)
f3[t_] := Sin[15 t + 8 f1[t]] ; (* antenna signal *)
f4[t_] := UnitTriangle[2 (t - 4)]; (* lightning EMP *)
f5[t_] := f3[t] + f4[t]; (* received signal *)
Plot[{f5[t], f1[t]}, {t, 0, 20}]

Therefore:

fc = 15; (*carrier frequency*)
fm = 8; (*modulated frequency*)
fs = 100; (*sampling rate*)
t = Range[0., 20, 2 Pi/fs];
y = Sin[fc* t + fm* Sin[t]] + UnitTriangle[2 (t - 4)];
z = fmdemod[y, fc, fs, 1, 0];
ListPlot[{Transpose[{t, z}], Transpose[{t, fm*Sin[t + Pi/2]}]}, 
 Joined -> True]

Which outputs a demodulated signal with lightning static.

Mathematica plot

BTW, verified in MATLAB as z = fmdemod(y,15,100,1):

MATLAB plot

kale
  • 10,922
  • 1
  • 32
  • 69
  • Is that "unwrap" as in phase unwrapping? There may be something here that can help. – Simon Woods Sep 06 '12 at 08:31
  • @SimonWoods, yep. I had the entire algorithm working (late) last night, but wasn't getting the same answers as MATLAB. The pieces I'm most unsure of is the Hilbert transform. I used J.M.'s discrete transform here: http://mathematica.stackexchange.com/questions/341/implementing-discrete-and-continuous-hilbert-transforms. I figured out diff = Differences, angle = Arg. At the end of the night, I just gave up. – kale Sep 06 '12 at 11:08
  • 1
    +1 for investing time and taking on a challenging task ;) – Vitaliy Kaurov Sep 06 '12 at 21:16
  • @Vitaliy, Thanks. This process just reaffirmed my hatred of MATLAB syntax. – kale Sep 07 '12 at 00:32
  • I tweaked your formatting a bit. Just a tiny note: Rest[FoldList[Plus, 0, x]] is more compactly done as Accumulate[x]. – J. M.'s missing motivation Sep 07 '12 at 10:00
  • @J.M. Crap. I knew when I was typing that, I was thinking, there's probably already a function for this. – kale Sep 07 '12 at 13:40
  • Two tiny changes you might want to consider for fmmod[]: 1. t1 = Range[0, ConstantArray[#2 - 1, #1] & @@ Dimensions[x]/fs, 1/fs] 2. Have the error condition return the built-in symbol $Failed instead of the string "Error". – J. M.'s missing motivation Sep 07 '12 at 13:56
  • @J.M. Changes made. Thanks for the code review. – kale Sep 07 '12 at 14:55
  • @kale - Thanks for your elaborate answer. This looks far worse than I expected. In continuous time I would have expected to see some distortion around the peak, but certainly not the ringing for half a period. Is this an artifact of the discrete time functions. Like I suspect that also the non-causal behavior is due to that, right? – stevenvh Sep 08 '12 at 15:19
  • @stevenh, Yeah, I'm not sure if that's a discrete artifact or not. When I was trying to implement the continuous demodulation, Mathematica was having trouble integrating the received function for the Hilbert transform (as in computing for minutes and a kernel crash). That's why I stuck with the discrete method. – kale Sep 08 '12 at 15:35
  • @stevenh, Also there may be additional FM demodulation algorithms that are different from the fmdemod algorithm implemented here that may handle that EMP pulse better. – kale Sep 08 '12 at 15:37