Budapest University of Technology and Economics
Department of Broadband Infocommunications and Electromagnetic Theory

András Retzler

Integrating digital demodulators into OpenWebRX
MSc Thesis

Thesis supervisor:
Péter Horváth, PhD
Associate Professor

Contents
1 Abstract...........................................................................................................................5
1.1 Összefoglaló............................................................................................................6
2 Introduction to OpenWebRX and digital modulations...................................................7
2.1 Recent improvements on OpenWebRX and CSDR................................................9
2.2 CSDR used for tracking Schiaparelli EDM lander...............................................10
3 Digital modulations......................................................................................................12
3.1 Motivation behind digital mode support...............................................................12
3.2 Results of modifications.......................................................................................14
3.3 Changes to the OpenWebRX protocol..................................................................15
3.4 Digital modulations in general..............................................................................16
3.5 Functional stages of processing in a digital modem.............................................19
3.6 Digital modes on amateur radio bands..................................................................21
3.7 Digital modes in consumer devices......................................................................22
4 A BPSK31 demodulator................................................................................................23
4.1 Implementation with CSDR..................................................................................25
4.2 Automatic gain control..........................................................................................27
4.3 Symbol timing recovery........................................................................................28
4.4 Implementation of non-data aided timing recovery..............................................34
4.5 Symbol timing recovery performance measurements...........................................38
4.6 Carrier recovery....................................................................................................41
4.7 Synchronization in a differential PSK receiver.....................................................46
4.8 Varicode decoder...................................................................................................48
4.9 Resource usage......................................................................................................50
5 More applications of CSDR.........................................................................................52
5.1 Generating BPSK31..............................................................................................52
5.2 Demodulating BPSK63.........................................................................................53
5.3 BPSK31 with different pulse shape......................................................................54
5.4 Costas loop for carrier recovery............................................................................55
5.5 Demodulating RTTY............................................................................................59
5.6 FSK demodulation................................................................................................61
5.7 Serial line decoder.................................................................................................642

5.8 Baudot decoder.....................................................................................................65
5.9 Demodulating M-FSK..........................................................................................66
5.10 Demodulating FSK signals transmitted using the CC1111 wireless MCU.........67
5.11 Generating additive white Gaussian noise..........................................................73
5.12 Functions helping development..........................................................................75
6 Conclusion....................................................................................................................77
7 Acknowledgement........................................................................................................78
8 Bibliography.................................................................................................................793

HALLGATÓI NYILATKOZAT
Alulírott Retzler András, szigorló hallgató kijelentem, hogy ezt a diplomatervet meg
nem engedett segítség nélkül, saját magam készítettem, csak a megadott forrásokat(szakirodalom, eszközök stb.) használtam fel. Minden olyan részt, melyet szó szerint,
vagy azonos értelemben, de átfogalmazva más forrásból átvettem, egyértelműen, aforrás megadásával megjelöltem.
Hozzájárulok, hogy a jelen munkám alapadatait (szerző, cím, angol és magyar nyelvű
tartalmi kivonat, készítés éve, konzulens neve) a BME VIK nyilvánosan hozzáférhető
elektronikus formában, a munka teljes szövegét pedig az egyetem belső hálózatán
keresztül (vagy hitelesített felhasználók számára) közzétegye. Kijelentem, hogy abenyújtott munka és annak elektronikus verziója megegyezik. Dékáni engedéllyel
titkosított diplomatervek esetén a dolgozat szövege csak 3 év eltelte után válik
hozzáférhetővé.
Kelt: Budapest, 2017. 05. 21.
….................................................
Retzler András

4

