Frequency Modulation (FM) is one of the oldest communication techniques for high fidelity transmission. Its digital counterpart, Frequency Shift Keying (FSK), also plays a crucial role in applications requiring low receiver complexity. In an FSK scheme, digital information is transmitted by changing the frequency of a carrier signal. It can also be mixed with Chirp Spread Spectrum (CSS) for low-power long-range communication as used in LoRa PHY.

## Binary FSK

Binary FSK (BFSK) is the simplest form of FSK where the two bits 0 and 1 correspond to two distinct carrier frequencies $F_0$ and $F_1$ to be sent over the air. The bits can be translated into symbols through the relations

\begin{equation*}

\begin{aligned}

0 \quad & \rightarrow \quad -1 \\

1 \quad & \rightarrow \quad +1

\end{aligned}

\end{equation*}

This enables us to write the two frequencies $F_i$ with $i ~ \epsilon ~ \{0,1\}$ as

\begin{equation*}

F_i = F_c + (-1)^{i+1} \cdot \Delta_F = F_c \pm \Delta_F

\end{equation*}

where $F_c$ is the nominal carrier frequency and $\Delta_F$ is the peak frequency deviation from this carrier frequency. The signal waveform can now be written as

\begin{equation}\label{eqFSKwaveform}

s(t) = A \cos \left(2\pi F_i t +\phi \right)= A \cos\Big[2\pi \big(F_c \pm \Delta_F\big) t + \phi\Big]

\end{equation}

where $0\le t \le T_b$ and $\phi$ is an arbitrary phase. Figure below displays a BFSK waveform for a random stream of data at a rate of $R_b = 1/T_b$. Note that we are not distinguishing between a bit period and a symbol period because both are the same for a binary modulation technique.

One of the most interesting modulation schemes in digital communication, namely Minimum Shift Keying (MSK), is a version of FSK. Let us turn towards the mostly used block for FSK demodulation in GNU Radio.

## Quadrature Demod Block

As far as an FSK receiver is concerned, a commonly used method in GNU Radio implementations is the Quadrature Demod block. A block diagram of such a detector is reproduced below from GNU Radio wiki where the block Quadrature Demod is encircled in red. Here, a larger flowgraph can be viewed by clicking on the image below.

Such a structure can be used to demodulate several frequency modulation schemes such as FM, FSK and GMSK. The input to the block is the complex baseband waveform. Within the block, a product of the one-sample delayed input and the conjugate original signal is computed, the output of which is a complex number.

\begin{equation*}

z(nT_S) = s(nT_S)\cdot s^*\left[(n-1)T_S\right]

\end{equation*}

The argument of this complex number is the signal frequency relative to the sample rate multiplied with the gain, as we will see later.

## Demodulating an FSK Signal

To see the role of a Quadrature Demod block in demodulating an FSK signal, let us consider a complex version of the FSK modulated signal described in Eq (\ref{eqFSKwaveform}) which just showed the real part.

\begin{equation*}

s(t) = A e^{j \left(2\pi F_i t + \phi\right)}

\end{equation*}

This signal is sampled at a rate of $F_S=1/T_S$ where $T_S$ is the sample period.

\begin{equation*}

s(nT_S) = A e^{ j \left(2\pi F_i nT_S + \phi\right)} = A e^{j \left(2\pi \frac {F_i}{F_S} n + \phi\right)}

\end{equation*}

### Generating the Waveform

In a very simple GNU Radio Companion flowgraph below, an FSK waveform is generated with center frequency 1.5 kHz and a frequency deviation of 500 Hz. This results in two carrier waves, one at 1 kHz representing a 0 and the other at 2 kHz representing a 1. This is implemented in the following manner (click on the image to enlarge it).

- Multiply the bits, e.g., 0,1,1,0,0,1,…, with the higher frequency wave at 2 kHz that produces a 2 kHz wave for 1 bits and a blank space of zeros for 0 bits.
- Multiply one minus the bits, e.g., 1- (0,1,1,0,0,1,…), with the lower frequency wave at 1 kHz that produces a 1 kHz wave for 0 bits and a blank space of zeros for 1 bits.
- Add the two waves together thus generating a BFSK waveform.

### Frequency Xlating FIR Filter

At the Rx side, a frequency translating FIR filter with a center frequency of 1.5 kHz is employed. According to its documentation, this block performs a frequency translation on the signal, as well as downsamples the signal by running a decimating FIR filter on it. This operation places the modulated signal at baseband and hence the two possible frequencies are now located at $\pm 500$ Hz. This is shown by two impulses at $\pm 500$ Hz below that is the output of the flowgraph described above (click on the image to enlarge it).

