Best way to demodulate an 8KHz FSK signal

Go To Last Post
32 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I'm working with UC3B512 and I need to demodulate an ETSI ETS300-230 protocol sent with FSK modulation.

My input signal is sampled at 8KHz (by another device) and sent to me through an SSI bus.

I though that the best compromise in terms of speed is to use a zero-crossing detector.

 

Is there someone who could give me some hints on how to start from? I mean, are there some "predefined algorithms" can I use?

 

In attach there is a captured signal, and here its print on Audacity:

 

 

Attachment(s): 

Do, or do not, there is no try.

Last Edited: Thu. Aug 10, 2017 - 07:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The simplest is to square up the signal and measure the period. If the signal is subject to sufficient noise, this technique fails. A more robust technique is to use DSP techniques and use digital filtering. I find the early app notes from Texas Instruments are a good siurce of information. I'm not sure what your etsi spec refers to, but bell/ccitt fsk standards should be well covered.

The usual technique is a bandpass filter followed by a low pass filter and detect the phase change. You might need a auto gain block on the input.

Last Edited: Tue. Aug 8, 2017 - 10:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8KHz might be a bit fast for a plain (not DSP) MCU. Depends on the clock rate and other required tasks.

 

What I get from Google is that ETS200-230 is a piece of hardware from Siemens and the serial protocol is MODBUS. You might have more success in that direction.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim, we're talking AVR32 here. I did 1200 baud fsk on a 40MHz ARM7 using around 2% cpu.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DBarzo wrote:

I'm working with UC3B512 and I need to demodulate an ETSI ETS200-230 protocol sent with FSK modulation.

 

Is there someone who could give me some hints on how to start from? I mean, are there some "predefined algorithms" can I use?

 

You can use the Goertzel algorithm (Link):

 

The Goertzel algorithm is a technique in digital signal processing (DSP) that provides a means for efficient evaluation of individual terms of the discrete Fourier transform (DFT)

 

Like the DFT, the Goertzel algorithm analyses one selectable frequency component from a discrete signal. Unlike direct DFT calculations, the Goertzel algorithm applies a single real-valued coefficient at each iteration, using real-valued arithmetic for real-valued input sequences.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Chuck99,

 

I'm using the Goertzel algorithm to decode the selective calls.

 

I never use it for the FSK modulation since I think the duration of a "tone" is too small.

In selective calls the tones duration is >= 40 msec while here a tone (Space / Mark) lasts >= 200 uSec

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
A more robust technique is to use DSP techniques and use digital filtering. I find the early app notes from Texas Instruments are a good source of information. I'm not sure what your etsi spec refers to, but bell/ccitt fsk standards should be well covered. The usual technique is a bandpass filter followed by a low pass filter and detect the phase change. You might need a auto gain block on the input.
 

 

Hi Kartman,

in fact in this moment I using a "kind" of this.

The problem is that before I used a 20KHz sampling and the filters method worked (more or less), but now, switched to 8KHz (and re-calibrating the filters), it not works anymore.

 

So I thought to switch to use a zero-crossing method...

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

perhaps make some kind of simple auto correlation on the signal (I have used it to find the preamp in AIS)(just find the difference)

 

what is the freq. of the signal compared to sample rate, then it can be like a running difference.    

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:

what is the freq. of the signal compared to sample rate, then it can be like a running difference.    

 

I' didn't understand very well laugh

