FM demodulation

I have a signal that starts out as an 8-bit 120Hz signal that is frequency modulated from 1650Hz (0x00) to 2450Hz (0xFF) that I'd like to sample somehow and reconstruct the original signal.

I have been pulling my hair out trying to figure out a cool way to accomplish this. Is there some cool algorithm that DSP people use to do this?

Thanks for any pointers!

--Keith Brafford

Reply to
Keith Brafford
Loading thread data ...

Homework ? First, you need to define the modulation details, between the Min and Max, is it absolute Hz-Linear, %Hz-proportional, or us-Linear, or %us-proportional.

Decode is not too hard, esp of a high signal/noise signal, as your data freq is

Reply to
Jim Granville

frequency

Hahaha...forgot about that c.a.e phenomenon. No, it's not homework. I developed the hardware to acquire the signal, and I wrote code that uses a 14.4KHz PWM to produce poor-man DAC output to a speaker (with some help from here a few weeks ago).

I have no idea what any of that means. I store a copy of 1/2 of a sine wave in memory, and a table indexed from 0x00 to 0xFF whose entries represent the delta with which I march through the sine wave to produce the desired output.

For instance, if the 120Hz sample I want to transmit is 0x00, I look up index 0x00 in the step table and see 0x23, which means that each output to the PWM ADC is

0x23 steps in the sine wave apart from the last one; at an interval defined by the value at index 0x00 that gives me 1650Hz.

If I continually look up index 0x00 and skip through the sine wave by 0x23 each time I will get a good clean 1650Hz sine wave output.

For each 120Hz data point that I want to modulate, I spend 120 iterations skipping through the sine wave. After the 120th iteration, I do the same thing with the skip value indexed by the next sample point.

The result is a working FM modulation of a signal that you can hear, and that a receiver (which I do not have) can also receive.

What I am trying to do is build my own receiver so I can test the quality of my sender.

What does min and max refer to? 0 == 1650Hz, FF == 2450Hz?

I don't know what these are. Is this related to that uLaw stuff I see in audio codecs from time to time?

--Keith

Reply to
Keith Brafford

One digital solution would be to sample the input stream, do a Fourier transform, and look for the frequency spike that corresponds to transmitted frequency. I'm not sure but I wonder if there'll be some extra spike due to phase distortion?

Another digital solution is to count zero crossings in a 120Hz period and compute frequency from that.

In the above approaches I think the receiver will have to look at the incoming data to determine how to synchronize onto the 120Hz frames, though.

An analog solution would be to run the input into a low-pass RC network to generate a voltage proportional to the input frequency, then sample the voltage with an A2D.

It's late and I'm probably missing an obvious approach... Kelly

Reply to
Kelly Hall

Yes

These refer to how you step from 1650Hz, to 2450Hz. If you are Hz linear, you divide the 800Hz by 256 steps. If you are Hz proportional, each step is 0.189% Sim for time you have 606us to 408us, so time linear dvides that by 256, and % proportional divides it into equal percentage steps.

If you fix your SineCycles, but vary the Timer-INT rate, you will be time-linear

Decode is done via the capture timer of any uC, and you time the period of a single whole cycle and then work backwards from that. A uC will give an answer every whole cycle, so you can average that it you wish in the SW, or let the downstream device average it.

I would favour time linear, as it avoids more quantize errors, and the decoder can have higher precision, plus saves code space and time.

-jg

Reply to
Jim Granville

Of course you can do it using some form of DSP, but the question is do you have enough computing power available...Look at this paper - it's only one solution and try Google to find some more...

formatting link

regards

Dejan

Reply to
Dejan Durdenic

Okay, putting things together, you have 14,400 samples per second, and you used 120 samples for each "tone" representing an 8-bit value. That's 120/14400=8.33mS per tone. Is that correct? If so, that looks awfully short for easy decoding - I count 13 cycles for a 1650Hz signal, and 120 samples of higher frequencies will have fewer cycles.

So, does this mean you have a series of 8-bit numbers, and you want to transmit 120 of them in every second? I guess so, that jibes with the 8.33mS value I got above.