The command firdes.low_pass(1.0,samp_rate,900,300) uses a lowpass filter with unity gain, a sample rate of 32 kHz, a cutoff frequency of 900 Hz and a transition bandwidth of 300 Hz. According to GNU Radio documentation, the cutoff frequency is meant to be at the center of transition band in firdes.low_pass function. This implies that the edge of passband lies at 900-300/2=750 Hz, well beyond the impulse location of 500 Hz. A decimation operation can also be used at this stage as an argument of Frequency Xlating FIR Filter to operate only at a minimum number of samples dictated by the sampling theorem. However I am not decimating the signal here since my objective is to display the proper waveforms for which a higher the number of samples produces better results.

### Operation of Quadrature Demod Block

Now the Quadrature Demod block computes the product of this signal with a unit delayed and conjugated version of itself.

\begin{equation*}

z(nT_S) = s(nT_S)\cdot s^*\left[(n-1)T_S\right]

\end{equation*}

This simplifies to the following expression.

\begin{equation*}

\begin{aligned}

z(nT_S) &= A e^{j \left(2\pi \frac{F_i}{F_S}n + \phi\right) }\cdot A e^{-j \left(2\pi \frac{F_i}{F_S}(n-1) + \phi\right) } \\

&= A^2 e^{j \left(2\pi \frac{F_i}{F_S}n + \phi – 2\pi \frac{F_i}{F_S}(n-1) – \phi\right) }\\

&= A^2 e^{j \left(2\pi \frac{F_i}{F_S}\right)}

\end{aligned}

\end{equation*}

Taking its argument reveals the underlying modulation frequency.

\begin{equation}\label{eqArg}

\mathrm{arg} \big\{z(nT_S)\big\} = 2\pi \frac{F_i}{F_S}

\end{equation}

Considering that $F_i$ is simply a sequence of two different frequencies depending on whether out input was a 0 or 1, the output of this operation is a square waveform similar to a Pulse Amplitude Waveform (PAM) with a modulation sequence of $\pm 2\pi/F_S$ (corresponding to $\pm 1$). This is the important point. The binary frequency modulated waveform has been sort of converted into a pulse amplitude waveform due to this operation. This stream of -1s and 1s can be detected in the Quadrature Demod Output shown in the figure above. This stream can be passed through a binary slicer to produce the final bit stream.

### Timing Synchronization

Any of the well known timing recovery algorithms can be applied for synchronization purpose. At first sight, it does not make sense that algorithms originally devised for a linear modulation scheme are applicable to an FSK waveform. Indeed, this is a great cause of confusion in SDR beginners. However, after the above explanation of demodulation process, we can see that a binary FSK waveform is indeed a square wave signal similar to a linearly modulated sequence. Therefore, we can apply any well known timing synchronization scheme such as a Gardner algorithm, polyphase clock sync, Mueller and Müller clock recovery, and so on. You can also read how carrier and timing are acquired for an MSK waveform.

A word of caution: GNU Radio is a tool to implement signal processing algorithms while leaving the underlying algorithms choice and development for custom blocks to the user. For a lab demo or a small project, there is no harm in performing the timing synchronization through any of the above mentioned techniques. On the other hand, a professional solution working under several different operating conditions should be more suited to the exact problem itself.

The problem here is that the argument function $\mathrm{arg}\{\cdot\}$ used in Eq (\ref{eqArg}) delivers the principal value of the argument which is highly non-linear and an unwrapping process would be needed. This becomes difficult as noise does not translate nicely from arguments to a linear representation and severely limits the performance at moderate to low SNRs.

timing recovery does not work with this scheme. The timing recoveries use interpolation using a polynomial filter which does not work with square like waves.

You’re right matt if the demod output consists of nice square waves as I plotted above for demonstration purpose. But most FSK systems do not produce such perfect square waves. A timing sync algorithm would work well with peaks at symbol centers at the input. The discussion and comments in this link might also help you. https://dsp.stackexchange.com/questions/67107/symbol-synchronization-for-gfsk-fsk-signals-in-gnu-radio

IMHO edge of the passband lies at 900 Hz because there is cut-off frequency. I don’t know why you subtracted 900 – 300 where 300 Hz means transition width. Is it a typo or I did grasp something?

Thanks for pointing that out. Although cutoff frequency should have been at the edge of passband, there is a slight confusion in GNU Radio documentation. The cutoff frequency in firdes.low_pass() is meant to be at the center of transition band, i.e. it should be 900-300/2=750 Hz here.