1 Abstract
OpenWebRX, a web-based SDR receiver application (the topic of my Bachelor's thesis),
is an online communication receiver that supports AM/FM/SSB/CW demodulation, andits web user interface helps accurate tuning with a real-time updated spectrogram of thereceived band. It allows remote access over the Internet, and multiple users can use it
for receiving different signals simultaneously.
Throughout my Master's thesis project, I have added a demodulator for BPSK31, whichis commonly used on amateur radio bands today, to the server-side signal processing.
The user can select a BPSK31 signal to receive by clicking on the waterfall diagram on
the web user interface, and the decoded data appears in the browser afterwards.
The CSDR software package that carries out digital signal processing has been extended
with new functions for BPSK31 and RTTY demodulators in a way that it is possible toreuse the same functions for receiving other BPSK and M-FSK modulated signals as
well. This work included implementing several fundamental synchronization techniques
used in digital demodulators.

5

1.1 Összefoglaló
Az OpenWebRX webes rádióvevő alkalmazás (amely a BSc szakdolgozatom témája
volt),egy

olyan

kommunikációs

vevőt

valósít

meg,

amely

támogatjaaz

AM/FM/SSB/CW üzemmódú jelek vételét, és webes kezelőfelülete a vételi sávról
készített, valós időben frissített spektrogrammal segíti a hangolást. Lehetővé teszi azInterneten keresztüli távoli elérést, és egyszerre több felhasználó is használhatja
különböző jelek vételére.
MSc diplomamunkám során a rádióamatőr sávokban gyakran használt BPSK31 jelek
vételére alkalmas demodulátorral egészítettem ki a szerveroldali jelfeldolgozást. A
webes felületen a felhasználó a vízesés diagramra kattintva kiválaszthatja a venni kívánt
BPSK31 jelet, ezt követően a böngészőben megjelenik a dekódolt adat.
A jelfeldolgozást végező CSDR programcsomag kiegészült a BPSK31 és RTTY
demodulátorokhoz szükséges funkciókkal, ezek azonban úgy lettek megvalósítva, hogyhasználhatók legyenek más BPSK és M-FSK modulált jelek vételére is. A munkához
hozzá tartozott egyes, a digitális demodulátorokban használt alapvető szinkronizációs
módszerek implementálása.

62 Introduction to OpenWebRX and digital modulations
OpenWebRX is an open source software defined radio (SDR) receiver application witha web interface, which allows amateur radio operators to set up remote receivers
accessible over the Internet. OpenWebRX supports a variety of SDR hardware
peripherals as input devices, and it can demodulate analog AM, FM, SSB and CW
signals, which are actively used on the amateur radio bands today.
OpenWebRX consists of a server application that performs the demodulation andstreams the resulting audio to the clients, and also a frontend application that provides aconvenient user interface in the client web browser (see Figure 1 and 2). Multiple users
can connect to the server at the same time, and each of them can select a channel tolisten to, by clicking on a particular signal on the waterfall display.

Figure 1: Original web user interface of OpenWebRX

7

Figure 2: Block diagram of OpenWebRX web-based SDR software [2]The technologies used to build the web interface include HTML5 and Javascript, withthe backend implemented in python. In the background, a digital signal prcessing (DSP)
library, libcsdr and a command-line tool, CSDR is performing the signal processing
tasks. As good performance was a design goal for CSDR, it was implemented in C/C++.
The build scripts allow us to constantly monitor the auto-vectorization results of the
GCC compiler. To accelerate execution on ARM CPUs, some algorithms were
optimized with inline assembly.
CSDR was designed to perform simple DSP on signals directly from the command-line,
and today its use is not limited to OpenWebRX. CSDR processes with different
processing functions can be chained after each other via FIFOs provided by the Linuxkernel, thus a simple signal processing dataflow system can be implemented with asingle command (see Figure 3).

Figure 4: Using CSDR to build an NFM demodulator from the command-line
While finishing my Bachelor’s thesis on OpenWebRX and CSDR, the source code of
the software projects have been published as open source on the GitHub project hosting
website.
I have also built an own website under the domain name SDR.hu (see Figure 7), where
people can access a list of publicly available OpenWebRX servers around the world. At
the time of writing, the website lists more than 100 receivers on 6 continents. There arereceivers using OpenWebRX (or its modified versions) in countries like the UnitedStates, Iceland, Australia and Japan.
8

Figure 7: Map of active receivers on SDR.hu
In this chapter, I am writing about OpenWebRX and CSDR in general. In Chapter 3, I
am telling more about the motivation behind digital mode support in OpenWebRX, andI am writing about the basics of digital modulations. In Chapter 4, each functional unitof the BPSK31 demodulator that has been integrated into OpenWebRX is described indetail. In Chapter 5, other results of this work are described, like an RTTY demodulator(not integrated into OpenWebRX yet), modified versions of the BPSK31 demodulator,and decoding the wireless transmissions sent by an MCU with built-in RF capabilities,
using CSDR. I feel that all of these are closely related to the topic, and show various
applications of the new features introduced in CSDR.

2.1 Recent improvements on OpenWebRX and CSDR
After finishing OpenWebRX as my Bachelor's thesis project in 2014, I continued towork on it, fixing software bugs and adding new features. Since the initial release, thefollowing new features were added:•

The user interface has been improved with squelch and waterfall controls,
waterfall color auto-adjustment, zoom buttons, and browser support for devices
running iOS.

•

OpenWebRX can now be used with most consumer SDR hardware devices

9available on the market, including AirSpy, SDRPlay, HackRF, AFEDRI SDR,HPSDR, RFspace devices, FiFi SDR, Perseus and RTL-SDR in various modes.
OpenWebRX supports many devices via the SoapySDR library and rx_tools
command-line tools [1].
•Both the audio stream and the continuously updating waterfall display content is
now compressed at the server and decompressed at the client, which results in
an approximately 8 times decrease in network bandwidth usage compared to theuncompressed stream. The compression used is ADPCM.

•

To allow DSP processing at the client for ADPCM decoding and resampling,libcsdr has been ported to Javascript with the Emscripten compiler. Thisapproach builds on the current capabilities of web browsers on compilingJavascript to native code when the webpage loads, to speed up processing (Just
In Time compilers). With the help of Emscripten, a unified codebase can be used
for both the client and the server.

•

The libcsdr library has been extended with SIMD optimized implementations of
the FIR decimation for the ARM architecture. This resulted in approximately
300% speedup on some embedded platforms including the Raspberry Pi 2.

•

I have released a related desktop SDR application for the Raspberry Pi 2, qtcsdr,
which uses the Qt library for UI. It supports both reception and transmission
through the rtl-sdr and rpitx projects, and also uses the CSDR tool forprocessing. While transmitting, the underlying rpitx tool (written by Evariste
Courjaud, F5OEO) uses one of the GPIO pins of the Raspberry Pi 2 to generate
an RF signal.

2.2 CSDR used for tracking Schiaparelli EDM lander
I have received e-mails from many people using OpenWebRX and CSDR for numerous
purposes. CSDR has been used in high altitude balloon experiments, OpenWebRX has
been used as the web front end of an FPGA based SDR platform, it has been bundled ina Linux distribution (SkyWave), and has been used at CubeSat ground stations.
However, the most interesting message arrived in November, 2016. I have received ane-mail from Stephan Esterhuizen, who works at NASA Jet Propolusion Laboratory. He
10informed me that CSDR has been utilized at a ground station used during the ExoMars
EDM landing attempt, and it formed a crucial part of their DSP pipeline.
Schiaparelli, the EDM (entry, descent and landing demonstrator) module is a technology
demonstration vehicle which was carried by the ExoMars Trace Gas Orbiter, with thegoal of demonstrating the capability of ESA to perform a controlled landing on thesurface of Mars. During the landing process, the telemetry signals of Schiaparelli weremonitored from the Giant Meterwave Radio Telescope (GMRT) in India (see Figure 5),
with a phased array of 28 antennas of diameter 45 meters each. The CSDR software wasused during the real-time detection of the very weak 5 Watt EDM transmitter, and it
ingested data from the GMRT phased array at approximately 140 MBytes/second,
where it went through various stages of mixing, filtering, decimating, and doppler
corrections until a resolution bandwidth of 1 Hz was obtained. Schiaparelli’s UHF
signal was successfully detected and tracked from pre-atmospheric entry until about one
minute before landing, when the signal was unfortunately lost. Figure 5 shows how thebaudline tool was used to display a waterfall diagram after processing the signal with
CSDR and other tools.

Figure 5: Antennas of the Giant Meterwave Radio Telescope [9] (on the left),the output of the DSP pipeline is displayed during the mission [26] (on the right).

11

3 Digital modulations
3.1 Motivation behind digital mode support
The original version of OpenWebRX was only able to demodulate analog audio
transmissions like AM, SSB and FM. However, amateur radio operators also use digitalmodulations. In modes like BPSK31 and RTTY, the participants have a near real-time
chat: the characters typed on their keyboards are modulated onto an RF carrier anddecoded at the target, but various modes exist for sending files, pictures (digital SSTV),
and also for extremely weak signal communication like EME.
There are several free and open source software packages to receive or transmit signals
in a variety of digital modes (e.g. Fldigi, gMFSK, minimodem) and also commercial
ones (Ham Radio Deluxe). To use these software, you have to connect the baseband
input and output of an RF transceiver (typically an amateur radio transceiver with SSBmode) to the audio device of the PC.
The GUI of the Fldigi software is shown on Figure 6. It allows you to select a signal on
the waterfall display, and decode it. After clicking on the T/R button, it starts to transmit
the characters you type.

12

Figure 6: Fldigi software receiving RTTY transmission
However, if OpenWebRX users wanted to receive digital modes, they had to use suchexternal software, that were designed for the audio input device. This meant asignificant amount of effort: they needed to setup and configure a virtual audio device
and connect it to the audio output of OpenWebRX, then configure the modem software
to use the same virtual audio device. This process might involve setting up proprietary
drivers on Windows (e.g. Virtual Audio Cable software), or configuring Pulseaudio
through the pavucontrol GUI tool on Linux, possibly loading the snd-aloop kernel
module. In addition, OpenWebRX uses a lossy audio compression by default, whichmeans some degradation in signal-to-noise ratio (SNR), while it still makes possible todecode some digital modes if the signal is strong enough.
I realized that integrating the SDR software and the digital modem removed suchbarriers in front of users with less computer experience, and it would also allow peopleinterested in ham radio to more quickly understand what digital modes are.
OpenWebRX is meant to be a self-contained system: all the users would have to do is to13

open the website, click on a signal and see the decoded data.
I also observed that most open source modem software do not provide an easy to use
API that would have allowed other applications to pass raw audio data into the decoder
and acquire the text output. While it was possible to modify one of these to provide theproper APIs, I decided to write my own implementation extending libcsdr and the
CSDR command line tool. This allowed me to learn more about the internals ofmodems. I have chosen the BPSK31 mode as the first to be implemented for
OpenWebRX as it is one of the most widely used digital modes on amateur radio bands.

3.2 Results of modifications
OpenWebRX has been extended with the capability to demodulate BPSK31
transmissions. The underlying CSDR software also has new features, so that it candemodulate RTTY (2-FSK) and BPSK31 transmissions, it can generate BPSK31
transmissions and simulate an AGWN channel. GNU Octave scripts have beendeveloped to calculate the S-curve of the error detectors and the variance graph of theestimators.
Figure 7 and 8 show the new user interface of OpenWebRX, while a BPSK31
transmission is being demodulated. When the webpage of an OpenWebRX receiver isopened, one of the analog demodulators is selected by default. The user can select a
digital demodulator from the appropriate listbox (next to the DIG button), or click on
the DIG button to select the last used digital demodulator.
In this case a new panel pops up, which contains the waterfall diagram of the baseband
signal. The user can select which channel to decode by clicking on the diagram. The
decoded data shows up under the waterfall diagram.

14

Figure 7: New user interface of OpenWebRX with integrated BPSK31 demodulator

Figure 8: New parts of the web user interface

3.3 Changes to the OpenWebRX protocol
To display BPSK31 demodulated data on the web UI, both the OpenWebRX server andfrontend code have been modified. These components communicate with each otherover WebSockets, with a custom protocol [2, pp. 30]. This protocol has been extended
with new messages, see Table 1. The term "secondary receiver" is used for the digital
15

mode demodulator. It is called secondary because it works in parallel with an analog
demodulator that still provides audio output. The input of the secondary receiver is theIF signal containing only the channel selected on the main waterfall diagram.
SourceExample message

Notes

ClientSET secondary_mod=bpsk31

Switch secondary receiver on

ServerMSG secondary_fft_size=1024 if_samp_rate=12000
secondary_bw=31.25 secondary_setup

Send secondary receiver setup
parameters

ServerFFTS<an array of 1024 floating point values>

Secondary FFT data

Server

DAT <text>

Secondary demodulator output

ClientSET secondary_offset_freq=524

Change offset frequency

Table 1: New messages in OpenWebRX protocol

3.4 Digital modulations in general
Digital modulations mean binary data transmitted over one or more modulated carriers.
The input of the modulator and the output of the demodulator is a discrete signal,
however, the signal passes through an analog wireless channel between them.
Most of the early work on digital modulations originates from the time when computer
systems were interconnected over wired telephone lines. Many of the concepts
developed for telephone modems were later reused for wireless transmission [3, pp. 3].
In a digital modem, the demodulator is traditionally more advanced to implement thanthe modulator, as it has to deal with tasks like synchronization, decoding, and problems
like variations in signal strength and additive noise on the channel.
Binary phase-shift keying (BPSK) is a simple example on how we can alter the phase ofa single sine wave to encode data. You can inspect the time domain signal and thecorresponding constellation diagram of a BPSK signal on Figure 9.

16

Figure 9: Simulation of BPSK signal in GNU RadioFor quadrature amplitude modulation (QAM), both the amplitude and the phase, and for
frequency-shift keying (FSK), the frequency are the physical values used for the
purpose of encoding discrete symbols.
Immediate changes in phase, amplitude or frequency have the drawback of having avery high signal bandwidth, thus making it inefficient to use on real wireless channels,
where bandwidth is a finite resource. Pulse shaping is used to limit the signal
bandwidth, and also to eliminate intersymbol interference (ISI).
The formula (1) describes a QAM modulated complex baseband signal [3, pp. 44]:∞y (t)= ∑ s[n] g(t−nT b )

(1)

n=−∞

•

s [n] is the value of the n-th discrete symbol (complex),•g( x) is the transmit filter or pulse shape (real-valued),•T b is the duration of each symbol (the reciprocal of the symbol rate).

The g( x) function should be chosen so that its value is zero at the maximum amplitudeof each neighboring symbol to eliminate ISI, see (2).
∀ n∈ ℤ if n≠0 then g(n T b)=0(2)

Such a function is the raised-cosine filter (3) [4]. If we take the square root of theimpulse response of the raised-cosine filter, we get the root-raised-cosine (RRC) filter.
If that is applied at both sides of the wireless channel, their overall impulse response
will be the same as of the the raised-cosine filter (see Figure 10).

17

Figure 10: The effect of raised-cosine filtering on consecutive symbols [5]{π sinc 1 , t= ±T
4
2β
2β
π βt
h(t )=cosTtsinc, otherwiseT
2β t 2
1−
T

( )
( )
( )
( )

}

(3)

Special pulse shapes are also used to decrease the required bandwidth of the signal.
SOQPSK-TG is a spectrally efficient modulation scheme used in aeronautics [6], thatdefines its own pulse shape. BPSK31 later covered in this thesis uses cosine shaping.
The modulations used typically have 2N constellation points, which means that a groupof bits are easily mapped to each point (and also that the constellation diagram issymmetric). However, during the demodulation process, usually there is an uncertain
phase offset, which would result in the constellation points mapping to different
symbols unless some kind of synchronization is carried out. For BPSK signals, one such
scheme is called differential BPSK (DBPSK), where the symbols are encoded in the
directions of the phase changes between constellation points, which are not affected bya phase offset.
18

The wireless channel is usually modeled with additive white Gaussian noise (AGWN).
(Other distorsions, including multipath propagation can also occur, and need to bemodeled differently.) To keep the integrity of data bits over the wireless channel,
forward error correction (FEC) techniques are used. These usually increase redundancy
in the data stream, but if a small number of bits have a wrong value, they can detect orcorrect it in certain scenarios. (If too many bits are wrong, however, these algorithms
also fail.) Convolutional codes, turbo codes and low-density parity check codes arecommonly used today [3, pp. 2].

3.5 Functional stages of processing in a digital modem
Turning data into a modulated signal usually consists of the following stages [3, pp. 5]:•

encoding,•

bit-to-symbol mapping,•pulse shaping,•

modulating carrier with amplitude / phase / frequency information.

Recovering the original data from the modulated signal involves the following stages ofprocessing:•carrier recovery,•

retrieving amplitude / phase / frequency from carrier,•symbol timing recovery,•equalization,•

symbol-to-bit mapping,•

decoding.

As the circuits of the receiver and the transmitter don't use the exact same clock source,
the signal sampled by the receiver will have some unwanted properties. There will be afrequency and phase offset between the local oscillator in the receiver and thetransmitter. For that reason, the receiver will "see" the constellation of the modulated
baseband signal continuously rotating (4),19

s r (t )=s(t )ej (2 πf offset t+ ϕoffset )(4)

where s r (t ) is the received signal, s (t) is transmitted signal, and f offset is thefrequency offset, ϕoffset is the phase offset. Sometimes the amount of rotation alsochanges over time because the frequency of the oscillators in both the receiver and thetransmitter can be affected by varying temperature.
Carrier recovery methods can compensate for the unknown frequency and phase offset
by recovering the original carrier at the receiver, and downconverting the input signal
with that. More information on this topic is available in section 4.6.
Furthermore, the clock frequency and phase will not be synchronized between the D/Aconverter in the transmitter, and the A/D converter in the receiver. As a consequence, in
the receiver, we might be sampling the symbol at the wrong time, during transition. In
order to maximize the performance, especially if additive noise is also present on thechannel, we need to sample at the point where the symbol amplitude is maximal.
Looking at the eye pattern of the baseband signal, the maximum eye opening is the ideal
sampling point, where the adjacent symbols have the least effect, and the where thecontribution of the convolved impulse response functions of the pulse shaping filter andthe channel reach its highest value for the given symbol. Symbol timing recovery
methods are detailed in section 4.3.
After the problems described above have been eliminated, recovering the amplitude andthe phase or frequency from the modulated signal and applying symbol-to-bit mappingis usually an easy task: we need to decide which symbol the constellation point is thenearest to.
Another step, equalization is usually required to compensate for distortion caused by thewireless channel, for which the main source is multipath propagation, resulting in ISI.
Adaptive filters can learn about the channel and realize an impulse response that is theinverse of it. Finally, the forward error correction used in the transmitter needs to bereversed.

20

3.6 Digital modes on amateur radio bands
Table 2 summarizes the properties of some popular digital modes used by amateur radio
operators.
Mode

Modulation, baudrate

RTTY

FSK, 45.45 baud

BPSK31

BPSK, 31.25 baud

QPSK31

QPSK, 31.25 baud

WSPR

4-FSK, 1.4648 baud

JT65 [7]64-CPFSK, 2.69 baud

Olivia-32-1K 32-FSK, 31.25 baud
Olivia-32-2K 64-FSK, 31.25 baud
Packet radio

FSK with 300/1200/2400/4800 baud, GFSK with 9600 baud

Table 2: Properties of some digital modes used on amateur radio bands
Some modes employ FEC techniques, while others do not. For example, BPSK31 and
RTTY do not use any error correction, which make it easier to implement a receiver forthem. QPSK31 and WSPR use convolutional codes, Olivia MFSK uses Walsh functions
for FEC. Comparing BPSK31 and QPSK31, the latter can reduce error rate on typicalradio paths, where the errors are in bursts rather than randomly spread, but it can do no
improvement if the noise level is high in overall.
Some modes are especially tailored for weak signal communication, use a frame
structure and can only carry a limited amount of information, like the amateur radio
callsign of the operator or the transmitter output power. WSPR and JT65 are in thiscategory, both developed by Joe Taylor, K1JT. These have a very low symbol rate andbandwidth in order to increase SNR at the receiver. JT65 is typically used for earthmoon-earth (EME) and meteor scatter contacts on the VHF and UHF bands. Tests
showed that using JT65B, 96% of the messages were decoded in -23 dB SNR(measured in 2500 Hz bandwidth) [7].
Packet radio, which was used to build wireless computer networks, should also bementioned. It was very popular before low-cost Internet access spread, and for many21

amateur radio operators, it was the first experience with services (like bulletin boards,
file access, etc.) that are nowadays part of the Internet culture. Its protocol originatesfrom X.25, a modified version of which is called AX.25, where each packet contains thecallsign of both the sender and the recipient. Nowadays the only widely used service
still relying on AX.25 is the Automatic Packet Reporting System (APRS), with 1200
baud AFSK signals, typically transmitting over FM links on VHF.

3.7 Digital modes in consumer devices
While the highlight of my paper is digital modes on amateur radio bands, it should not
be forgotten that many consumer devices use wireless communication: mobile phones,
wireless keyfobs for cars, temperature sensors, etc.
Internet of Things (IoT) is also a common term used today, referring to embedded
devices connected to the Internet. Nowadays very cheap RF SoCs are available, andsuch a SoC can include an MCU, a modem, up- and downconverters, and a PA in one
package. As the central unit of an embedded device, it can control various peripherals of
the system while it directly performs two-way communication on its radio interface.
As an example, ESP8266EX chips contain a 32-bit MCU running at 160 MHz alongwith an integrated WiFi controller [8], available under 1.5 USD per piece at the time ofwriting.
A variety of RF transceiver ICs are available for products using more simple wirelessprotocols. For example, the Texas Instruments CC1111 is a sub-GHz wireless MCU that
can act as an FSK, GFSK, MSK, ASK, or OOK transceiver [10].
While CSDR does not support complex modulation schemes like OFDM, some of its
functions could be reused to decode the signals of IoT devices using simple protocols
and modulations, from the command-line, see section 5.10.

22

4 A BPSK31 demodulator
BPSK31 is a digital mode originally developed by Peter Martinez (G3PLX) in 1998. It
has been popularized by the WinPSK software and its successors. It uses differential
binary phase-shift keying (DBPSK) modulation with a symbol rate of 31.25 baud.
BPSK31 does not use any forward error correction, while its variant called QPSK31
uses convolutional code.
On Figure 11, a BPSK31 signal can be inspected. During symbol transitions, BPSK31
does not keep the amplitude constant, it rather has a sinusoidal envelope, with thecomplex baseband signal reaching zero in the middle of the transition.

Figure 11: The real signal present on the antenna, and the downconverted, complex
valued baseband signal. The same signals are shown with different zoom levels on theleft and right.
We can write the baseband BPSK31 signal as (5).
∞y (t)= ∑ s [n]g (t−n T b)
n=−∞

g(t)=

•

{

1+cos

tπ
Tb

( ) if −T ≤t≤Tb
2
0 if t >T b or t<−T b

b

}

(5)

s [n] corresponds to the symbols (complex numbers, which can take the values
1+0 j and 1−0 j ),•T b is the duration of a single bit,•g(t) is the impulse response of the pulse shaping filter.

23

To verify this formula, I have created a GNU Octave script which can plot the impulse
response of the pulse shaping filter, along with an example baseband signal for a few
input symbols (see Figure 12). The script is now part of the CSDR distribution(grc_tests/psk31_sigmodel.m).

Figure 12: Output of GNU Octave script for analysis of
BPSK31 baseband signals (Ts is the symbol duration)
While the sinusoidal pulse shape does not provide protection against ISI like the rootraised-cosine does, it decreases the signal bandwidth so that it is possible to have 256
separate channels even in a single 8 ksps audio stream. I have verified with spectrum
analysis that the BPSK31 emission bandwidth is around 60 Hz at -26 dB (see Figure13), which is identical to the results published on the ARRL website [11].

24Figure 13: Spectrum and constellation diagrams of BPSK31 modulated signal

4.1 Implementation with CSDR
As the CSDR command-line tool can be used to build DSP chains in the command-line,
running different DSP functions in different processes connected with OS pipes, theBPSK31 demodulator has been implemented in the same philosophy.
The command to demodulate a BPSK31 signal acquired from the audio card, centered at
1 kHz can be found below. OpenWebRX uses a similar command internally.
arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr '=-1000./48e3') | \csdr fir_decimate_cc 32 | \csdr bandpass_fir_fft_cc $(csdr '=-(31.25)/1.5e3') \$(csdr '=(31.25)/1.5e3') $(csdr '=31.25/1.5e3') | \csdr simple_agc_cc 0.001 0.5 | \csdr timing_recovery_cc GARDNER 48 0.5 2 --add_q | \CSDR_FIXED_BUFSIZE=1 csdr dbpsk_decoder_c_u8 | \CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8

