May
2006, Issue 190
ARM-Based
Modern Answering Machine
Philips
ARM Design Contest 2005 First Prize
FSK
SECRETS
An
FSK demodulator demodulates the caller ID information
from the telephone line. A simple edge detector followed
by a counter can be used to demodulate FSK even on the
tiniest 8-bit microcontroller. These demodulators perform
well when fed with a perfect signal, but they show limited
performance in real (noisy) applications. I couldn’t
run such a demodulator on my DSL-equipped telephone
line. I needed a high-performance FSK detector.
Interestingly,
it’s hard to find information about demodulating FSK
without using an edge detector. One semiconductor company
that shall remain nameless even turned the source code
from an application note into data statements (.word
xxxxh) in the heart of an FSK demodulator in an obvious
effort to hide the secret of FSK demodulation. After
searching the ’Net for some time, I finally found the
technical note, “FSK: Signals and Demodulations,” in
which author Bob Watson describes a filter-type approach
to the demodulation of FSK signals.
I
also found a practical implementation in the ham radio
world: a data transmission system called packet radio
can use FSK modulation. A radio link is generally a
poor media for data transmission. Noise, distortion,
and phase shift are common impairments that affect the
signal. The receiver must be robust enough to take care
of these impairments.
The
FSK system used by ham radio operators is similar to
the Bell 202 standard telephone companies use to carry
caller ID information. The signaling speed is 1,200
bps. The frequency for a 0 is 2,200 Hz. The frequency
for a 1 is 1,200 Hz.
There
are also some differences. For example, packet radio
is synchronous, and caller ID is asynchronous. That
doesn’t really affect the signal processing though.
A practical implementation of the secretive FSK demodulation
involves two filters tuned to the 0 and 1 frequencies.
The
demodulator uses four tables. The coeffloi[] and coeffloq[]
tables are initialized with the cosine and sine components
of eight samples at low frequency (1,200 Hz). coeffhii[]
and coeffhiq[] have eight samples at high frequency
(2,220 Hz). Every time a sample is retrieved from the
ADC, the low- and high-frequency filters are run with
the last eight samples. This process is detailed in
Listing 2.
At
the end of the filter loop, outloi and outloq represent
the phase and amplitude of the 1,200-Hz component of
the input signal. outhii and outhiq represent the phase
and amplitude of the 2,200-Hz component. I’m not interested
in the phase information, so I can just calculate the
total energy in each filter by taking the sum of the
squared I and Q component (see Figure 3). I can then
subtract the energy detected in the low filter from
the energy detected in the high filter. If the result
is positive, then a high frequency (2,200 Hz, bit 0)
is assumed. If it’s negative, a low frequency (1,200
Hz, bit 1) is assumed.
|

(Click here to enlarge)
|
Figure
3—Check out the FSK demodulator. The last eight
received samples are processed through four independent
filters. The I and Q components for each frequency
are then squared and added together. The filter
with the highest energy wins! |