Can you explain more deep?

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the FSK freq. compared to 8KHz (it's easier if a hole number)

What is the baud rate ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

sparrow2 wrote:

What is the FSK freq. compared to 8KHz (it's easier if a hole number)

What is the baud rate ?

 

The Mark   freq is 1200 Kz

The Space freq is 1800 Hz

 

The baud rate is 1200 bps

 

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think zero crossing will work very well in this case. A single space is 1.5 cycles, and a single mark 1 cycle. Back in the day(maybe 34 years ago), when I was really quite smart, I can remember trying to decode maritime weather fax broadcasts that had a vaguely similar relationship between carriers and baud rate, and it was an effing nightmare. Phase locked loop decoder worked much better, IIRC.

 

That's not to say that throwing a bit of DSP at it wouldn't work, but I was using a 2MHz 6809 s the time, and zero crossing was really the only option.

 

I also agree that Goertzel probably won't be any use at all. It might alert you to the presence of a 1200kHz tone  or an 1800kHz tone, but you knew that already.

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So the problem here is that the 8kHz sampling rate is far too low.

 

Why was that rate chosen?

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks a lot John for your reply!

 

John_A_Brown wrote:
Back in the day(maybe 34 years ago), when I was really quite smart

 

LOL

Nevertheless smartness never die wink

 

 

John_A_Brown wrote:

I don't think zero crossing will work very well in this case. A single space is 1.5 cycles, and a single mark 1 cycle.

I can remember trying to decode maritime weather fax broadcasts that had a vaguely similar relationship between carriers and baud rate, and it was an effing nightmare. Phase locked loop decoder worked much better, IIRC.

 

Have you some points, links or other to look at about PLL decoder in C?

 

Maybe I can share my code, if someone is interested in this topic.

 

John_A_Brown wrote:

I also agree that Goertzel probably won't be any use at all. It might alert you to the presence of a 1200kHz tone  or an 1800kHz tone, but you knew that already.

 

Exactly.

 

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

So the problem here is that the 8kHz sampling rate is far too low.

 

Why was that rate chosen?

 

Yep.

The answer is little bit articulated.

To summarize, I develop on a board attached to a radio device and its forward me the PCM audio samples in different ways..

Actually I take the audio at the sampling rate is 20KHz and my decoder works, but I see some instability problems on the radio (the timing are tight), so I decided to switch to another chain point and, there, the sampling rate is 8KHz.

 

Do, or do not, there is no try.

Last Edited: Tue. Aug 29, 2017 - 12:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Have you some points, links or other to look at about PLL decoder in C?"

'fraid not. I was talking about hardware.

 

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

one thing you have to look at is if the signal is AC coupled ! or true DC. (your problem with 20kHz could be that it's AC! )

 

I have decoded AIS (9600 baud GMSK) with sound sampling of 11.2KHz, but normally I use 48KHz also because that is 5 times the baudrate.  

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:

one thing you have to look at is if the signal is AC coupled ! or true DC. (your problem with 20kHz could be that it's AC! )

I have decoded AIS (9600 baud GMSK) with sound sampling of 11.2KHz, but normally I use 48KHz also because that is 5 times the baudrate.  

 

Unfortunately I cannot decide the sampling rate. It's fixed to 20KHz or 8KHz

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DBarzo wrote:

Hi Chuck99,

 

I'm using the Goertzel algorithm to decode the selective calls.

 

I never use it for the FSK modulation since I think the duration of a "tone" is too small.

In selective calls the tones duration is >= 40 msec while here a tone (Space / Mark) lasts >= 200 uSec

 

From Wikipedia (Link):

Implementations of FSK modems

Reference implementations of FSK modems exist and are documented in detail.

The demodulation of a binary FSK signal can be done using the Goertzel algorithm very efficiently,

even on low-power microcontrollers. (FSK Modulation and Demodulation With the MSP430 Microcontroller - Link)

 

Edit: added missing link.

 

Last Edited: Thu. Aug 10, 2017 - 12:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But will Goertzel work on such short amounts of each frequency? I now that it has an inherent detection time which is at least equal to the number of sample used.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote:

DBarzo wrote:

Hi Chuck99,

 

I'm using the Goertzel algorithm to decode the selective calls.

 

I never use it for the FSK modulation since I think the duration of a "tone" is too small.

In selective calls the tones duration is >= 40 msec while here a tone (Space / Mark) lasts >= 200 uSec

 

From Wikipedia (Link):

Implementations of FSK modems

Reference implementations of FSK modems exist and are documented in detail.

The demodulation of a binary FSK signal can be done using the Goertzel algorithm very efficiently,

even on low-power microcontrollers. (FSK Modulation and Demodulation With the MSP430 Microcontroller - Link)

 

Good find.

Now all the OP needs to do is learn MSP430 assembler. Is that Goertzel, though? I used Goertzel(once) and it doesn't look familiar.

 

 

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

John_A_Brown wrote:

Is that Goertzel, though? I used Goertzel(once) and it doesn't look familiar.

 

I report, you decide.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

But will Goertzel work on such short amounts of each frequency? I now that it has an inherent detection time which is at least equal to the number of sample used.

 

Good point.

 

From embedded.com: The Goertzel Algorithm (Link):

Block size

Goertzel block size N is like the number of points in an equivalent FFT. It controls the frequency resolution (also called bin width).

 

For example, if your sampling rate is 8kHz and N is 100 samples, then your bin width is 80Hz.

 

DBarzo in post#11 wrote:

The Mark   freq is 1200 Kz

The Space freq is 1800 Hz

 

The baud rate is 1200 bps

 

To get 1200 bps, the block size needs to be reduced to 6 which yields a bin width of 1333Hz which will be +/- 667Hz from center frequency.

 

But the Space frequency of 1800 Hz would be inside the bin (533Hz to 1867Hz), so that wouldn't work.

 

I guess that for a baud rate of 1200, Goetzel isn't the way to go.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DBarzo wrote:

Unfortunately I cannot decide the sampling rate. It's fixed to 20KHz or 8KHz

 

If 20kHz works, but 8kHz does not, why not use 20Khz.

It seems that 1200/1800 1200baud is quite information compressed already, so cutting corners to 8kHz is not going to help ? That has far fewer sample points per-bit time. (6.66 vs 16.66)

 

What is the carrier lead time - your capture seems to gate the carrier ?

You could look to Phase/Frequency lock to 1200 base, and then check if there is an expected 1200 follower, or an 1800 follower 

I'm guessing the modulator actually sends 1200 phase modulated too, so as to continue the 1800 slope, and the 1800 has 2 possible images, meaning you have a total of 4 'patterns' to test for 'closest match to'.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote "Good point"

 

And one the OP made back in post #6. Which Brian and I both agreed with.

 

I do think the MSP430 link has legs, though. Although it will require some time to understand exactly what's going on.

 

I am also fairly certain there will be other examples on the web. I just haven't found the right combination of search terms yet... Wikipedia had a Matlab example, but it made little sense to me.

 

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Who-me wrote:

If 20kHz works, but 8kHz does not, why not use 20Khz.

 

I pointed out the reason here.

 

 

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if you have 20kHz working why no just upsample 8KHz (either 2 2.5 or 3 times). And then run the same decoder.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"here the sampling rate is 20KHz and my decoder works, but I see some instability problems on the radio (the timing are tight),"

 

Maybe you could expand on this. I, for one, don't really understand what you're saying here.

 

 

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DBarzo wrote:

Who-me wrote:

 

If 20kHz works, but 8kHz does not, why not use 20Khz.

 

I pointed out the reason here.

 

So you need to tune the 20kHz solution a little ?

The main decision rate is only 1200Hz, but you need to phase align the decision boundaries, hence the questions about preamble and fixed mark times between the space modulations.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Would love to know if you made progress on this.

 

Quebracho seems to be the hardest wood.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi John,

 

yes of course! smiley

Now I'm in holidays (finally! cheeky). I'll update my post next week when I came back to work.

 

PS. I start to test a zero-crossing simulation on PC...for now the result aren't encouraging.

 

Do, or do not, there is no try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, so these are my TESTS until now.

 

What I actually do is quite "stupid": I calculate the length of each half-period and, when I got three of them (the mark is 1.5 period), I "decide" if it is a mark or space:

(don't take this code as "production code" :) )

 


    #define MARK_PERIOD(period)  (period > 800)  && (period <= 1500)  // 1245 uSec
    #define SPACE_PERIOD(period) (period >= 410) && (period <= 800)   // 530  uSec

    #define MARK_HALF_PERIOD(period)  (period > 330)  && (period <= 500)
    #define SPACE_HALF_PERIOD(period) (period >= 100) && (period <= 330)

    // "count" the number of half-periods

    if (MARK_HALF_PERIOD(half_period))
    mark_hp_count++;

    if (SPACE_HALF_PERIOD(half_period))
    space_hp_count++;

    if (++half_period_counter <= 2)
    {
    mark_period += half_period;
    space_period += half_period;  // The space period must be calculated oly for two half-period
    }          

    if (half_period_counter == 3)
    {
    mark_period += half_period;

    if (MARK_PERIOD(mark_period) && (mark_hp_count >= space_hp_count))
    {
        if (!locked)
        {
        locked = TRUE;
        printf("\n>>> LOCKED! <<<\n");
        }

        tot_bits++;
        printf("1");
        mark_hp_count = 0;
    }
    else
    {
        if (SPACE_PERIOD(space_period) && (space_hp_count >= mark_hp_count))
        {
        tot_bits++;
        printf("0"); 

        // Since the space is a period, here I have to "came back" to the previous one
        i--;
        tot_sample_count--;
        half_period_counter = 0;
        half_period -= x;

        space_period = 0;
        mark_period = 0;
        mark_hp_count = 0;
        space_hp_count = 0;
        continue;

        }
        else
        {
        printf("\nERROR\n");
        }

    }

    }

 

 

This approach is sensible to the semi-period threshold.

It works not-so-bad but, when the half-periods are "comparable", problems arise.

As in figure, on the second byte (0x33) my method decode the 3th bit 0 instead of 1 because count its first two half-periods as a space bit. and the "alignment problem" arise...
 

 

If someone have some suggestions... :)

 

Cheers.

Do, or do not, there is no try.

Last Edited: Fri. Aug 25, 2017 - 02:01 PM