The clean separation between building blocks of this processing chain allows us toeasily derive modified digital modes from BPSK31. For example, changing the symbol
rate is just a matter of changing a few parameter values in the command above (see also
section 5.2). If one decided to add FEC to BPSK31, it required adding a pair offunctions to CSDR (although this is not subject of this thesis). The easy fine tuning ofparameters allows greater flexibility.
The following points contain an analysis of the command above.
25

•The arecord command reads the raw data from the audio device, using asampling rate of 48000 sps, with 16 bit signed integer format.

•

The csdr convert_s16_f command converts the data to floating point (the range[−32768 ;+36767] is converted to [−1.0 ;+1.0] ).
•A channelizer consisting of csdr shift_addition_cc, csdr fir_decimate_cc andcsdr bandpass_fir_fft_cc selects a single channel with a bandwidth of ~62.5 Hz,
sampled at 1.5 ksps out of the 48 ksps input signal.
The bandwidth of the BPSK31 signal is only 31.25 Hz, but we need someoversampling for the timing recovery function to work. In this case the signal isoversampled 48 times. I used a filter with a wider passband than needed because
the user does not always tune to the signal very accurately on the web interface.
The csdr = function allows us to calculate a formula and insert the result as aparameter into another command. See section 5.12 about that.

•

An AGC (csdr simple_agc_cc) keeps the signal power constant, however, it
should not distort the amplitude changes at the transients between symbols. On
that reason, its timing constant should be higher than the duration of a symbol.

•

To find the maximum amplitude for each symbol within the signal, symbol
timing recovery is used: csdr timing_recovery_cc implements non-data aided
timing recovery methods. Here the Gardner method is used.
As csdr timing_recovery_cc only outputs one sample per symbol, the blocks
afterwards work on signal sampled at approximately 31.25 sps. The default
buffer size in CSDR is 1024 or 16384 samples (depending on function), at which
real-time decoding would be impossible, as the processes first wait for the buffer
to fill up before starting processing.
A recent feature set added to CSDR included an option to set the buffer sizes
from environment variables. Setting the CSDR_FIXED_BUFSIZE variable to 1means that the functions will work on a single sample and then wait until new
data is available. This boosts the user experience much, the decoded text appears
immediately.

26

•

Carrier recovery, symbol decision and differential decoding is jointly done bycsdr dbpsk_decoder_c_u8.

•

The BPSK31 signal has the characters stored in Varicode encoding, so we needto convert Varicode to ASCII.

The following part contains a detailed description of the related new functions in CSDR.

4.2 Automatic gain control
At the time I started this project, the CSDR process has already contained multiple AGC
functions:•csdr fastagc_ff precisely adapts to the maximum value of the signal, to makesure that no clipping happens. It makes that possible by working on three buffersinternally.

•

csdr agc_ff models how a traditional AGC circuit works. Its attack and decay
rates can be set separately, along with the hang time and attack wait time.

While these blocks all work on real signals, to build the data flow of my BPSK31
demodulator, I needed a block that can work on complex signals. In addition, I wanted
to implement an algorithm that is really simple to use, without many different
parameters to set.
The resulting function, csdr simple_agc_cc implements a control system, see Figure 14
for an overview.

Figure 14: Block diagram of simple_agc_cc
A new gain value is calculated for every sample, but it is ran through a low-pass filter
before it is applied, as in (6).
Gain new =LPF

(Input signal )( Amplitude)
Reference
27(6)

The LPF is a single-pole IIR filter (7), the α parameter of which is the rate parameterof csdr simple_agc_cc.
y [n]=α x [n]+(1−α) y [n−1](7)The τ time constant of the filter corresponding to α can be calculated as in (8).
1fs1−ατ=T s α
T s=

(

(8)

)

In my BPSK31 demodulator, the AGC is applied to a signal sampled at 12 ksps, with
α=0.0001 that corresponds to a time constant of 0.8322 seconds.
The syntax of the new AGC function in CSDR is detailed below. It also contains aparameter for the maximum possible gain output by the controller.
csdr simple_agc_cc <rate> [reference [max_gain]]