120 iterations at the presumed 14.4kHz sample rate (120 samples per second times 120 'iterations per sample' is 14,400Hz. I think I'm decoding all this now...). I may have just confused data points and iterations, but the product is the same.

It appears that your output is a short tone (that lasts 8.33mS?) for each input byte, with 0 sending 1650Hz, 1 sending 1653.125Hz, 2 sending 1656.25Hz, ... for 256 frequencies. I might call this FSK (Frequency shift keying, though FSK is (almost?) always just two frequencies instead of many) rather than FM.

This requires a "receiver" to be able to determine the frequency with resolution of 3 Hz. The longer the tone lasts, the easier this is to do. If the tone is too short, it may be impractical or even impossible. Using 8.33mS tones may not be impossible, but it sure seems impractical, certainly for a microcontroller. This could perhaps be done with a DSP but I can see this as being 'challenging' even for experienced DSP designers/programmers. I'd suggest sending each tone for a much longer period of time, and/or spreading out the frequencies ove a much larger range so that one could reasonably distinguish the frequencies (and also important, the transitions between them) using zero-cross timing and counting with a microcontroller. A problem with this scheme is that there is no sync between bytes sent unless consecutive bytes are different. If you send 100 zeroes, it will send a constant 1650Hz tone, and you won't be sure where one byte starts and the next ends. The receiver could count 99 or 101 bytes and never know it missed or added a byte.

Doesn't look like it to me. He's asking how the frequency changes with an increase in the 8-bit number. I'm presuming it's linear with frequency, as it appears you're stepping through a sine table with phase accumulator, with the frequency being the sum of a comstant (that give the lowest frequency of 1650) and the byte to send.

-----

formatting link

Reply to
Ben Bradley

Yes - or ~0.7us if you work in the time-domain.

It depends on the signal/noise of the medium, and the task. The OP has relatively low 120Hz information bandwidth, and may be sending analog data (rather than data packets) that needs galvanic isolation. Even a small uC can resolve to better than 0.7us, and do this every cycle (400-600us) - so you can design a FM receiver, that will read the IP, and give a time(1/frequency) result. This could work well doing isolated/remote sending of temperature,voltage or similar analog values.

If the objective is to build a data-modem, that's a different story, needing frame sync info, and a means of handling signal/noise and group delay variations, with low bit error rates.

-jg

Reply to
Jim Granville

That would be true for traditional designs. However, given the way that the poster generates the tone, the frequency will have the same error as the symbol timing. That is, the receiver can account for it.

Reply to
jetmarc

Damn, you beat me to it. I'd say thats the engineering approach. Feed it via a diode and pulldown resistor to a digital pin and time the inter-pulse (rising edge or falling edge) time, via interrupts, polling or any way you wish. If you need better bit resolution, count the total time for several pulses. Sampling at faster than 120Hz would allow you to run a software phase locked loop to track the modulation clock.

*Nods* also a good approach, especially if the processor has a 10 or 12 bit ADC on board.

I know it's not, but it does sound like one of those undergrad engineering questions that's testing your ability as an engineer rather than your scientific knowlege. Then again, let us not forget that for every problem, there is one answer that is simple, elegant, and utterly wrong.

Mike

Reply to
MSC

Please note that a low-pass filter does not alone make a frequency- to-voltage conversion. Instead, it computes the average value of the incoming signal. For a constant duty cycle pulse stream, the output from the low-pass stays constant even if the frequency changes, as long as the frequency is sufficiently far above the filter corner frequency.

The input must first be shaped into a constant-width pulse stream with e.g. a monostable (urgh!) before filtering.

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio

Precisely. I am sending a 120Hz analog signal. I will also be doing some FSK between 1650Hz and 2450Hz, but I think I need to understand how I am going to demodulate the analog signal before I try to understand FSK.

IP?

--Keith

Reply to
Keith Brafford

you

Thanks!

--Keith

Reply to
Keith Brafford

I'd suggest: Using the CAPTURE mode of any capable uC, and you can get a result every cycle, then average as needed - will depend on the signal/noise of the medium. Your numbers need around 700ns for 8 bit resolve in linear-time-domain modulation, but timers should be able to resolve 4-8 times better - if CPU time allows, measure to the MAX uC precision and discard bits later. Do the same on TX, and you may be able to send better than

8 bits, and by doing time-domain-linear modulations, table look-up quantize effects are avoided. Use a simple bandpass filter/comparitor on RX, and take care to switch TX modulation Freq on full cycle zero crossings

-> "Input"

-jg

Reply to
Jim Granville

What exactly am I capturing with the uC? I thought that input capture counted cycles until a digital signal asserts itself. Am I really just looking for the zero-crossings?

--Keith

Reply to
Keith Brafford

Yes - mostly they capture on an input edge

Yes, that gives the frequency info - and the uC can total.average as you like. With the large ratio you have between carrier and data bandwidths you do not need really anything fancier.

- ie you are a long way simpler than a 57K modem :)

-jg

Reply to
Jim Granville

What do I do to the signal (in hardware) to make its zero-crossings work with the input capture?

--Keith

Reply to
Keith Brafford

Use an analog comparator to threshold the input signal. For noise cancellation, some hysteresis may be in order (use a little positive feedback).

HTH

Tauno Voipio tauno voipio @ iki fi

Reply to
Tauno Voipio

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.