4.3 Symbol timing recovery
If the IF signal is sampled at 1500 sps, but our symbol rate is only 31.25 baud, then weneed to select 31.25 samples from a set of 1500 samples every second, and decide if
they correspond to a (−1+ 0 j) or a (+1+0 j) symbol ("0" or "1").
Figure 15 shows what happens in practice if the signal is noisy and we sample it with awrong phase offset. Table 3 shows the symbol decisions made in this case.
Slicer output: 1 11 0 1 11 1 01 11
Original:
11 0 0 1 11 0 10 1 1
Table 3: Comparison of thesymbol decision and thetransmitted symbols in case ofincorrect sampling phase
In contrast, if the signal is sampled at the correct locations, the symbol decision output
equals to the original data transmitted, see Figure 16.

28

Figure 15: Noisy BPSK31 baseband signal sampled atwrong locations

Figure 16: Noisy BPSK31 baseband signal sampled at
the center of each symbol

A classification of timing recovery methods is available below [3, pp. 279].
•

Non-data aided timing recovery methods only rely on the input signal,
without any knowledge of the transmitted symbol or the symbol decision. They
might be placed before the carrier recovery function in the flow graph. They
provide a wider capture range and have better results at low SNR compared todecision-directed methods.

29◦ The early-late gate timing recovery algorithm is based on a control systemthat tries to find the middle of a symbol by designating three points on it, andcalculating the a phase offset correction at the next symbol based on thevalues of the input signal at these points. (9) is the formula [12] for the earlylate timing error detector (TED) in case of a real input signal.
e [n]= y [ nT +d [n]]⋅( y [ nT +0.5 T + d [n ]] – y [ nT −0.5T +d [n] ] )(9)▪ e [n] is the calculated timing error for the n-th symbol, which is the sumof the timing error for the I and the Q branches ( e I [n] and e Q [n] ).
▪

y I [n ] and y Q [n] correspond to the real and the imaginary part of the
input signal.

▪ T is the duration of a single symbol.
▪ d [n] is the estimated phase offset for the n-th symbol.
Note that (9) is only the timing error detector, a single part of the control
system. One way to update the phase offset from the error value is using a
proportional controller, as presented in (10) [3, pp. 299], where μ is the
update step-size (the proportional gain).

d [n]=d [n−1]−μ⋅e[n−1](10)Figure 17:The early-late gate TED
Figure 17 allows us to explain the early-late gate timing error detector (TED)
in an even more simple way. Based on the notation used on the figure, incase of a real signal, the error can be calculated as (11).

30

e= y M⋅( y R− y L )(11)◦ The Gardner algorithm (12) [13][14][15] (introduced by Floyd M. Gardnerin 1986) is very similar to the early-late gate, but the loop rather tries to findthe zero crossing with the middle point. The delay between its points is ½ T(while it was ¼ T for the early-late algorithm).

e [n]=[ y [ ( n−1)T +d [n−1] ] − y [ nT +d [n]] ]⋅y [ nT −0.5 T + d [n−1] ](12)Figure 18: The Gardner TED
Figure 18, shows how the Gardner algorithm works by example. The
simplified formula for real signals (13) is similar to the one for early-late
TED, but the sign of the error is different.
e=− y M⋅( y R − y L )= y M⋅( y L − y R )(13)◦ The squaring timing recovery [16] [3, pp. 294] is similar in principle to thesquaring loop for carrier recovery. The exponentiated signal will contain aspectral line corresponding to the data rate. If we apply a narrow-band filter
to pass that single spectral line, the peaks of the result in time domain can beused to sample the original signal (see Figure 19). You can the see the resultof raising a BPSK31 signal to square on Figure 20.
31

Figure 19: Block diagram of squaring timing recovery

Figure 20: BPSK31 signal squared, with peaks at DC, +31.25 Hz and -31.25 Hz

32•

Decision-directed timing recovery methods take the symbol decisions into
consideration. In general, they produce better results if executed after matchedfiltering and carrier recovery, and if the SNR is sufficiently high enough.
◦ The TED formula of the Mueller and Müller algorithm [17] [18] is (14) incase of a complex input signal.
e [n]=ℜ{ f decide * ( y ((n−1)T +d [n−1] ) ) y ( n T +d [n ])−f decide * ( y ( n T +d [n] ) ) y ((n−1)T +d [n−1] ) +d [n−1]}(14)(15) is a simplified formula for the M&M TED:
e=ℜ { f decide *( y L ) yC −f decide * ( y C ) y L }(15)◦ The formula of the zero-crossing TED [18](16) is similar to the Mueller andMüller algorithm above.
e [n]= y ( nT −0.5 T +d [n] ) [ f decide ( y (( n−1)T +d [n] ) )−f decide ( y ( nT + d [ n]) ) ](16)

Its simplified version is (17), see Figure 21 for an example how this formula
works.
e= y M [ f decide ( y L )−f decide ( y R ) ]Figure 21: The zero-crossing TED

33

(17)

Some methods only have a TED formula for real signals, but they can still be applied tocomplex signals, by calculating the error for the real and the imaginary part separately,and summing them up, as in (18) [13].
e [ n]=e I [n]+e Q [n](18)Both carrier and symbol timing recovery algorithms introduce a trade-off between
convergence speed and the variance of estimation error [19].

4.4 Implementation of non-data aided timing recovery
For CSDR, the early-late and the Gardner algorithms have been implemented. These areboth non-data aided timing recovery methods, so I considered these more sufficient for
general use because they also work at low SNR.
The input of csdr timing_recovery_cc is the baseband signal, which is advised to beoversampled at least 4 times compared to the data rate. The output is the signal sampled
at the estimated maximum eye openings, at the data rate. These complex samples can bemapped to the nearest constellation points to find the symbols corresponding to them.
What differentiates the csdr timing_recovery_cc command from other open source tools
available is the possibility to generate images about the internal working of thealgorithm using GNU Octave immediately. Using the --octave switch for csdr
timing_recovery_cc, and piping stderr into an interactive GNU Octave session, one canget immediate visual feedback about the performance of the timing recovery algorithm
on the given signal, and the graphs can also be saved to PNG files using the--octave-save switch.
Both the early-late and the Gardner methods take three samples into consideration while
determining the timing error. Figure 22 shows an example output of csdr
timing_recovery_cc using the plotting capabilities of GNU Octave. Figure 23 shows acompilation of diagrams generated during the phase acquisition using the Gardner
method on a BPSK31 signal, and Figure 24 shows the same for the early-late gatealgorithm, but here the signal gets past the preamble phase, and the algorithm still keeps
locking.

34

Figure 22: GNU Octave plotting the status of the Gardner algorithm, with the actual
error value and phase offset in samples (cxoff). It shows the I and Q branches
separately (on the left), and also the complex signal on a 3D plot (on the right).

Figure 23: The Gardner timing recovery algorithm locks onto the BPSK31 baseband
signal. (The number in the top right corner of each diagram shows the sequence.)

Figure 23 and 24 also emphasize the difference between the Gardner and the early-latealgorithm: the Gardner algorithm tries to find the middle of the signal transition, and theoutput sample is taken from the red dot on the left, while the early-late algorithm tries to"climb" to the middle of the symbol, taking the output sample from the middle red dot.

35

Figure 24: The early-late gate timing recovery algorithm locks onto the BPSK31
baseband signal during preamble, and stays locked afterwards.
36

The syntax of the CSDR function corresponding to the timing recovery is as below:
csdr timing_recovery_cc <algorithm> <decimation> [mu [max_error \[--add_q [--output_error | --output_indexes | \--octave <show_every_nth> | \--octave_save <show_every_nth> <directory> ]]]]

The algorithm can currently be set to "GARDNER" or "EARLYLATE".
The decimation parameter refers to the number of samples per symbol at the input
signal.
The mu parameter is the update step of the loop, see (10).
The max_error allows us to clip the error signal, to keep it in a given range.
If the --add_q parameter is false, the TED is only evaluated on the real part of thesignal. If --add_q is true, it is evaluated on both the I and the Q branch, and the results
are added.
With --output_error, the output of the function is changed: it rather outputs thecalculated error of the TED for each output sample, which can be used for generating
the S-curve, see section 4.5.
Similarly, with --output_indexes, the function outputs the indexes of the maximum
amplitude points in the input stream, which can be used while generating the estimator
variance diagram, see section 4.5.
With the --octave switch, GNU Octave commands are written to the standard error,
which plot the input samples related to the current symbol, and also the relevant points
on them. The required parameter show_every_nth means that one out of
show_every_nth will be plotted with Octave. If show_every_nth is 0, then a plot will be
generated for every single symbol. The --octave-save parameter has the same function,
but it saves the graphs into PNG files into the directory also given as parameter.
The zsh shell can be used to redirect the standard error to GNU Octave directly fromcsdr timing_recovery_cc, as in the example command below. This allows one to plot theinternals of the algorithm while running a signal through it.

37

csdr timing_recovery_cc GARDNER 48 0.5 2 --add_q \--octave 0 2> >(octave -i)

4.5 Symbol timing recovery performance measurements
While developing the analog demodulator processing chain, it was sufficient to observe
the spurious-free dynamic range (SFDR) for most algorithms to confirm that they work
properly. However, evaluating the performance of timing recovery algorithms is a moredifficult task.
One of the metrics of the timing recovery algorithm is the S-curve. The S-curve shows
how the TED reacts if fed with the same input signal with different phase offsets.
Basically, it is a plot to show how the error depends on the phase offset. To draw thiscurve, the TED need to be placed in an open loop, so that the error does not have any
effect on the sampling phase in the next iteration.
A GNU Octave script, grc_tests/bpsk31_scurve.m has been written on the purpose ofgenerating the S-curve, the results of which are found on Figure 25 and Figure 26. The
template for the command used to generate the input with changing phase offset can befound below. It is used internally by the Octave script.
dd bs=8 skip=<phase_offset> \if=bpsk31_baseband_sample_complex_8000_sps_010101.raw | \csdr timing_recovery_cc <timing_recovery_algorithm> 256 \--add_q –output_error

The S-curve is correct if the error is only zero when the symbol is sampled at the
maximum amplitude. If the error is zero at any other point, it is called a false lock point,
because the loop can get stuck there while sampling at the wrong phase.
A sufficient TED is free from false lock points. In both Figure 25 and 26, the phaseoffsets of 0, 128 and 256 correspond to maximum eye openings, and no false lockpoints can be identified. A significant difference between the two TED formulas is thesign of the error, which needs to be taken into consideration in other parts of the timing
recovery algorithm.

38

Figure 25: S-curve for early-late TED on BPSK31
baseband signal

Figure 26: S-curve for Gardner TED on BPSK31
baseband signal

We can further analyze the performance of the estimator by generating the variancediagram, by measuring the variance of the phase error while feeding the demodulator
with the sum of modulated random data and Gaussian white noise. The diagram shows
the variance at different SNR per bit ( Eb / N 0 ) values.
The grc_tests/bpsk31_tedvar.m script has been written to carry out this measurement. It

39measures the estimator variance for 1,000,000 symbols. As the necessary computations
take a long time, this Octave script has been optimized to use multiple CPU cores, and it
caches the signal and the noise in advance. The output of the script can be inspected on
Figure 27 and 28.

Figure 27: Estimator variance of the Gardner
algorithm in csdr timing_recovery_cc

Figure 28: Estimator variance of the early-late gatealgorithm in csdr timing_recovery_cc

40

4.6 Carrier recovery
If the conditions are ideal, the IF signal is the baseband BPSK31 signal centered at DC.
However, in practice there is an unknown phase or frequency offset between thetransmitted and the received signal, as the oscillators of the transmitter and the receiverare not synchronized, and are also subject to drifting due to temperature changes (thisoffset might even change in time).
We can see the result of a frequency offset at the receiver on Figure 30 and 31, while theoriginal signal (without offset) is shown on Figure 29.

Figure 29: Transmitted BPSK31
baseband signal

41

Figure 30: Received BPSK31 baseband signal
radwith a frequency offset of Δ ω=0.005 π
sec

Figure 31: Received BPSK31 baseband signal
radwith a frequency offset of Δ ω=0.1 π
sec
The received baseband signal can be written as (19), where the ϕoffset contributes aconstant phase difference, and f offset contributes a constant phase rotation to thebaseband signal.
y received (t)=e j(2 π foffsett +ϕoffset )∞∑ s[n] g(t−nT b )

(19)

n=−∞

This rotation can also be inspected on the constellation diagram, as seen on Figure 32.
(In case of a frequency offset, it is also common to see a full circle on the constellation
diagram.)42

Figure 32: Constellation diagram of transmitted BPSK signal (on the left), received
BPSK signal with a phase offset (in the middle), received BPSK signal with a frequency
offset (on the right).

The carrier recovery function should estimate the unknown e j (2 π foffsett +ϕ offset )in (19), andmultiply the input signal with the conjugate of the estimate in order to correct it.
We classify the carrier recovery methods as follows.
•

Non-data aided carrier recovery methods do not assume any previous
knowledge about the data symbols.

Figure 33:
Coarse carrier acquisition◦ Coarse carrier acquisition using DFT/FFT is based on the Fouriertransform of the input signal, and looks for the bin corresponding to the peakof the signal to find the frequency offset, see Figure 33.
◦ The Costas loop is a phase-locked loop (PLL) modified so that it can lockon PSK signals (see Figure 34) and it is possible to use it for fine carrier
acquisition. It also has decision directed versions, as shown later.

43

Figure 34: Block diagram of Costas loop for locking on BPSK signals [23]◦ It can be shown that raising PSK and QAM input signals to a given power,
the result will have a sinusoidal component with a constant phase. The
squaring loop uses a PLL to lock on this component.

Figure 35: Block diagram of squaring loop [3, pp. 249]•

Decision directed carrier recovery calculates the phase difference between thereceived sample and the corresponding output of the symbol decoder, thus ittakes the value of the decoded symbol into consideration and attempts tominimize the phase difference using an adequate control loop, see Figure 36. See
also Figure 37 for a Costas loop that can lock on QPSK signals.

44

Figure 36: Block diagram ofdecision directed carrier recovery [3,pp. 264]

Figure 37: Block diagram of Costas loop forlocking on QAM signals [25], [3, pp. 260]•

Data-aided carrier recovery methods uses previous knowledge about thetransmitted symbols:◦ if the transmission starts with a sequence of training symbols, e. g. a
preamble that precedes each packet,◦ if a pilot signal is available to lock onto.

For best performance, carrier recovery can be done in multiple stages: first, a coarse
carrier acquisition can be made using FFT, it can be refined using one of the non-dataaided methods, and then we can proceed to the decision-directed method.
The locking range of latter stages is narrower, but their error variance in tracking modeis better. Note that the timing recovery and equalization might have adaptive parts that
also need to be tuned before we can proceed from one stage to another.

45

The carrier recovery method I first implemented was a Costas loop, which worked well
if the frequency difference was very small (see section 5.4). However, the user typically
fails to correctly select the center of the BPSK31 signal on the web UI, and clicking at
the wrong pixel on the waterfall diagram easily results in a frequency error in the orderof 10 Hz.

4.7 Synchronization in a differential PSK receiver
For differential BPSK signals, there is a method that allows joint carrier synchronizationand differential decoding, as described in [20, pp. 26].
Even if carrier synchronization is applied at the receiver, the constellation of thereceived signal is subject to a possible 180° rotation. In this case, the samples get
mapped to wrong symbols at the slicer.
As an example, if we send the symbol sequence "01001" at the transmitter, we might get"01001" or "10110" at the receiver, based on how the carrier recovery locked.
A way to solve this problem is encoding the symbols with the phase changes. This
technique is called DBPSK (differential BPSK). For BPSK31:•

if the phase remains unchanged for the duration of a symbol, it means a "1",•

if the phase changes 180° between symbols, is means a "0".

From the output of the slicer, we have the necessary information about phase changes.
See Table 4 for the function carried out by the differential decoder.
Last
input
0
0
1
1

Current
Output
input
0
1
1
0
0
0
1
1

Table 4: Logic function carried out
by the differential decoder

CSDR now also contains a differential encoder that applies this operation in reverse. "0"and "1" symbols map to 0x00 and 0x01 bytes at the input and output of the these46

commands. You can find the syntax of the related CSDR commands below:
csdr differential_decoder_u8_u8
csdr differential_encoder_u8_u8

To show how the binary data can be read and decoded by visually inspecting the
waveform, see Figure 38.

Figure 38: Symbol decisions (above) and differential decoded data (below)
Note that the decoded data does not depend on the initial phase offset of the receiver, as
seen on Figure 39.

Figure 39: Symbol decisions (above) and differential decoded data (below)
with a different receiver starting phase offset
However, carrier synchronization and differential decoding can be done in a single step,
as implemented in csdr dbpsk_decoder_c_u8 (see Figure 40). The method to be
described works on the output of symbol timing recovery (with one sample for eachsymbol), and makes use of the current and the last input sample, calculating thedifference of their phase. If the difference is above 90°, we assume that the current
symbol has changed, and write an "0" to the output, while if the difference is below 90°,
we assume that the symbol has not changed, and write a "1".

47

Figure 40: The block diagram of csdr dbpsk_decoder_c_u8

4.8 Varicode decoder
BPSK31 uses Varicode for encoding the characters, which is a variable-length code thatmaps shorter bit sequences to more frequently used letters. Characters are delimited bymultiple "0" symbols.
The bit sequences of the characters were designed in a way that multiple "0" bits cannot
come after each other inside them. If we see multiple "0" bits after each other, the next
"1" bit will be part of a new character.
With the full conversion table (in Table 5) one can decode the Varicode characters into
ASCII. Figure 41 shows the waveform with the Varicode characters highlighted. Using
the code table, the character sequence "abc" can be decoded.

48

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
:
/
{
|
}
;

1111101
11101011
10101101
10110101
111011111011011
11111101
101010101
1111111111111101
101111101
11010111
10111011
11011101
10101011
11010101
111011101
10101111
11011111101101
101010111
110110101
101011101
101110101
101111011
101111011
11110101
1011011111
1010110111
110111011
1010110101
110111101

a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
<
=
>
?
@
~

1011 SPACE
1011111!
101111"101101#
11$111101%1011011&101011(
1101)
111101011*
10111111+
11011,
1110111111.
111/11111110110111111
1
10101
2
10111
3
101
4
110111
5111101161101011711011111
8
1011101
9111010101[
111101101\
1010101]
111010111^
1010101111_
1010111101.
1011010111 DEL

1111111111
101011111
111110101
111011011
1011010101
1010111011
11111011
11110111
101101111
111011111
1110101
1101011010111110101111
10110111
10111101
11101101
11111111
101110111
101011011
101101011
110101101
110101011
110110111
1010101101
111110111
111101111
111111011
1010111111
101101101
1110110101

NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
DLE
DCI
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US

1010101011
1011011011
1011101101
1101110111
1011101011
1101011111
1011101111
1011111101
1011111111
11101111
11101
1101101111
1011011101
11111
1101110101
1110101011
1011110111
1011110101
1110101101
1110101111
1101011011
1101101011
1101101101
1101010111
1101111011
1101111101
1110110111
1101010101
1101011101
1110111011
1011111011
1101111111

Table 5: Varicode to ASCII mapping table, including control characters [11]Figure 41: BPSK31 waveform and corresponding binary data
(after differential decoding)I first observed the protocol by inspecting the signal generated by the Fldigi digitalmodem software. During idle periods, when the software has ran out of characters tosend and is waiting for the user to start typing again, the Fldigi software is continuously
sending zeros, which means a sequence of "101010..." after differential encoding. Thisbehavior allows the symbol timing recovery algorithm to keep synchronized.

49

The corresponding CSDR functions are listed below. CSDR also contains a Varicode
encoder that can be used to generate BPSK31 modulated signals.
csdr psk31_varicode_decoder_u8_u8
csdr psk31_varicode_encoder_u8_u8

The input of the Varicode decoder is 0x00 and 0x01 bytes, the symbols after differential
decoding. The output of the decoder is ASCII data. (The same applies to the encoder,but in reverse order.)Internally the Varicode decoder uses a FIFO to store the last 32 bits received, and if it
detects a valid Varicode character at the beginning of the FIFO, it writes thecorresponding ASCII value to the standard output.

4.9 Resource usage
BPSK31 is very low data rate, and the demodulator works from an IF signal of around10-12 ksps, which results in low CPU usage. While the main waterfall diagram
currently uses overlapped FFT by default, the secondary waterfall is not, and the FFT
size for it is also smaller, 1024 compared to 4096 for the main waterfall, thus the FFT
operations for the secondary waterfall diagram use much less CPU than the main
waterfall diagram. As a consequence, there is no point in doing optimizations for low
data rate digital modes. You can compare CPU usage on a development version of
OpenWebRX with BPSK31 demodulator Figure 42 and 43.

50

Figure 42: OpenWebRX and its child processes in the output of the top command
without running the BPSK31 demodulator

Figure 43: OpenWebRX and its child processes in the output of the top command whilerunning the BPSK31 demodulator

51

5 More applications of CSDR
5.1 Generating BPSK31
To have a complete implementation of BPSK31 in CSDR, I also needed a BPSK31
transmitter. (This method was also used while generating estimator variance graphs.)
The following command outputs a valid BPSK31 signal to the audio card:
while true; doecho -n "CQ CQ CQ DE HA7ILM HA7ILM HA7ILM PSE K";
done | \csdr psk31_varicode_encoder_u8_u8 | \csdr differential_encoder_u8_u8 | \csdr psk_modulator_u8_c 2 | \csdr gain_ff 0.25 | \csdr psk31_interpolate_sine_cc 256 | \csdr shift_addition_cc 0.125 | \csdr realpart_cf | \csdr convert_f_s16 | \mplayer -cache 1024 -quiet \-rawaudio samplesize=2:channels=1:rate=8000 -demuxer rawaudio -There is another version that produces the same result, using the formula (5):while true; do \echo -n "CQ CQ CQ DE HA7ILM HA7ILM HA7ILM PSE K"; \done | \csdr psk31_varicode_encoder_u8_u8 | \csdr differential_encoder_u8_u8 | \csdr psk_modulator_u8_c 2 | \csdr gain_ff 256 | \csdr plain_interpolate_cc 256 | \csdr pulse_shaping_filter_cc COSINE 256 | \csdr shift_addition_cc 0.125 | \csdr realpart_cf | \csdr convert_f_s16 | \mplayer -cache 1024 -quiet \-rawaudio samplesize=2:channels=1:rate=8000 -demuxer rawaudio -Let's analyze each command. Varicode and differential encoding have been described in
sections 4.7 and 4.8. A common function for both commands, the PSK modulator can
generate a baseband N-PSK signal, mapping input bytes to samples at the given
constellation points:
csdr psk_modulator_u8_c <n_psk>

For a BPSK signal, n_psk=2 and the samples output are:52

•complex floating point 1+0 j for 0x00 byte input,•

complex floating point −1+ 0 j for 0x01 byte input.

To add pulse shaping, we need to interpolate these samples. We can either use thefunction psk31_interpolate_sine_cc the result of which is a valid BPSK31 baseband
signal, or carry out the raw interpolation (adding zero samples between the ones
corresponding to the symbols) and running the pulse shaping filterg(t ) in separate

steps, as in (5).
csdr psk31_interpolate_sine_cc <interpolation>
csdr plain_interpolate_cc <interpolation>
csdr pulse_shaping_filter_cc \(RRC <samples_per_symbol> <num_taps> <beta> | \COSINE <samples_per_symbol>)

The remaining csdr commands shift the signal up to 2 kHz and turn it into a real signal,then play it on the audio device.

5.2 Demodulating BPSK63
Note that using this transmitter and receiver structure, we can almost instantly derivedifferent modulations from a given one. For example, deriving a BPSK63 demodulator
from the command for BPSK31 is the matter of changing four numbers.
arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr '=-1000./48e3') | \csdr fir_decimate_cc 32 | \csdr bandpass_fir_fft_cc $(csdr '=-(62.5)/1.5e3') \$(csdr '=(62.5)/1.5e3') $(csdr '=62.5/1.5e3') | \csdr simple_agc_cc 0.001 0.5 | \csdr timing_recovery_cc GARDNER 24 0.5 2 --add_q | \CSDR_FIXED_BUFSIZE=1 csdr dbpsk_decoder_c_u8 | \CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8

The command below has been tested against a signal generated with Fldigi, as seen on
Figure 44.

53

Figure 44: BPSK63 demodulator developed quickly with CSDR

5.3 BPSK31 with different pulse shape
We can also easily derive new digital modes that previously did not exist from thecommand of an existing one. For example, building a custom version of BPSK31 thatuses RRC pulse shape can also be made by changing the command line, by adding the
RRC filter to both the receiver and the transmitter. The RRC filtered BPSK31 is
expected to be less sensitive to ISI.
The command below provides an RRC filtered BPSK31 transmitter ( β=0.5 ).
while true; do echo -n "CQ CQ CQ DE HA7ILM HA7ILM HA7ILM PSE K
done | \csdr psk31_varicode_encoder_u8_u8 | \csdr differential_encoder_u8_u8 | \csdr psk_modulator_u8_c 2 | \csdr gain_ff 64 | \csdr plain_interpolate_cc 256 | \csdr pulse_shaping_filter_cc RRC 256 1001 0.5 | \csdr shift_addition_cc 0.125 | \csdr realpart_cf | \csdr convert_f_s16 | \mplayer -cache 1024 -quiet -rawaudio \samplesize=2:channels=1:rate=8000 -demuxer rawaudio -"; \The change in the pulse shape can be instantly seen on the waveform as well, see Figure54

45 below.

Figure 45: Waveform of generated BPSK31 signal with RRC pulse shape
The demodulator command is as follows:
arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr '=-1000./48e3') | \csdr fir_decimate_cc 32 | \csdr pulse_shaping_filter_cc RRC 48 1001 0.5 | \csdr simple_agc_cc 0.001 0.5 | \csdr timing_recovery_cc GARDNER 48 0.5 2 --add_q | \CSDR_FIXED_BUFSIZE=1 csdr dbpsk_decoder_c_u8 | \CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8

Note that Fldigi was also found to correctly decode BPSK31 with RRC pulse shaping,although not optimized for that.

5.4 Costas loop for carrier recovery
The command below is a version of the BPSK31 demodulator that uses a Costas loop.
arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr '=-1000./48e3') | \csdr fir_decimate_cc 32 | \csdr bandpass_fir_fft_cc $(csdr '=-(31.25)/1.5e3') \$(csdr '=(31.25)/1.5e3') $(csdr '=31.25/1.5e3') | \csdr simple_agc_cc 0.001 0.5 | \csdr timing_recovery_cc GARDNER 48 0.5 2 --add_q | \CSDR_FIXED_BUFSIZE=1 csdr bpsk_costas_loop_cc 0.10 0.707 | \CSDR_FIXED_BUFSIZE=1 csdr realpart_cf | \CSDR_FIXED_BUFSIZE=1 csdr binary_slicer_f_u8 | \CSDR_FIXED_BUFSIZE=1 csdr differential_decoder_u8_u8 | \CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8

In this command, the Costas loop is placed after the symbol timing recovery phase. The
Gardner algorithm still works well if a small, additional phase or frequency offset ispresent. This way the Costas loop works on one sample per symbol, and tries to rotate
the samples back, as near to the ideal BPSK constellation points as possible.

55

In practice, the Costas loop was less efficient than the solution described in 4.7. This
could be improved upon if a coarse carrier recovery algorithm has been applied first. It
also helped if the waterfall display was improved so that it was easier to tune to the
PSK31 signal accurately.
However, the Costas loop described here is a general algorithm that could possibly used
for other modulations as well, not only BPSK31. The syntax of the related CSDR
function is as below:
csdr bpsk_costas_loop_cc <loop_bandwidth> <damping_factor> \[--dd | --decision_directed] [--output_error | \--output_dphase | --output_nco | \--output_combined <error_file> <dphase_file> <nco_file>]

Figure 46 shows the block diagram for the CSDR implementation of a Costas loop for
BPSK signals. Both of its input and output is complex floating point. It has a switch toturn it into decision directed mode (--dd or --decision_directed), then it implements thesame block diagram as on Figure 36.

Figure 46: Block diagram for non-data aided mode of
csdr bpsk_costas_loop_cc
Internally, it uses a second order loop filter, the structure of which is shown on Figure
47, where (20) and (21) are the formulas for calculating the α and β parameters [21].
α=4 ζ θn2

1+2 ζ θn +θ n

4 θ2n
β=
1+ 2 ζ θn +θ 2n

56

(20)

(21)

The ζ parameter is the damping factor, which is to be chosen to 0.707 for a criticallydamped loop. θn stands for the loop bandwidth. The same parameters are to be given to
the csdr bpsk_costas_loop_cc command.

Figure 47: Second order loop filter for PI controller
The error detector calculates I⋅Q in the default non-data aided mode, and calculates
the phase distance from the nearest symbol in decision directed mode. Its S-curve isshown on Figure 48.

Figure 48: S-curve of BPSK Costas loop in CSDR.
The blue line corresponds to the non-data aided mode,and the red line corresponds to the decision directed mode.

57

The

optional

parameters--output_error,--output_dphase,--output_nco

and--output_combined allow us to inspect how the algorithm works internally during
synchronization.
Figure X shows a situation where the input signal had a large frequency error and a highamount of noise, but the loop managed to achieve phase lock.

Figure 49: Internal operation of BPSK Costas loop in CSDR
If the frequency offset was too high and the loop did not manage to lock, see the error
signal in such a case on Figure 50.

Figure 50: The error signal when the Costas loop failed to lockI also created a GNU Radio test bench for this function, which allowed me to compare
my algorithm to the Costas loop built into GNU Radio.

58

The decision directed version of the Costas loop needs to decide about the closest
symbol to the given sample. Even if the non-data aided version is used, we still need todecide about it in the next step, because we want to turn the output samples into bits.
For this task, we can split the constellation into areas around the ideal constellation
points. If the sample falls into a given area, we can return the symbol mapped to it.

Figure 51: Operation of slicer
on BPSK signal
In case of BPSK, it is a very easy task: if the real part of the symbol is positive, we havea "1" symbol, else we have a "0" symbol, as on Figure 51.
The CSDR function to carry out this operation is called binary_slicer_f_u8, as hard
symbol decision is also referred to as "slicer". The syntax of the related CSDR function
is below. It applies hard symbol decision to the complex baseband input signal. It
outputs a 0x00 byte or a 0x01 byte based on the decision.
csdr binary_slicer_f_u8

5.5 Demodulating RTTY
Radioteletype (RTTY) is a system that originally consisted of two or more
electromechanical teleprinters in different locations, connected over a wireless link [22].
This mode has a long history on amateur radio bands: amateur radio operators havebeen using modified commercial teleprinters since the 1950s.
RTTY uses a 2-FSK modulated signal, which means transmitting two different tones for"0" and "1" symbols (also called "space" and "mark"), with a tone spacing of 170 Hz,

59and symbol rate of 45.45 baud. The line coding is similar to UART: there is a start bit, astop bit, and there are data bits in between. However, RTTY uses 5 data bits, encoded in
Baudot code instead of ASCII.
The Baudot code consists of two tables, one for letters and another for numbers andsymbols (figures). Two special codes were selected to change between tables. The
Baudot code is shown in Table 6.

Table 6: Baudot code table [24]I have implemented two different types of FSK demodulators for RTTY. The firstcommand uses an FM detector to acquire frequency information from the signal:
arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr =-2000/48e3) | \csdr fir_decimate_cc 48 | \CSDR_FIXED_BUFSIZE=128 csdr simple_agc_cc 0.0001 0.5 | \csdr peaks_fir_cc 31 $(csdr =85/1e3) $(csdr =-85/1e3) | \CSDR_FIXED_BUFSIZE=128 csdr fmdemod_quadri_cf | \CSDR_FIXED_BUFSIZE=128 csdr gain_ff 40 | \CSDR_FIXED_BUFSIZE=256 csdr serial_line_decoder_f_u8 22 5 1 | \CSDR_FIXED_BUFSIZE=4 csdr rtty_baudot2ascii_u8_u8

The other FSK demodulator compares the output of the space and mark filters to findout about the transmitted symbol:

60

arecord -r48000 -c1 -fS16_LE | \csdr convert_s16_f | \csdr dsb_fc | \csdr shift_addition_cc $(csdr =-2000/48e3) | \csdr fir_decimate_cc 48 | \CSDR_FIXED_BUFSIZE=128 csdr simple_agc_cc 0.0001 2 | \CSDR_FIXED_BUFSIZE=128 csdr bfsk_demod_cf $(csdr =2*85/1e3) 21 | \CSDR_FIXED_BUFSIZE=256 csdr serial_line_decoder_f_u8 22 5 1 | \CSDR_FIXED_BUFSIZE=1 csdr rtty_baudot2ascii_u8_u8

For both commands, first the audio data is acquired with arecord, then using the format
conversion, shift and FIR decimation operations in CSDR, the result is the complex
baseband FSK signal.

5.6 FSK demodulation
Both commands use bandpass filters, the center of which are the frequencies of thespace and mark tones. A peak filter is the opposite of a notch filter, passing only
frequencies in the immediate surroundings of a given center frequency. Withpeaks_fir_cc, a pair of peak filters are generated and their taps are added together. The
resulting filter passes only the two FSK tones. Longer filter length means sharper
passband. The syntax of related commands is below:
csdr firdes_peak_c <rate> <length> [window [--octave]]csdr peaks_fir_cc <taps_length> [peak_rate × N]

61

Figure 52: Transfer characteristic of peak filter with 31 taps
The taps of a single peak filter are calculated as:h(t )=f window { e j 2 π f t }p

In (22), f p is the frequency of the peak, and f window is the window function.

62

(22)

Figure 53: Filter passing two peaks in GNU Radio testbench
See a sample peak filter transfer charactersitic on Figure 62, and Figure 53 for a GNU
Radio simulation of two peaks at equal distance from DC, where the filter is driven withrandom input, so that the spectrum graph shows the approximate filter characteristic.
Now that we have our two tones selected with a bandpass filter, we need to know which
tone is currently on. The first command reuses the FM demodulator I have alreadywritten: fmdemod_quadri_cf.
The other way to sepearate the two frequencies is to calculate the power of the signal at
the output of each bandpass filter, and subtract them from each other. We can decide
between mark and space by checking if the result is above or below zero, see Figure 54.

Figure 54: Block diagram of FSK demodulator comparing the output ofmark and space band-pass filters
The command csdr bfsk_demod_cf implements a similar data flow, but it does not makethe decision: its output is processed by the serial line decoder function instead.
csdr bfsk_demod_cf <spacing> <filter_length>63

5.7 Serial line decoder
After applying any of the frequency discrimination methods above, our signal will look
like as in Figure 55.

Figure 55: FSK signal after frequency detector stage
The next problem to solve is symbol timing synchronization. The interesting part is,
RTTY works very similar to UART, with the difference of having 5 data bits instead of
8. An UART line is high by default. The UART receiver starts when it captures the zerocrossing at the beginning of the start bit, thus synchronization happens at each character.
I implemented a generic algorithm for recovering data from a sampled serial line, thus it
is not limited to decoding RTTY. The number of data bits and stop bits can be
configured. It is possible to put an ADC on a serial line, record a block of samples andthen process them with this command. The syntax is as follows:
csdr serial_line_decoder_f_u8 <samples_per_bits> [databits [stopbits]]

It synchronizes on the first falling edge of the start bit, samples the given number ofdata bits, and also checks the stop bit (see Figure 56).
It averages several samples from the middle of the data bit in order to make the bit
decision. (Currently, the number of samples to average can be adjusted internally in thecode.)

64

Figure 56: Internal operation of serial line decoder

5.8 Baudot decoder
As the data returned from serial_line_decoder_f_u8 is still in Baudot code, we need toturn it to ASCII, for which I have created a new function:
csdr rtty_baudot2ascii_u8_u8

See Table 6 for reference. As demonstrated on Figure 57, CSDR can be used to decodereal-world RTTY transmissions.

65

Figure 57: RTTY decoding with CSDR

5.9 Demodulating M-FSK
CSDR contains commands that are tailored for decoding multiple frequency-shift
keying. The generic slicer is to be used after the FM demodulator. It allows you to map
the frequency values to N distinct symbols:
csdr generic_slicer_f_u8 <n_symbols>

For example, if n_symbols is set to 3, it will output 0x00 for values in the (−∞; 0.5)
range, 0x01 for values in the range [−0.5, 0.5 ) and 0x02 for values in [ 0.5, ∞ ) .
A demonstration of 4-FSK demodulation has been included in CSDR, which can bestarted by loading grc_tests/test_m_fsk.grc into GNU Radio Companion. The 4-FSK
signal is generated by GNU Radio (see Figure 58), and the symbols are correctly
decoded by CSDR and written into a temporary file.

66

Figure 58: 4-FSK signal generated by GNU Radio is used as the input for the
demodulator built with CSDR

5.10 Demodulating FSK signals transmitted using the CC1111
wireless MCU
When I came up with the idea of CSDR, I imagined it as an universal command line
tool that can perform simple digital signal processing tasks for Software Defined Radio.
The purpose of this section is to show that with its recently introduced support for
digital modes, it is possible to use it for decoding signals of wireless devices that use
simple modulation schemes.
This is important because today IoT is a growing market, and many IoT devices
communicate wireless, mostly using WiFi, Bluetooth or the mobile network to connect
to the Internet. However, some devices communicate on the ISM bands with no67

encryption, and many IoT vendors have low security standards (not limited to wirelesscommunication, but for the whole system), so new vulnerabilities are found regularly byresearchers.
Reverse engineering of wireless protocols often starts with using an SDR receiver torecord some packets sent by the target, and then analyzing the baseband I/Q signal. For
the latter, the work the received signal is often obtained at a considerably good SNR,
and the task is to build a working demodulator as soon as possible, rather than buildinga receiver that works well even under bad conditions. For example, fine tuning theparameters of the Costas loop for maximum performance are less important than having
the decoded data at hand in this application.
As CSDR can be used as a digital modem, it could generate a modulated signal fromcrafted packets, and also for demodulation during interception. In the following part, an
example follows to demonstrate that FSK transmissions sent by the popular sub-GHz
wireless MCU, Texas Instruments CC1111 can be decoded with CSDR.
The YARD Stick One, produced by Great Scott Gadgets, can be considered as adevelopment board for the CC1111. With the open source RfCat firmware installed, theRF SoC on the panel can fully be controlled over USB: setting receiver and transmitterparameters, sending and receiving data can be carried out from a convenient IPython
shell on the host PC. While the YARD Stick One is a special development tool, many
commercial devices use the same chip, or use similar simple FSK modulation.
I started by setting up the YARD Stick One to send a known message.
$ rfcat -r #open the rfcat IPython shell#set frequency and data rate:
d.setFreq(433000000)
d.setMdmDRate(1000)#check radio parameters, make a note of the sync word:print d.reprRadioConfig()#transmit 100 packets:for i in range(0,100): d.RFxmit('test')

The radio is set up to transmit the message "test" at 1000 symbol/second, at 433 MHz.
While transmitting, I used an RTL-SDR to receive the signal.

68

rtl_sdr -f 433000000 rfcat.cu8

Note that you need to choose a frequency where you are legally allowed to transmit, or
you need to use a direct cable connection via an attenuator between the YARD Stick andthe SDR receiver.
In case of a completely unknown signal, the work would continue by analyzing thesignal to determine the modulation, estimating the symbol rate, etc. This could be donein GNU Radio or other tools, including the one shown in Figure 59, called Inspectrum.

Figure 59: Analyzing recorded I/Q signal with Inspectrum
Inspectrum shows us the spectrogram of recorded I/Q files, and it allows us todemodulate FSK manually by visually selecting the center frequency, the bandwidth andthe bit duration. I found the feature to put a grid on a packet to allow manual timing
recovery very intuitive, see Figure 60.

69Figure 60: Grid for manual timing recovery in Inspectrum, with the derived FSK
demodulated signal on the bottom subpane
I have exported the demodulated bits to the standard output, and broken the packet into
different parts:
1, 0, 1, 0, 1, 0, 1, 0, --- preamble
1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 1, 1, 0, 0, --- sync word: 0x0C4E
0, 1, 0, 0, 1, 1, 1, 0,
0, 1, 1, 1, 0, 1, 0, 0, --- 't'
0, 1, 1, 0, 0, 1, 0, 1, --- 'e'0, 1, 1, 1, 0, 0, 1, 1, --- 's'
0, 1, 1, 1, 0, 1, 0, 0 --- 't'

By looking at the datasheet of the CC1111 [10], one can easily find that the messages
follow the structure above. I have also verified that the transmitted sync word matches
the one in RfCat settings.
Manual tools like Inspectrum are not convenient if one wants to decode a high amountof packets. On that reason, I built an FSK demodulator using CSDR, similar to the one
for RTTY in section 5.5. While tuning the parameters of the timing recovery algorithm,70

I used its feature to plot the internal state with GNU Octave into PNG files, so that I
could make sure that each symbol is sampled at the correct phase (see Figure 61). I haveobserved that the Gardner algorithm successfully locked on the signal while receiving
the preamble.
One of the advantages of CSDR is that there is an easy way to see if the timing recovery
block managed to sample at the maximum eye opening. This is hard to do with a GNU
Radio flowgraph, as one has to manually, visually compare the results with the original
baseband signal in time domain.

Figure 61: Gardner algorithm locking on the FSK signal
sent by the CC1111 on the YARD Stick One
The following command demodulates the recorded signal, finds the preamble and thesynchronization word, and prints the bits of the packet following them:cat rfcat.cu8 | csdr convert_u8_f | \71

csdr fir_decimate_cc 10 $(csdr =50000./24e5) | \csdr shift_addition_cc $(csdr =42000/240000.) | \csdr fmdemod_quadri_cf | csdr gain_ff 4 | csdr dsb_fc | \csdr bandpass_fir_fft_cc -0.0001 0.0001 0.03 | \csdr timing_recovery_cc GARDNER 204 0.5 2 --add_q | \csdr realpart_cf | csdr binary_slicer_f_u8 | \csdr pattern_search_u8_u8 32 0 1 0 1 0 1 0 1 \0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, | xxd -g 1

In the output of the command one can inspect the bits of the first two packets:
00000000: 00 01 01 01 00 01 00 00 00 01 01 00 00 01 00 01
00000010: 00 01 01 01 00 00 01 01 00 01 01 01 00 01 00 00
00000020: 00 01 01 01 00 01 00 00 00 01 01 00 00 01 00 01
00000030: 00 01 01 01 00 00 01 01 00 01 01 01 00 01 00 00(...)................
................
................
................

Next I put together a command that receives the wireless transmissions of the CC1111
with the RTL-SDR, demodulates them and decodes the 4-byte test messages in realtime:
rtl_sdr -f433000000 -s2400000 - | \csdr convert_u8_f | \csdr fir_decimate_cc 10 $(csdr =50000./24e5) | \csdr shift_addition_cc $(csdr =35000/240000.) | \csdr fmdemod_quadri_cf | csdr gain_ff 4 | csdr dsb_fc | \csdr bandpass_fir_fft_cc -0.0001 0.0001 0.03 | \csdr timing_recovery_cc GARDNER 240 0.5 2 --add_q | \csdr realpart_cf | csdr binary_slicer_f_u8 |csdr pattern_search_u8_u8 32 1 0 1 0 1 0 1 \0 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, | \csdr pack_bits_8to1_u8_u8

Figure 62 shows this command in action.

72

Figure 62: CSDR decoding 4 byte packets
containing the string "test", sent from CC1111

5.11 Generating additive white Gaussian noise
Wireless channels are often modeled as channels with additive white Gaussian noise(AWGN) present. The awgn_cc function in CSDR does the same:
csdr awgn_cc <snr_db> [--awgnfile /path/to/file] [--snrshow]

It adds white Gaussian noise to the signal to achieve a given SNR, assuming that thesignal is clean and its power level is 0 dB. It can also measure the real SNR if the--snrshow switch is on, so that the snr_db parameter can be adjusted. The measured
SNR is printed on the standard error pipe.
While getting a block of uniform white noise is easy on a Linux system (basically,73

/dev/urandom generates uniform noise), some additional calculations are needed to get
Gaussian white noise. While both types of noise have the same flat spectrum, theiramplitude distribution is different, which can be observed on their histograms.
The Box-Muller transform (23) allows us to transform two uniformly distributed
random variables, U 0 and U 1 into two random variables with standard normal
distribution, Z 0 and Z 1 .
Z 0 =R cos(Θ)= √−2 lnU 0 cos(2 π U 1)
Z 1=R sin(Θ)=√−2 lnU 0 sin (2 π U 1)

(23)

Based on this formula, the method to generate 32-bit complex valued Gaussian white
noise is as follows:
1. Read 8 bytes from /dev/urandom, as 32 bit integers (int).
2. Cast them into 32-bit float and divide them by INT_MAX.
3. These numbers will be the current value of U 0 and U 1 . Apply the formula
above to get Z 0 and Z 1 .
4. Use the resulting values for Z 0 and Z 1 as the real and the imaginary part of theoutput random number.
There are also CSDR functions to generate noise in itself:
csdr uniform_noise_f
csdr gaussian_noise_c

As a note, generating noise based on /dev/urandom can be slow in some applications. I
measured a 10 Mbyte/s maximum reading speed. On this reason, a custom
pseudorandom number generator (PRNG) could be used, but the easiest way to speed up
thisprocessing

functionwastopre-generate

Gaussian

noise

using

csdr

gaussian_noise_cc into a file, and pass that to csdr awgn_cc. This is what the optional--awgnfile parameter can be used for.
The csdr awgn_cc function has been used to create noisy conditions while testing the
my demodulators against Fldigi, and also for generating the variance diagrams in
section 4.5.

74

5.12 Functions helping development
At the time of writing, the CSDR command-line tool had 103 functions. While
executing "csdr --help" gives a list of these functions, I have realized the need of easy
searching within the functions for their syntax, thus the "?<keyword>" search function
has been introduced. As an example, see the new command and its result below.
$ csdr ?psk
csdr ?: csdr 2>&1 | grep psk
psk31_varicode_encoder_u8_u8
psk31_varicode_decoder_u8_u8
psk_modulator_u8_c <n_psk>
psk31_interpolate_sine_cc <interpolation>bpsk_costas_loop_cc <loop_bandwidth> <damping_factor> <gain> (...)

The command above filters the help for CSDR commands containing "psk".
Another new function, "??<keyword >" opens the browser and jumps straight to thegiven function in the CSDR documentation on GitHub.
I have also repeatedly faced that some CSDR functions take parameters that areconvenient to be calculated using a formula. See the beginning of the CSDR command
for a simple NFM demodulator:
rtl_sdr -s 2400000 -f 145000000 -g 20 - | \csdr convert_u8_f | \csdr shift_addition_cc \`python -c "print float(145000000-145350000)/2400000"` | \csdr fir_decimate_cc 50 0.005 HAMMING | \csdr fmdemod_quadri_cf | \(...)

In this example, the rate parameter of csdr shift_addition_cc is calculated using Python.
(Similarly, in GNU Radio Companion, one can give mathematical expressions toparameters of blocks, and these are evaluated as Python expressions.) It lookedconvenient to create an easy to remember shorthand for calculations like that, resulting
in the "=<expression>" CSDR function. A simple example is shown below:$ csdr =3+4*5+pi
26.1415926536$ csdr '=(3+4)*5+pi'

75

38.1415926536

This method also uses Python for evaluating expressions. If there are parentheses in theexpression, it is advised to put it in quotes, as the shell would attempt to parse theparentheses. Now the same beginning part of the NFM demodulator looks as below:
rtl_sdr -s 2400000 -f 145000000 -g 20 - | \csdr convert_u8_f | \csdr shift_addition_cc $(csdr '=float(145000000-145350000)/2400000')|\csdr fir_decimate_cc 50 0.005 HAMMING | \csdr fmdemod_quadri_cf | \
(...)

76

6 Conclusion
The main objective of this thesis has been studying various methods and algorithms
used in digital modems. The topics I was most interested in were carrier and symbol
timing recovery algorithms, as these are essential for building demodulators. I reallyenjoyed implementing functional parts of BPSK and FSK demodulators, and putting
them together into working demodulator DSP chains.
In the future I am planning to add the RTTY receiver to the web UI, and I am alsointerested in improving the performance of the BPSK31 demodulator.

77

7 Acknowledgement
I would like to express my gratitude to my supervisor, Péter Horváth, PhD for teachingme so much about signal processing and wireless communication. Furthermore, I would
like to thank everyone who uses my open source projects, which inspires me to learn
more about Software Defined Radio.

78

8 Bibliography[1] R. X. Seger, "rx-tools", retrieved on 2017. 04. 04. from:https://github.com/rxseger/rx_tools[2] A. Retzler, "Software Defined Radio Receiver Application with Web-based Interface(BSc Thesis)", retrieved on 2017. 04. 14. from: http://openwebrx.org/bsc-thesis.pdf[3] B. Farhang-Boroujeny, Signal Processing Techniques for Software Radios, Lulu
Press, Inc., 2010.
[4] Wikipedia, "Raised-cosine filter", retrieved on 2016. 05. 22. from:https://en.wikipedia.org/wiki/Raised-cosine_filter[5] Wikimedia Commons, "Consecutive raised-cosine impulses, demonstrating zero-ISI
property", released under CC-BY-SA 3.0, retrieved on 2017. 05. 20. from:https://commons.wikimedia.org/wiki/File%3ARaised-cosine-ISI.svg[6] B. Umashankar, S. Aswathy, N. Prasad , C. Bhattacharya, K. K. Naik, "SOQPSK – A
Spectrally Efficient Modulation Scheme for Aeronautical Telemetry Applications",
International Journal of Engineering Science and Innovative Technology (IJESIT), Vol.
2, Issue 2, 2013. 03., retrieved on 2017. 04.21. from:http://www.ijesit.com/Volume%202/Issue%202/IJESIT201302_59.pdf[7] J. Taylor (K1JT), "The JT65 Communications Protocol", retrieved on 2016. 05. 23.
from: http://physics.princeton.edu/pulsar/K1JT/JT65.pdf[8] Espressif Inc., "ESP8266EX Overview", retrieved on 2017. 04. 07. from:https://espressif.com/en/products/hardware/esp8266ex/overview[9] D. Green, "GMRT photos", retrieved on 2017. 04. 04. from:https://www.mrao.cam.ac.uk/~dag/GMRT-PICS/2004-02b.jpg[10] Texas Instruments Inc., "Low-Power SoC (System-on-Chip) with MCU, Memory,
Sub-1 GHz RF Transceiver, and USB Controller", retrieved on 2017. 05. 20. from:http://www.ti.com/lit/ds/symlink/cc1110-cc1111.pdf

79

[11] S. L. Karty (N5SK), "PSK31 Spec", retrieved on 2016. 05. 22. from:http://www.arrl.org/psk31-spec[12] The MathWorks Inc., "Early-Late Gate Timing Recovery", retrieved on 2017. 04.
19. from: https://www.mathworks.com/help/comm/ref/earlylategatetimingrecovery.html[13] F. M. Gardner, "A BPSK/QPSK Timing-Error Detector for Sampled Receivers",
IEEE Transactions on Communications, vol. COM-34, 1986. 05., retrieved on 2017. 04.
19. from: http://ieeexplore.ieee.org/document/1096561/[14] The MathWorks Inc., "Gardner Timing Recovery", retrieved on 2017. 04. 19. from:https://www.mathworks.com/help/comm/ref/gardnertimingrecovery.html[15] NuRAN Wireless, "Symbol timing recovery methods for digital I/Q demodulator",
retrieved on 2017. 04. 19. from: https://www.nutaq.com/blog/symbol-timing-recoverymethods-digital-iq-demodulator[16] The MathWorks Inc., "Squaring Timing Recovery" retrieved on 2017. 04. 21. from:https://www.mathworks.com/help/comm/ref/squaringtimingrecovery.html[17] K. H. Mueller, M. Müller, "Timing Recovery in Digital Synchronous Data
Receivers", IEEE Transactions on Communications, Vol. COM-24, No. 5, 1974. 05.
[18] The MathWorks Inc., "comm.SymbolSynchronizer System object" retrieved on
2017. 04. 19. from:https://www.mathworks.com/help/comm/ref/comm.symbolsynchronizer-class.html[19] M. Renfors, "Synchronisation in Digital Receivers", retrieved on 2017. 04. 27.
from: http://www.cs.tut.fi/kurssit/TLT-5806/Synch.pdf[20] U. Mengali; A. N. D'Andrea, Synchronization Techniques for Digital Receivers,
Plenum Press, New York, 1997.
[21] T. Rondeau, "Control Loop Gain Values", retrieved on 2017. 04. 21. from:https://www.mathworks.com/help/comm/ref/squaringtimingrecovery.html[22] Wikipedia, "Radioteletype", retrieved on 2016. 05. 22. from:https://en.wikipedia.org/wiki/Radioteletype[23] Wikimedia Commons, "Costas loop", available under CC-BY-SA 4.0 license.
80Retrieved on 2016. 05. 22. from:https://en.wikipedia.org/wiki/Costas_loop#/media/File:Costas_loop_model.svg[24] Zs. Krüpl (HG2ECZ), "Magyar rádióamatőrök információs lapja", retrieved on
2016. 05. 23. from: http://www.ham.hu/[25] Wikipedia, "Costas loop after synchronization", available under CC-BY-SA 3.0
license, retrieved on 2016. 05. 22. from:https://en.wikipedia.org/wiki/Costas_loop#/media/File:Costas_loop_after_sync.svg[26] ESA Operations, "Signal from @ESA_EDM...", retrieved on 2017. 05. 21. from:https://twitter.com/boomtnt46/status/788748256608129024

81