+ All Categories
Home > Documents > UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Date post: 15-Aug-2015
Category:
Upload: sameer-murthy
View: 79 times
Download: 3 times
Share this document with a friend
Popular Tags:
120
Implementation of a Software FM Receiver using GNU Radio and the USRP ENGT 8310 - 8312 Major Individual Project THESIS Supervisor: Dr DAVID HUANG Head of Signal Processing and Wireless Communications Laboratory Department of Electrical, Electronics and Computer Engineering Student Name: SAMEER Student Number: 20184885 Date of Submission: 12 / 11 /2007 Revision History: Version 1: 30/09/2007 Created Version 2: 12/11/2007 Last Updated
Transcript
Page 1: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Implementation of a Software FM Receiver using GNU

Radio and the USRP ENGT 8310 - 8312 Major Individual Project

THESIS

Supervisor: Dr DAVID HUANG

Head of Signal Processing and Wireless Communications Laboratory

Department of Electrical, Electronics and Computer Engineering

Student Name: SAMEER

Student Number: 20184885

Date of Submission: 12 / 11 /2007

Revision History:

Version 1: 30/09/2007 Created

Version 2: 12/11/2007 Last Updated

Page 2: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

1

LETTER TO THE DEAN

# 30 / 24, Woodlands, Pearson Street,

Churchlands, Perth – 6018, WA

Date: 11/11/2007

The Dean

Faculty of Engineering Computing and Mathematics

The University of Western Australia

35 Stirling Highway

CRAWLEY WA 6009

Dear Sir

I submit to you this dissertation entitled “Implementation of a Software FM Receiver

using GNU Radio and the USRP” in partial fulfilment of the requirement of the award

of Master of Engineering.

Yours faithfully

Sameer

Page 3: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

2

(Image source: GNU Radio)

Welcome to the world of GNU Radio and Universal Software Radio Peripheral!

(Image source: Ettus Research LLC)

Page 4: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

3

Table of Contents

List of Illustrations.....................................................................................................4

I. ABSTRACT...........................................................................................................5

A. Key Terms......................................................................................................6

B. GNU (GNU’s Not Unix!) ..............................................................................6

II. ACKNOWLEDGEMENTS...............................................................................7

III. INTRODUCTION .............................................................................................8

A. Background....................................................................................................8

B. Purpose of the Project ....................................................................................9

IV. DESCRIPTION................................................................................................10

A. Basic Architecture in GNU Software Radio................................................10

B. The Software................................................................................................12

C. Hardware Requirements...............................................................................12

D. The Universal Software Radio Peripheral (USRP)......................................13

V. INSTALLATION OF GNU RADIO SOFTWARE AND USRP........................23

A. Installation of GNU Radio Step-by-Step .....................................................23

B. Installation of GNU Radio on Linux ...........................................................24

C. Installation of the USRP Hardware..............................................................30

VI. TESTING THE GNU RADIO SOFTWARE AND USRP..............................33

A Testing Data .................................................................................................33

B Testing Sound ...............................................................................................36

C. Evaluation and Demo using the BasicRX Daughterboard...........................36

VII. EXPLORING GNU RADIO PROGRAMS ....................................................40

A. Learning by Example...................................................................................40

VIII. IMPLEMENTATION OF FM RECEIVER ................................................43

A. Frequency Modulation .................................................................................43

B. FM Reception Methodology........................................................................44

C. FM Receiver Program..................................................................................48

IX. PROMISES OF GNU RADIO AND USRP....................................................60

A. Significance of USRP ..................................................................................60

B. Significance of GNU Radio .........................................................................62

X. RELATED AND FUTURE WORK....................................................................64

Page 5: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

4

XI. SUMMARY AND CONCLUSIONS ..............................................................64

XII. REFERENCES ................................................................................................65

XIII. SOURCES OF ILLUSTRATIONS .............................................................67

List of Illustrations

Figure 1. A GLONASS Receiver Figure 2. A GPS Receiver...............................8

Figure 3. Receive Path .................................................................................................10

Figure 4. Transmit Path................................................................................................10

Figure 5. The Universal Software Radio Peripheral (USRP) Block Diagram.............15

Figure 6. The USRP main motherboard with the FPGA, 4 ADCs and 4 DACs .........15

Figure 7. The USRP main motherboard with it’s up to 4 supporting daughter boards16

Figure 8. Basic RX daughterboard (Image source: GNU Radio) ................................19

Figure 9. Basic TX daughterboard (Image source: GNU Radio) ................................19

Figure 10. The FPGA schematic..................................................................................21

Figure 11. Digital Down Converter Block Diagram....................................................21

Figure 12. Spectrum of the 93.5 – 95.5MHz FM band................................................38

Figure 13. Spectrogram of an FM Receiver with sidebands. GNU Radio and USRP

running on Linux Ubuntu 7.04.....................................................................................39

Figure 14. Frequency Modulation(Image source: Wikipedia).....................................44

Figure 15. Shows our typical setup of a FM Receiver using the BasicTX

daughterboard, Antenna and USRP .............................................................................45

Figure 16. Block Diagram of FM Receiver and Quadrature Demodulator .................47

Figure 17. Shows the received FM station and its post demodulated signal. ..............59

Figure 18. The USRP is in use in all 38 of the countries colored red in this map. ......61

Figure 19. JTRS Seal ...................................................................................................62

Page 6: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

5

I. ABSTRACT

A major obstacle facing most radio platforms is the rigid nature of the current radio

platforms. At design time, all radio parameters are hard wired into the device and can

never be adapted to optimally serve a specific purpose. Software Defined Radio

(SDR) aims to change this reality by combining a collection of software modules with

minimal hardware, such that the waveforms transmitted and received are defined by

software, therefore allowing unprecedented flexibility in adapting the radio platform

to the current task at hand. Currently, adding an audio, video, or data stream to a radio

signal so it can be broadcast—a process known as modulation—is nearly always done

by dedicated electronics. The same is true with the reverse process— demodulation—

required to receive a transmission. Radio waves can be modulated in any number of

ways, and each way requires different circuitry.

The idea behind software-defined radio is to do all that modulation and demodulation

with software instead of with dedicated circuitry. The most obvious benefit is that

instead of having to build extra circuitry to handle different types of radio signals, we

can just load an appropriate program. One moment our computer could be an AM

radio, the next a wireless data transceiver—and then perhaps a TV set. Or we could

leverage the flexibility of software to do things that are difficult, if not impossible,

with traditional radio setups. An emergency message can be broadcasted on every FM

band; A dozen walkie-talkie channels could be scanned at once; or design and test a

new wireless data protocol; no problem with the software radio.

This paper presents the design, testing and implementation of a complete SDR

framework on a Linux Operating System. A case study of a simple Frequency

Modulated (FM) radio is used to showcase the flexibility of the SDR solution. The

functionality of the SDR framework is tested on actual hardware utilizing a Personal

Computer (PC) to run the software related tasks and an external board that receives

the signal at radio frequency, down-converts it to a lower intermediate frequency, and

finally presents digitized samples for processing by the PC. Full testing and

implementation results are presented, complemented by a thorough discussion of the

design process.

Page 7: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

6

A. Key Terms

GNU radio, Python, Decimation, Frequency Modulation (FM), Frequency

Demodulation, GNU Radio, Software Defined Radio (SDR), Universal Software

Radio Peripheral (USRP)

B. GNU (GNU’s Not Unix!)

GNU is a computer operating system composed entirely of free software. Its name is a

recursive acronym for GNU's Not Unix, which was chosen because its design is Unix-

like, but differs from Unix by being free software and by not containing any Unix

code.GNU was founded by Richard Stallman and was the original focus of the Free

Software Foundation (FSF).

The project to develop GNU is known as the GNU Project, and programs

released under the auspices of the GNU Project are called GNU packages or GNU

programs. According to Stallman, the name “GNU” was inspired by various plays on

words, including the song The Gnu. The goal was to bring a wholly free software

operating system into existence [1].

The GNU Project was launched in 1984 to develop a complete Unix-like operating

system which is free software: the GNU system. Variants of the GNU operating

system, which use the kernel called Linux, are now widely used; though these systems

are often referred to as “Linux”, they are more accurately called GNU/Linux systems.

GNU is a recursive acronym for “GNU's Not Unix”; it is pronounced guh-noo,

approximately like canoe [2].

Page 8: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

7

II. ACKNOWLEDGEMENTS

My sincere thanks to University of Western Australia, for providing all the

opportunities, and imparting the wonderful higher education to me.

I express my deep sense of gratitude to Dr David Huang for his time-to-time; much

needed valuable guidance and would like to thank him for his support and

encouragement throughout the project.

I wish to express my profound thanks to A/Prof Gary Bundell, our esteemed Head of

the Department of Electrical, Electronics and Computer Engineering for his immense

support, hearted encouragement and ever lasting inspiration.

I am highly indebted to SPWCL-Lab, UWA, which helped me with valuable and wide

resources and also making available to me the necessary infrastructure.

Pursuing this project has been a very exciting experience and educative. I was

exposed to quite a lot of information and had the opportunity of working with other

students of the SPWCL research group. I would also like to show a huge appreciation

to Dawei Shen, University of Notre Dame Research Group, for creating the tutorials

on GNU Radio.

Finally, salutations to my family, friends and colleagues, Ramya K N, Mihir Patel and

Tejas Bokare, for their much needed moral support and encouragement that has been

provided under numerous occasions and making this project successful.

Page 9: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

8

III. INTRODUCTION

A. Background

Software radio is the technique of getting code as close to the antenna as possible. It

turns radio hardware problems into software problems. The fundamental characteristic

of software radio is that software defines the transmitted waveforms, and software

demodulates the received waveforms. What this means is that it turns the digital

modulation schemes used in today's high performance wireless devices into software

problems. This is in contrast to most radios in which the processing is done with

either analog circuitry or analog circuitry combined with digital chips. GNU Radio is

a free software toolkit for building software radios [3].

Software radio is a revolution in radio design due to its ability to create radios that

change on the fly, creating new choices for users. At the baseline, software radios can

do pretty much anything a traditional radio can do. The exciting part is the flexibility

that software provides us. Instead of a bunch of fixed function gadgets, in the next

few years we'll see a move to universal communication devices. Imagine a device that

can morph into a cell phone and get us connectivity using GPRS, 802.11 Wi-Fi,

802.16 WiMax, a satellite hookup or the emerging standard of the day. We could

determine our location using Global Positioning System (GPS), Global Navigation

Satellite System (GLONASS) or both [3].

Figure 1. A GLONASS Receiver Figure 2. A GPS Receiver

Page 10: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

9

Perhaps most exciting of all is the potential to build decentralized communication

systems. If we look at today's systems, the vast majority is infrastructure-based.

Broadcast radio and TV provide a one-way channel, are tightly regulated and the

content is controlled by a handful of organizations. Cell phones are a great

convenience, but the features our phone supports are determined by the operator's

interests, not ours [3].

A centralized system limits the rate of innovation. Instead of cell phones being

second-class citizens, usable only if infrastructure is in place and limited to the

capabilities determined worthwhile by the operator, we could build smarter devices.

These user-owned devices would generate the network. They'd create a mesh among

themselves, negotiate for backhaul and be free to evolve new solutions, features and

applications [3].

B. Purpose of the Project

This project is building on the available research results with the aim of developing a

complete SDR framework within the Signal Processing and Wireless Communication

Laboratory (SPWCL) at the University of Western Australia. A simple FM receiver

was selected as an initial case study to showcase the methodology, however the

comprehensive knowledge of SDR techniques accumulated within this project will be

used to pave the way for future advanced radios. This research consists of various

phases as follows: introductory theoretical analysis, Installation, testing and

customizing the GNU software code and final implementation and result verification

of the receiver.

In this academic semester, we will build the environment of GNU radio on Windows

and Linux operating systems, be familiar with it, and learn how to use the existing

libraries and modules to accommodate different applications.

Page 11: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

10

IV. DESCRIPTION

A. Basic Architecture in GNU Software Radio

PC USRP (mother board)

Figure 3. Receive Path

PC USRP (mother board)

Figure 4. Transmit Path

Figure 3 and 4: Typical software radio block diagram

Figure 3, shows a typical block diagram for a software radio. To understand the

software part of the radio, we first need to understand a bit about the associated

hardware. Examining the receive path in the figure, we see an antenna, a mysterious

RF front end, an analog-to-digital converter (ADC) and a bunch of code. The USB

and FPGA details can be found in the [Appendix A].

A.1 Analog to Digital Converter (ADC)

The analog-to-digital converter is the bridge between the physical world of

continuous analog signals and the world of discrete digital samples manipulated by

software.

ADCs have two primary characteristics, sampling rate and dynamic range.

Sampling rate is the number of times per second that the ADC measures the analog

User Defined Code

USB FPGA DAC RF Front End

User Defined Code

USB FPGA ADC RF Front End

Page 12: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

11

signal. Dynamic range refers to the difference between the smallest and largest signal

that can be distinguished; it's a function of the number of bits in the ADC's digital

output and the design of the converter. For example, an 8-bit converter at most can

represent 256 (28) signal levels, while a 16-bit converter represents up to 65,536

levels. Generally speaking, device physics and cost impose trade-offs between the

sample rate and dynamic range.

After getting through the ADC, the continuous signal becomes a sequence of

numbers entering the computer, which can be processed digitally as an array in the

software [3].

A.2 The RF Front End

To understand the role of the RF front end, we need to talk about a bit of theory.

Nyquist theorem tells us that, to avoid aliasing when converting from analog to

digital, the ADC sampling frequency must be at least twice the bandwidth of the

signal of interest, in order to sustain all the spectrum information accurately.Aliasing

is what makes the wagon wheels look like they're going backward in the old westerns:

the sampling rate of the movie camera is not fast enough to represent the position of

the spokes unambiguously [3].

Assuming we're dealing with low pass signals - signals where the bandwidth of

interest goes from 0 to fMAX, the Nyquist criterion states that our sampling frequency

needs to be at least 2 * fMAX. But if our ADC runs at 64 MS/s, how can we listen to

broadcast FM radio at 94.5 MHz? The answer is the RF front end. The receive RF

front end translates a range of frequencies appearing at its input to a lower range at its

output. For example, we could imagine an RF front end that translated the signals

occurring in the 90 - 100 MHz range down to the 0 - 10 MHz range.

Mostly, we can treat the RF front end as a black box with a single control, the center

of the input range that's to be translated. As a concrete example, a cable modem tuner

module translates a 6 MHz chunk of the spectrum centered between about 50 MHz

and 800 MHz down to an output range centered at 5.75 MHz. The center frequency of

the output range is called the intermediate frequency, or IF [3].

Page 13: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

12

B. The Software

The digital signals finally get into the computer. What waits for them is our code-the

so called software. GNU Radio is a set of signal processing tools for the computer. It

encompasses hundreds of signal processing blocks and a few graphical utilities. It can

tie in with hardware such as USRP and various ADC/DAC PCI cards. Signal

processing blocks are written in C++, while creating flow graphs and connecting

signal blocks is done in an interpreted language called Python.

GNU Radio provides a library of signal processing blocks and the glue to tie it all

together. The programmer builds a radio by creating a graph (as in graph theory)

where the vertices are signal processing blocks and the edges represent the data flow

between them. Conceptually, blocks process infinite streams of data flowing from

their input ports to their output ports. Blocks' attributes include the number of input

and output ports they have as well as the type of data that flows through each. The

most frequently used types are short, float and complex.

Some blocks have only output ports or input ports. These serve as data sources

and sinks in the graph. There are sources that read from a file or ADC, and sinks that

write to a file, digital-to-analog converter (DAC) or graphical display. About 100

blocks come with GNU Radio. Graphs are constructed and run in Python [3].

B.1 Graphical User Interfaces

Graphical interfaces for GNU Radio applications are built in Python. Interfaces may

be built using any toolkit we can access from Python; wxPython is recommended to

maximize cross-platform portability. GNU Radio provides blocks that use

interprocess communication to transfer chunks of data from the real-time C++ flow

graph to Python-land [3].

C. Hardware Requirements

GNU Radio is reasonably hardware-independent. Today's commodity multi-gigahertz,

super-scalar CPUs with single-cycle floating-point units mean that serious digital

Page 14: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

13

signal processing is possible on the desktop. A 3 GHz Pentium or Athlon can evaluate

3 billion floating-point FIR taps/s. We now can build, virtually all in software,

communication systems unthinkable only a few years ago.

Our computational requirements depend on what we're trying to do, but generally

speaking, a 1 or 2 GHz machine with at least 512 MB of RAM should suffice. We

also need some way to connect the analog world to our computer. Low-cost options

include built-in sound cards and audiophile quality 96 kHz, 24-bit, add-in cards. With

either of these options, we are limited to processing relatively narrow band signals

and need to use some kind of narrow-band RF front end [3].

Another possible solution is an off-the-shelf, high-speed PCI analog-to-digital board.

These are available in the 20M sample/sec range, but they are expensive, about the

cost of a complete PC. For these high-speed boards, cable modem tuners make

reasonable RF front ends.

Finding none of these alternatives completely satisfactory, the Universal

Software Radio Peripheral or USRP for short was designed [3]. Regarding the RF

front end and AD/DA converters, there are certainly many choices. However, the

Universal Software Radio Peripheral (USRP) board, which is designed wholly for

GNU Radio, is strongly recommended. In fact, most GNU Radio players are using

USRP boards. Not only because they are nice and convenient to use, but also because

we can get the most technical supports from the GNU Radio community. So, to make

our life simpler, we just choose the USRP.

D. The Universal Software Radio Peripheral (USRP)

Our preferred hardware solution is the Universal Software Radio Peripheral (USRP).

These days, when we talk about the GNU Radio, the Universal Software Radio

Peripheral (USRP) board has become an indispensable hardware component. It is

developed by Matt Ettus [4] wholly for the GNU Radio users. Basically, the USRP is

an integrated board which incorporates AD/DA converters, some forms of RF front

end, and a field programmable gate array (FPGA) which does some important but

computationally expensive pre-processing of the input signal. The USRP is low-cost

Page 15: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

14

and high speed, which is the best choice for a GNU Radio user to implement some

real time applications. We could purchase the USRP board from Ettus Research LLC

[4].

Figure 5, shows the block diagram of the USRP. The brainchild of Matt Ettus, the

USRP is an extremely flexible USB device that connects our PC to the RF world. The

USRP consists of a small motherboard containing up to four 12-bit 64M sample/sec

ADCs, four 14-bit 128M sample/sec DACs, a million gate-field programmable gate

array (FPGA) and a programmable USB 2.0 controller. Each fully populated USRP

motherboard supports four daughterboards, two for receive and two for transmit. RF

front ends are implemented on the daughterboards. A variety of daughterboards are

available to handle different frequency bands. For amateur radio use, low-power

daughterboards are available that receive and transmit in the 440 MHz band and the

1.24 GHz band. A receive-only daughterboard based on a cable modem tuner is

available that covers the range from 50 MHz to 800 MHz. Daughterboards are

designed to be easy to prototype by hand in order to facilitate experimentation[3].

The flexibility of the USRP comes from the two programmable components on the

board and their interaction with the host-side library. To get a feel for the USRP, let's

look at its boot sequence. The USRP itself contains no ROM-based firmware, merely

a few bytes that specify the vendor ID (VID), product ID (PID) and revision. When

the USRP is plugged in to the USB for the first time, the host-side library sees an

unconfigured USRP [3].

Page 16: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

15

Figure 5. The Universal Software Radio Peripheral (USRP) Block Diagram

Figure 6. The USRP main motherboard with the FPGA, 4 ADCs and 4 DACs (Image source: Ettus Research LLC)

Receive

Daughterboard

FPGA

DAC

DAC

ADC

ADC

ADC

ADC

DAC

DAC

FX2 USB 2.0

Controller

Receive

Daughterboard

Transmit

Daughterboard

Transmit

Daughterboard

Page 17: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

16

The library can tell it's unconfigured by reading the VID, PID and revision. The first

thing the library code does is download the 8051 code that defines the behavior of the

USB peripheral controller. When this code boots, the USRP simulates a USB

disconnect and reconnect. When it reconnects, the host sees a different device: the

VID, PID and revision are different. The firmware now running defines the USB

endpoints, interfaces and command handlers. One of the commands the USB

controller now understands is load the FPGA. The library code, after seeing the USRP

reconnect as the new device, goes to the next stage of the boot process and downloads

the FPGA configuration bit stream [3].

FPGAs are generic hardware chips whose behavior is determined by the

configuration bit stream that's loaded into them. We can think of the bit stream as

object code. The bit stream is the output of compiling a high-level description of the

design. In our case, the design is coded in the Verilog hardware description language.

This is source code and, like the rest of the code in GNU Radio, is licensed under the

GNU General Public License [3]. A typical setup of the USRP board consists of one

mother board and up to four daughter boards, as shown in Figure 7. On the mother

board, we can see the DC power input and the USB 2.0

Figure 7. The USRP main motherboard with it’s up to 4 supporting daughter boards (Image source: USRP User’s and Developer’s Guide)

Page 18: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

17

D.1. Features

• Four 64 MS/s 12-bit analog to digital Converters

• Four 128 MS/s 14-bit digital to analog Converters

• Four digital downconverters with programmable decimation rates

• Two digital upconverters with programmable interpolation rates

• High-speed USB 2.0 interface (480 Mb/s)

• Capable of processing signals up to 16 MHz wide

• Modular architecture supports wide variety of RF daughterboards

• Auxiliary analog and digital I/O support complex radio controls such as RSSI

and AGC

• Fully coherent multi-channel systems (MIMO capable)

D.2. Specifications

Supported Operating Systems

• Linux

• Mac OS X

• Windows XP, Windows 2000

• FreeBSD, NetBSD

Input

• Number of input channels: 4 (or 2 I-Q pairs)

• Sample rate: 64 Ms/s

• Resolution: 12 bits

• SFDR: 85 dB

Output

• Number of output channels: 4 (or 2 I-Q pairs)

• Sample rate: 128 Ms/s

• Resolution: 14 bits

• SFDR: 83 dB

Page 19: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

18

Auxiliary I / O

• High-speed digital I/O: 64 bits

• Analog input: 8 channels

• Analog output: 8 channels

D.3. The daughter boards

On the mother board there are four slots, where we can plug in up to 2 RX daughter

boards and 2 TX daughter boards. The daughter boards are used to hold the RF

receiver interface or tuner and the RF transmitter.

There are slots for 2 TX daughter boards, labelled TXA and TXB, and 2

corresponding RX daughter boards, RXA and RXB. Each daughter board slot has

access to 2 of the 4 high-speed AD / DA converters (DAC outputs for TX, ADC

inputs for RX). This allows each daughter board which uses real (not IQ) sampling to

have 2 independent RF sections, and 2 antennas (4 total for the system). If complex

IQ sampling is used, each board can support a single RF section, for a total of 2 for

the whole system [5]. Different daughter boards handle different frequency ranges,

giving the USRP an overall potential range of 0 hertz to 2.9 gigahertz, which covers

everything from AM radio, through FM and television, to beyond Wi-Fi.

We can see there are two SMA connectors on each daughter board. We normally use

them to connect the input or output signals. Most of the USRP daughter boards use

SMA-F connectors for hooking up antennas.

There are several kinds of daughter boards available now from Ettus Research

[4].The daughter boards used in this project are only discussed in the following

section.

D.3.1 Basic Receiver (BasicRX) and Basic Transmitter (BasicTX) daughter

boards

1 MHz to 250 MHz Receiver and Transmitter

Page 20: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

19

The BasicTX and BasicRX are designed for use with external RF frontends as an

intermediate frequency (IF) interface. Two SMA connectors are used to connect

external tuners or signal generators. We can treat it as an entrance or an exit for the

signal without affecting it. The ADC inputs and DAC outputs are directly

transformer-coupled to SMA connectors (50Ω impedance) with no mixers, filters, or

amplifiers.

The BasicTX and BasicRX give direct access to all of the signals on the

daughterboard interface (including 16 bits of high-speed digital I/O, SPI and I2C

buses, and the low-speed ADCs and DACs), and as such are useful for developing our

own daughterboards or custom FPGA designs.

Figure 8. Basic RX daughterboard (Image source: GNU Radio)

Figure 9. Basic TX daughterboard (Image source: GNU Radio)

Page 21: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

20

D.4 The FPGA

An FPGA is like a small, massively parallel computer that we design to do exactly

what we want. Programming the FPGA takes a bit of skill, and mistakes can fry the

board permanently. That said, a standard configuration is provided that is useful for a

wide variety of applications.

Using a good USB host controller, the USRP can sustain 32 MB/sec across the USB.

The USB is half-duplex. Based on our needs, we can partition the 32 MB/sec between

the transmit and the receive directions. In the receive direction, the standard

configuration allows us to select the part or parts of the digitized spectrum we're

interested in, translate them to baseband and decimate as required. This is exactly

equivalent to what's happening in the RF front end, only now we're doing it on

digitized samples. The block of code that performs this function is called a digital

down converter (Figure 11, “Digital Down Converter Block Diagram”). One

advantage of performing this function in the digital domain is we can change the

center frequency instantaneously, which is handy for frequency hopping spread

spectrum systems [3].

In the transmit direction, the exact inverse is performed. The FPGA contains multiple

instances of the digital up and down converters. These instances can be connected to

the same or different ADCs, depending on our needs [3].

The FPGA being used on the USRP is an Altera Cyclone EP1C12Q240C8

The hardware language used to describe the functionality within the FPGA is written

in Verilog and synthesized using Altera's free web tool Quartus II. The FPGA runs off

a 64MHz clock with every internal component synchronous to that global clock. Due

to the relatively high clocking frequency, everything within the FPGA is highly

pipelined to achieve the highest speed possible [6].

Page 22: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

21

Figure 10. The FPGA schematic [Appendix A – Details of the block diagram]

Figure 11. Digital Down Converter Block Diagram

Page 23: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

22

NOTE: The function of the Digital Down Converter block is explained in Section

VIII, “Implementation of FM receiver”.

So far, we have completed the introduction to the software and hardware description

of our Software Defined Radio project. In the next few sections we will focus on the

software and the hardware setup / installation for our project.

Page 24: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

23

V. INSTALLATION OF GNU RADIO SOFTWARE AND USRP

A. Installation of GNU Radio Step-by-Step

In the following sections I would like to introduce the installation procedure of the

GNU Radio on the Linux Ubuntu 7.04 Machine and also would like to describe what

worked for me in the process of installation, the difficulties faced and how they were

resolved.

Installing GNU Radio is probably the biggest leap for a beginner. GNU Radio

can run on any platform, however, some installations are easier than others. GNU

Radio must be compiled from source and all of the dependencies have to be taken

care of. If our heart is set on Windows, we can install GNU Radio using Cygwin

[Appendix B]. If an extra PC can be spared, GNU Radio can be best installed on

Ubuntu Linux.

The GNU Radio software, in addition to its own code, relies on a lot of thirdparty

software from other free and open-source projects. Getting all this additional software

up and running is actually the trickiest part of setting up GNU Radio, and the

difficulty is compounded by both a lack of reliable documentation and out-of-date

software. The documentation is poor and just getting started is not obvious.

Once we have the software up and running, we know that programs for GNU Radio

are written using the C++ and Python languages. The conceptual approach is to treat

the various parts of the system as modules that send information to one another,

allowing programmers to concentrate on whatever piece they are interested in, while

treating the other modules as black boxes.

Routing between modules is done with Python, so that a developer might write

a Python program that uses an off-the-shelf “source” module, which grabs a chunk of

radio spectrum from the hardware, and a similar “sink” module, which sends the

output of the program to, say, a set of speakers or a radio transmitter. In between the

source and sink modules the developer could put a custom signal-processing module,

which itself would be written in C++ (signal processing is not done with Python for

performance reasons). This gives developers the ability to assemble working systems

Page 25: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

24

rapidly. Plenty of sample programs are included with the software to give new

developers a head start.

A.1 Windows

GNU Radio definitely works in Windows XP.GNU Radio can be installed under the

Cygwin environment [Appendix B].

A.2 Linux

Ubuntu Linux is very nice for GNU Radio because all the dependencies can be easily

met. We simply have to select the correct check boxes and click install. Also, the

pains free and best part of Linux is that everything is open source and free.

What we will need:

• PC with USB 2.0 and DVD drive,

• Linux Ubuntu Edgy 6.10 or Feisty 7.04DVD,

• USRP,

• An internet connection,

• The better part of an afternoon.

B. Installation of GNU Radio on Linux

NOTE: This project uses the official release of GNU Radio software version 3.0.3.

The following procedures and scripts have been taken from the official GNU software

radio documentation [8].

B.1 Installation Options

Installation on Ubuntu 7.04 ("Feisty") systems may be completed using binary

packages and a package manager, or may be done by download and source compile.

Page 26: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

25

The following sections provides information and scripts to compile and install GNU

Radio and its required background applications, libraries, and includes on Ubuntu

Linux 6.10 ("Edgy") or 7.04 ("Feisty").

NOTE: The official releases of GNU Radio, version 3.0.3 or earlier, will NOT

reliably function on Feisty when using a USRP; the USRP will work once, then fail

and require the USRP to be power cycled or Ubuntu to be rebooted. Fixes for correct

functionality are available in the SVN trunk.

B.2 Pre-Requisites for Source Build

The following packages are required for compiling various parts of GNU Radio on

Ubuntu. These packages can be installed via "synaptic", "dselect", or "apt-get". We

use the latest versions of all packages unless otherwise noted.

Development Tools (need for compilation)

• g++

• subversion

• make

• autoconf, automake, libtool

• sdcc (from "universe"; 2.4 or newer)

• guile (1.6 or newer)

Libraries (need for runtime and for compilation)

• python-dev

• FFTW 3.X (fftw3, fftw3-dev)

• cppunit (libcppunit and libcppunit-dev)

• Boost (libboost and libboost-dev)

• libusb and libusb-dev

• wxWidgets (wx-common) and wxPython (python-wxgtk2.6)

• python-numpy (via python-numpy-ext) (for SVN on or after 2007-May-28)

• ALSA (alsa-base, libasound2 and libasound2-dev)

• Qt (libqt3-mt-dev; version 4 does not seem to work)

Page 27: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

26

• SDL (libsdl-dev)

SWIG (1.3.31 or newer required)

• Edgy or previous: requires installation from source

• Feisty or newer: use the standard package install (swig)

QWT (optional) (5.0.0 or newer required)

• Must be installed from source (as of 2007-05-07), as both Edgy and Feisty

provide 4.2.

Other useful packages

• doxygen (for creating documentation from source code)

• usbview (from "universe")

• octave (from "universe")

B.3 Broken libtool on Debian and Ubuntu

Because Debian and Ubuntu apply a poorly implemented "enhancement" to the

upstream version of libtool, they break the ability to test code and libraries prior to

installing them. We think that testing before installation is a good idea. To work

around their damage, be sure to include $PREFIX/lib (and $PREFIX/lib64 on 64-bit

machines) in /etc/ld.so.conf.

If we don't include $PREFIX/lib in /etc/ld.so.conf, we will see errors during

the linking phase of the build. There are several places it shows up. The first one is

often during the build of mblocks. It's not an mblock problem. It's a Debian/Ubuntu

problem.

We do this to work around the "feature":

$ cp /etc/ld.so.conf /tmp/ld.so.conf

$ echo /usr/local/lib >> /tmp/ld.so.conf

Page 28: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

27

$ sudo mv /tmp/ld.so.conf /etc/ld.so.conf

$ sudo ldconfig

B.4 Install Scripts

The following are scripts to take us through a GNU Radio install on a typical Ubuntu

Edgy or Feisty install, with the hope that it provides enough guidance such that we

can get GNU Radio up and running on our Ubuntu box.

• This section is for Edgy or previous only (no changes are needed on Feisty):

Manually we have to uncomment all repositories to include "universe" and

"multiverse" either via direct editing

sudo <EDITOR> /etc/apt/sources.list

or via the provided GUI: System -> Administration -> Software Sources. Then we

enter the admin password for access. On the "Ubuntu" tab, we have to make sure all

of "main restricted universe multiverse" are checked and the rest unchecked (or deal

with those are we deem correct for our setup). We click "Close", then "Reload" to

update the package list.

The uncommented lines of the file "/etc/apt/sources.list" should read something like:

deb http://us.archive.ubuntu.com/ubuntu/ edgy main restricted universe

multiverse

deb http://us.archive.ubuntu.com/ubuntu/ edgy-updates main restricted

universe multiverse

deb http://security.ubuntu.com/ubuntu/ edgy-security main restricted

universe multiverse

Page 29: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

28

We update the local dpkg cache:

sudo apt-get update

Then we install required packages (some are likely already installed by Ubuntu by

default; some are likely redundant with others; but this group works well for both

Edgy and Feisty)

sudo apt-get -y install g++ automake1.9 libtool python-dev fftw3-dev

libcppunit-dev libboost-dev sdcc libusb-dev libasound2-dev libsdl1.2-dev

python-wxgtk2.6 subversion guile-1.6 libqt3-mt-dev python-numpy-ext

We also install optional packages, if desired; some might already be installed from the

previous command:

sudo apt-get -y install gkrellm wx-common libwxgtk2.6-dev alsa-base

autoconf xorg-dev g77 gawk bison openssh-server emacs cvs usbview octave

Get, Compile (if needed), And Install SWIG

• Edgy or previous:

$ wget http://superb-east.dl.sourceforge.net/sourceforge/swig/swig-

1.3.31.tar.gz

$ tar zxf swig-1.3.31.tar.gz

$ cd swig-1.3.31

$ ./configure

$ make

$ sudo make install

Page 30: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

29

$ cd ..

• Feisty or newer:

sudo apt-get -y install swig

Get, Compile, Install QWT 5.0.0 or newer (optional):

• NOTE: We should not need to set the environment variables "QTDIR" or

"QWT_CFLAGS", so leave them be (for now).

wget http://superb-east.dl.sourceforge.net/sourceforge/qwt/qwt-5.0.2.tar.bz2

tar jxf qwt-5.0.2.tar.bz2

cd qwt-5.0.2

Now we edit qwtconfig.pri:

• Change the unix version of "INSTALLBASE" to "/usr/local" (was

"/usr/local/qwt-5.0.2");

• Change "doc.path" to "$$INSTALLBASE/doc/qwt" (was

"$$INSTALLBASE/doc");

• Save, exit.

The "doc" portion is in both HTML and man-style, but is all in /usr/local/doc/

html,man. While this isn't the standard path, there doesn't seem to be an easy way to

separate them and thus this is left as is. Then:

qmake

make

sudo make install

Page 31: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

30

Download, bootstrap, configure, and compile GNU Radio:

svn co http://gnuradio.org/svn/gnuradio/trunk gnuradio

cd gnuradio

./bootstrap

./configure

make

Optionally: We run the GNU Radio software self-check; does not require a USRP.

make check

If any test or tests do not work, GNU Radio might still function properly, but it might

be wise to look in the email archives for a fix or to write the email list. If writing to

the email list, we need to include the OS type, OS version, and CPU type (e.g. via

"uname -a"), anything special about the computer hardware, software versions (gcc,

g++, swig, sdcc, etc) and how it has been installed (standard or non-standard package,

source).

Now we install GNU Radio for general use (default is in to /usr/local):

sudo make install

C. Installation of the USRP Hardware

When we unpack the hardware, we'll find various boards and screws and such. The

Ettus Research’s "USRP User's and Developer's Guide” [Appendix C], describes how

to assemble the hardware, and discusses some parts of the installation.

Page 32: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

31

WARNING : We plug in or unplug daughter boards only when the power is off.

If we forget this, we'll blow the tiny on-board fuse at "F501" (we can follow the trace

on top from the power connector; it's the first thing the trace leads to), and the board

will stop working.

Then we plug the Power cord into the USRP. We should see a green LED (hidden

under the "RXA" daughterboard, which is nearest to the USB connector) blinking at

about 2Hz (twice a second). Then we plug in the USB connector between the USRP

and the computer.

For the moment we will need to have root privileges to access the USRP.

We have to type "su" and hit Enter. When prompted for a password, we type the root

password and hit Enter.

NOTE: The following procedures and scripts have been taken from the official GNU

software radio documentation [8].

B.1 Installation scripts

Ubuntu uses udev for handling hotplug devices, and does not by default provide non-

root access to the USRP. The following script sets up groups to handle USRP via

USB, either live or hot-plug

sudo addgroup usrp

sudo addgroup <OUR_USERNAME> usrp

echo 'ACTION=="add", BUS=="usb", SYSFSidVendor=="fffe",

SYSFSidProduct=="0002", GROUP:="usrp", MODE:="0660"' > tmpfile

sudo chown root.root tmpfile

sudo mv tmpfile /etc/udev/rules.d/10-usrp.rules

Page 33: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

32

• At this point, Ubuntu is configured to know what to do if/when it detects the

USRP on the USB, except that "udev" needs to reload the rules to include the newly

created one. The following might work, but if it doesn't then rebooting the computer

will.

sudo /etc/init.d/udev stop

sudo /etc/init.d/udev start

or

sudo killall -HUP udevd

We can check if the USRP is being recognized, by examining /dev/bus/usb after

plugging in a USRP. Using the command:

ls -lR /dev/bus/usb | grep usrp

This should result in one or more lines (one for each USRP) reading something like:

crw-rw---- 1 root usrp 189, 1 2007-11-07 21:46 002

Each device file will be listed with group 'usrp' and mode 'crw-rw----'.

• NOTE: If installing on Feisty, the computer may need to be rebooted in order

for the GNU Radio software to interface correctly with the USRP hardware. This does

not seem to be necessary on Edgy, just Feisty.

Page 34: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

33

VI. TESTING THE GNU RADIO SOFTWARE AND USRP

Once we've verified that the USRP is available to Ubuntu, now it is time to verify that

GNU Radio works with the USRP.Let us start with known functional Linux system

with USB support. We open two different terminal windows. If we like, we can also

run the "usbview" program. To see a real-time display of all log messages, we use one

of these terminals and execute:

tail -f /var/log/messages

Plug the Power cord into the usrp. Then plug in the USB connector between the usrp

and the computer. On the terminal with the log messages should be a message like:

new high speed USB device using address 1

If it says "full speed" rather than "high speed", either we do not have the correct

kernel module loaded for USB 2.0 or our hardware only supports USB 1.x.

Post-installation tasks

After installation, all the components mentioned above are installed in

/usr/local/lib/python2.4/site-packages, which is not included in Python’s working path

by default. To let the Python find these modules and for convenience, we’ll need to

set the PYTHONPATH environment variable as follows:

$ export PYTHONPATH=/usr/local/lib/python2.4/site-packages

We may want to add this to our ~/.bash_profile.

A Testing Data

From the "gnuradio" directory, we need to verify that all of the following work:

Page 35: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

34

• The following script is used to show the Python interface to the USRP; the

program “benchmark_usb” provides a rough estimate of the maximum throughput

(quantized to a power of 2) between the host computer and the USRP. We type the

following:

cd gnuradio/gnuradio-examples/python/usrp

#contains the python examples for the single-usrp board

./benchmark_usb.py

Output

Testing 2MB/sec... usb_throughput = 2M

ntotal = 1000000

nright = 999916

runlength = 999916

delta = 84

OK

Testing 4MB/sec... usb_throughput = 4M

ntotal = 2000000

nright = 1998049

runlength = 1998049

delta = 1951

OK

Testing 8MB/sec... usb_throughput = 8M

ntotal = 4000000

nright = 3997535

runlength = 3997535

delta = 2465

OK

Testing 16MB/sec... usb_throughput = 16M

ntotal = 8000000

Page 36: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

35

nright = 7996865

runlength = 7996865

delta = 3135

OK

Testing 32MB/sec... usb_throughput = 32M

ntotal = 16000000

nright = 15999436

runlength = 15999436

delta = 564

OK

Max USB/USRP throughput = 32MB/sec

While "benchmark_usb" might not return a full 32 MB/s of throughput, the script

should at least run properly; if not, either GNU Radio didn't make correctly or the

USRP isn't accessible.

• The following script is used to show the C++ interface to the USRP; the

programs “test_usrp_standard_tx” and “test_usrp_standard_rx” provides a good

estimate of the maximum throughput (non-quantized) between the host computer and

the USRP.

cd usrp/host/apps

./test_usrp_standard_tx

./test_usrp_standard_rx

Outputs

The output from test_usrp_standard_tx should look like this:

“xfered 1.34e+08 bytes in 4.19 seconds. 3.2e+07 bytes/sec. cpu time = 0.528

0 underruns”

Page 37: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

36

The output from the test_usrp_standard_rx should look like this:

“xfered 1.34e+08 bytes in 4.19 seconds. 3.2e+07 bytes/sec. cpu time = 0.588

noverruns = 0”

To update the rest of the system, after which we might need to reboot, we use:

sudo apt-get -y upgrade

To upgrade the Linux distribution, after which a reboot is required, we use:

sudo apt-get -y dist-upgrade

B Testing Sound

$ cd gnuradio/gnuradio-examples/python/audio

$ python dial_tone.py

Output

This should produce a dial-tone through our speakers. If Python gives us an error

message, there is a problem with our installation of GNU Radio. If we get no error

messages but no sound, we check to see that our speakers are turned on, our volume is

turned up. We use Ctrl-C to stop the dialtone. With this minimal GNU Radio system

we can capture signals from our sound card, read signals from a file, or generate

signals; process signals; and play signals on our sound card or save them to a file.

To run this example, no USRP board is required, but the sound card equipped on our

computer.

C. Evaluation and Demo using the BasicRX Daughterboard

Page 38: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

37

In the previous section, we know that GNU Radio with USRP has the ability to

communicate with each other. At this point we are ready to start exploring the full

potential of our new system! Now that our GNU Radio system is installed, it is time

to start exploring. The best way to learn about GNU Radio is to study and modify the

examples in the various subdirectories of gnuradio/gnuradio-examples/python. We

need to make sure that PYTHONPATH is set as described above.

We type the following and hit Enter:

cd gnuradio-examples/python/usrp

Now we can test our daughterboard by plugging in the BasicRX daughtercard in the

"RXA" connector, and run a spectrum analyzer. We type the following and hit Enter.

python usrp_fft.py -d 32 -f 94.5M

Output

The output of this script is shown in the figure 12. We are now looking at a GUI

display of a 2 MHz segment of the spectrum centered at 94.5 MHz with a random

moving blue line which represents the amplitude of the signal detected at that

frequency. To change the bandwidth, we can enter an even decimation factor (256 or

lower down to 4) into the "Decim" field. For example a decimator factor of 64 gives a

1 MHz segment of the spectrum around the center frequency, a decimator factor of 32

gives a 2 MHz segment of the spectrum and so on.

To change the center frequency, we enter the frequency (in Hz) into the

"Center freq" field. We can also enter the frequency in Mhz followed by a capital

"M". The frequency range shown is -1 MHz to +1 MHz below and above the center

frequency of 94.5 MHz. The plot’s vertical divisions are 200 kHz apart. A possible

active channel should be visible in plot display as wide bump centered around a

vertical division.

Page 39: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

38

Figure 12. Spectrum of the 93.5 – 95.5MHz FM band.

Page 40: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

39

Figure 13. Spectrogram of an FM Receiver with sidebands. GNU Radio and USRP running on Linux Ubuntu 7.04.

The above figure 13 shows the output of the same previous example but with a

different kind of frequency spectrogram. This plot is called as the Waterfall Model

display of the usrp_fft.py where we can see the strong FM band 96.1M with its

sidebands. We can change the frequency of interest by entering the value into the

“Center freq” field shown in the plot.

The spectrogram displays the strong FM bands in the vicinity and the flow of signals

falls from top to bottom. Hence it is called the Waterfall Model display of the

frequency spectrum of interest. The strong orange line in the middle shows the

presence or reception of the 96.1M FM band. The signals scattered around this line

displays the presence of other weak bands called the “side bands” with noise.

Page 41: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

40

VII. EXPLORING GNU RADIO PROGRAMS

A. Learning by Example

The quickest way to understand how to use GNU Radio is to start with some basic

examples. First an example, `dial tone', is chosen for illustration purpose. This is a

very simple `Hello World!' style example. But it should be enough to demonstrate the

strength and beauty of the graph mechanism in GNU Radio. In this example, we

simply generate two sine waves of different frequency and play the tones through the

sound card. Only the signal source and sink are involved, without real signal

processing. This is the same example which was used in the Testing section to test the

sound. The source code of this example is located in [Appendix D].

A.1. The Famous Phone-Tone Example [dial_tone.py]

#!/usr/bin/env python

Makes the python code executable by executing $ chmod +x “filename.py”.

from gnuradio import gr

from gnuradio import audio

from gnuradio.eng_option import eng_option

from optparse import OptionParser

Bring in blocks from the main gnu radio package. Import necessary modules from

GNU radio library.

class my_graph(gr.flow_graph):

Defining a function my_graph()and setting up signal flow graph. Two modules gr and

audio are imported first. Then a function my_graph (), is defined:

my_graph () is a global function within the module dial_tone.py,

def __init__(self):

gr.flow_graph.__init__ (self)

Page 42: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

41

Create the flow graph. Instantiating a flow graph object from flow graph class.

flow_graph is a class defined in the module gr.flow_graph.py.

parser = OptionParser(option_class=eng_option)

parser.add_option("-O", "--audio-output", type="string", default="",

help="pcm output device name. E.g., hw: 0, 0 or /dev/dsp")

parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,

help="set sample rate to RATE (48000)")

(options, args) = parser.parse_args ()

if len(args) != 0:

parser.print_help()

raise SystemExit, 1

The option parsers are used to provide the user, with different options to select types

of audio output devices, sampling rates etc. It accepts the user’s input arguments

when the program is executed in shell.

sample_rate = int(options.sample_rate)

ampl = 0.1

Two constants are defined. Sampling frequency and amplitude on soundcard.

src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)

src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)

Create the signal sources.

Parameters are: sample rate, type, output freq, amplitude. Setting up sine waves at 350

and 440 Hz.

dst = audio.sink (sample_rate, options.audio_output)

Defining destination to be soundcard. That is, create a signal sink.

self.connect (src0, (dst, 0))

self.connect (src1, (dst, 1))

Connecting source and destinations, left and right channel.

Page 43: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

42

if __name__ == '__main__':

try:

my_graph().run()

except KeyboardInterrupt:

pass

Create code to execute or run the flow graph.

Explanation of the above illustration in brief

We start by creating a flow graph to hold the blocks and connections between them.

The two sine waves are generated by the gr.sig_source_f calls. The f suffix indicates

that the source produces floats. One sine wave is at 350 Hz, and the other is at 440

Hz. Together, they sound like the US dial tone.

‘audio.sink’ is a sink that writes its input to the sound card. It takes one or

more streams of floats in the range -1 to +1 as its input. We connect the three blocks

together using the connect method of the flow graph.

‘connect’ takes two parameters, the source endpoint and the destination

endpoint, and creates a connection from the source to the destination. An endpoint has

two components: a signal processing block and a port number. The port number

specifies which input or output port of the specified block is to be connected. In the

most general form, an endpoint is represented as a python tuple like this: (block,

port_number). When port_number is zero, the block may be used alone.

These two expressions are equivalent:

self.connect ((src1, 0), (dst, 1))

self.connect (src1, (dst, 1))

Once the graph is built, we start it. Calling start forks one or more threads to run the

computation described by the graph and returns control immediately to the caller. In

this case, we simply wait for any keystroke.

We run the program using: “python dial_tone.py” or simply “./dial_tone.py”and this

should produce the dial tone through our speakers.

Page 44: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

43

VIII. IMPLEMENTATION OF FM RECEIVER

A. Frequency Modulation

In order to better understand the FM receiver implemented using GNU Software

Radio platform, Frequency Modulation and Demodulation techniques will be briefly

introduced. Modulation is changing the characteristics of a carrier wave by the

message signal that is to be communicated from one station to the other. In frequency

modulation the amplitude of the message signal determines the variations in the

frequency of the carrier wave, which is a sinusoidal signal generated by a local

oscillator at the transmitting station. With FM, the instantaneous frequency of the

transmitted waveform is varied as a function of the input signal.Figure 13 illustrates a

Frequency Modulated signal at the output of a transmitter. Figure 13(a) shows m (t),

the input signal (the message, music and so forth), and s (t), Figure 13(b), the

resulting modulated output.

A message signal m (t), frequency modulating a carrier wave Ac cos (2πf

ct), results in

an FM signal in the form of ∫+t

fcc dmktfA0

))(22cos( ττππ , with instantaneous

frequency if = )(tmkf fc + [9], where m (t) is the input signal, k is a constant that

controls the frequency sensitivity and f c is the frequency of the carrier (for example,

100.1MHz). Frequency has units of radians per second. As a result, frequency can be

thought of as the rate at which something is rotating. If we integrate frequency, we get

phase, or angle. Conversely, differentiating phase with respect to time gives frequency

[11].

At the receiver end, the message signal is recovered by producing a signal

whose amplitude is directly proportional to the frequency of the FM wave. This

process is referred to as “Frequency Demodulation,” and the corresponding device is

called a “Demodulator.”[9]

These are the key insights we use to build the receiver.

Page 45: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

44

(a)

(b)

Figure 14. Frequency Modulation (Image source: Wikipedia)

Figure 14, shows an example of frequency modulation. The top diagram shows the

modulating signal (red signal) m (t) superimposed on the carrier wave (green signal).

The bottom diagram shows the resulting frequency-modulated signal.

B. FM Reception Methodology

In the GNU software radio, the antenna receives the signal; the Radio Frequency (RF)

front-end on the receiving daughterboard selects the channel chosen by the user via

software, and lowers the frequency range of the received signal from high RF range to

Intermediate Frequency (IF) band that can be handled by the Analog-to-Digital

Converter (ADC) [11]. An ADC, commonly characterized by its sampling rate and

dynamic range, converts the continuous analog signals received from the

daughterboard to digital samples that can be used by the software.

Page 46: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

45

Figure 15. Shows our setup of an FM Receiver using the BasicTX daughterboard, Antenna and USRP

B.1 Function of the Digital Down Converter

The digital signal is then fed to the Digital Down Converter (DDC) in the FPGA of

the USRP, where the samples are multiplied by digital sinusoidal signals with

frequencies equal to those of the input samples [5]. The product consists of a high

frequency component at twice the carrier frequency and a low frequency component

at zero. The low-pass filter of the DDC passes only the low frequency component,

which is the base band signal, and also allows data rate reduction of the signal. The

data rate of the base band signal is then reduced to match the USB port specifications.

Reducing the data rate of a signal or decimation is a common practice in signal

processing applications. According to Nyquist theorem, sampling rate has to be at

least twice the maximum frequency of the signal to be sampled, in order to avoid

aliasing. Aliasing occurs when the sampled signal is not the representation of a unique

analog signal. Assuming that signal x(n) has a frequency spectrum in the interval 0≤

|w| ≤ π, if the sampling rate is simply reduced by D, aliasing occurs, since the

Page 47: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

46

sampling rate is no longer greater than 2fmax

[10]. Therefore, prior to reducing the

sampling rate, a lowpass filter, called decimation filter, reduces the signal bandwidth

to w (max) = π / D; The signal can then be safely down-sampled by a factor of D [10].

The block diagram of figure 16, illustrates the flow of the received signal from the

antenna to the USB port.

Next, software by means of a general purpose processor of a regular personal

computer performs the main signal processing on the data received from the USRP

and recovers the message signal. The software block called “Quadrature

Demodulator,” shown in Figure 16 (b), performs the main frequency demodulation.

The Quadrature Demodulator multiplies each input sample, which is a complex

number, by the complex conjugate of the adjacent sample and takes the arc tangent of

the product, in order to determine the angle between two subsequent samples:

After the signal is demodulated, a low pass filter structure selects the proper

portion of the FM spectrum and reduces the data rate to one that can be handled by

the sound card. A deemphazing stage is also necessary prior to the soundcard, which

is performed in the software. For most practical applications the power of the signal

diminishes significantly at high frequencies. Therefore, in the transmitter network,

high frequency components are amplified to improve the signal noise ratio (SNR).

This action is called “pre-emphasizing.” [5] At the receiver end, the opposite

operation, called de-emphasizing” is performed to deemphasize the high-frequency

components, allowing the recovery of the original signal power distribution.

Figure 16, shows our strategy for listening to an FM station. If we remove the carrier,

we're left with a baseband signal that has an instantaneous frequency proportional to

the original message m (t). Thus, our challenge is to find a way to remove the carrier

and compute the instantaneous frequency.

Page 48: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

47

Figure 16. Block Diagram of FM Receiver and Quadrature Demodulator

We get rid of the carrier by using our software digital downconverter (DDC) block,

fir_filter_ccf. This block is composed conceptually of a numerically controlled

oscillator that generates sine and cosine waveforms at the frequency that we want to

translate to zero, a multiplier and a decimating finite impulse response filter. The ccf

suffix indicates that this block takes a stream of complex on its input, produces a

stream of complexes on its output and uses floating-point taps to specify the filter

[11].

The digital downconverter does its job by taking advantage of a trigonometric identity

that says when you multiply two sinusoids of frequency f1 and f2 together, the result is

composed of two new sinusoids, one at f1+f2 and the other at f1-f2. In our case, we

multiply the incoming signal by the frequency of the carrier. The output consists of

two components, one at 2x the carrier and one at zero. We get rid of the 2x

component with a low-pass filter, leaving us the baseband signal [11].

ADC

D

Sine / Cosine generator

Basic RX D

Quad De-

Modulator

Page 49: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

48

The next job is to compute the instantaneous frequency of the baseband signal. We

use the quadrature_demod_cf block for this. We approximate differentiating the phase

by determining the angle between adjacent samples. We recall that the downconverter

block produces complex numbers on its output. Using a bit more trigonometry, we

can determine the angle between two subsequent samples by multiplying one by the

complex conjugate of the other and then taking the arc tangent of the product [11].

Now our objective is to receive a Frequency Modulated (FM) signal by using the

modules in GNU Radio. Let us analyse the code line by line. This example

implements an FM receiver with graphical user interface. The source code of this

implementation is located in [Appendix E].

The explanation of the whole program is divided into 2 parts. The first half which will

follow hereafter focuses on the basics of Python. The second half which contains the

Graphical User Interface part of the program has been included in the [Appendix G].

C. FM Receiver Program

C.1 The first line (usrp_wfm_rcv.py [Appendix E])

If we have read the code of other examples, we can find the first line of these

programs is almost always

#! /usr/bin/env python

The Python scripts can be made directly executable if we put this line at the beginning

of the script and giving the file an executable mode. The '#!' must be the first two

characters of the file. The script is given the executable mode by using the 'chmod'

command [13]:

$ chmod +x usrp_wfm_rcv.py

Now the script usrp_wfm_rcv.py becomes executable. We can run this program in the

shell using

$. / usrp_wfm_rcv.py arguments

Page 50: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

49

The Python interpreter will be invoked and the code in this script will be executed line

by line orderly. Python is an interpreted language, like Matlab script. No compilation

and linking is necessary. There are several ways to invoke the Python interpreter: we

can also use

$ python ./ usrp_wfm_rcv.py arguments

without the need to give the script the executable mode.

We can also use the interactive mode, by just typing the command in the shell:

$ python

then the Python interpreter environment will be invoked and we could input our code

line by line. However, this is obviously inconvenient. We seldom use the interpreter

interactively, unless we write some throw-away programs, test functions or use it as a

desk calculator. Most of the time, packing codes in a .py file and making the script

self-executable is more convenient to us [13].

C.2 Importing necessary modules

from gnuradio import gr, gru, eng_notation, optfir

from gnuradio import audio

from gnuradio import usrp

from gnuradio import blks2

from gnuradio.eng_option import eng_option

from gnuradio.wxgui import slider, powermate

from gnuradio.wxgui import stdgui2, fftsink2, form

from optparse import OptionParser

from usrpm import usrp_dbid

import sys

import math

import wx

Understanding these statements requires the knowledge of 'module' and 'package'

concepts in Python. Here is a brief introduction. If we quit the Python interpreter and

enter it again, all the functions and variables we have defined are lost. Therefore, we

Page 51: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

50

wish to write a somewhat longer program and save it as a script, containing function

and variable definitions, and maybe some executive statements. This script can be

used as the input of the Python interpreter. We may also want to use a fancy function

we've written in several programs without copying its definitions to each program

[13].

To support this, Python provides a module/package organization system. A module

is a file containing Python definitions and statements, with the suffix '.py'. Within a

module, the module's name (as a string) is available as the value of the global variable

'_ _name_ _'. Definitions in a module can be imported into other modules or into the

top-level module. A package is a collection of modules that have similar functions,

which are often put in the same directory. The '_ _init_ _.py' files are required to

make Python treat the directories as packages. A package could contain both modules

and sub-packages (can contain sub-sub-packages). We use 'dotted module names' to

structure Python's module namespace. For example, the module name A.B designates

a submodule named 'B' in a package named 'A'.

A module can contain executable statements as well as function definitions.

The statements are executed only the first time the module is imported somewhere

and so that the module is initialized. Each module has its own private symbol table,

which is used as the global symbol table by all functions defined within that module.

The author of a module can use the global variables in the module without worrying

about accidental clashes with the module user's global variables. As a module user,

we can access a module's function and global variables using `modname.itemname'.

Here the `itemname' can either be a function or a variable [13].

Modules can import other modules using `import' command. It is customary to place

all `import' statements at the beginning of a module. Note that the import operation

is quite flexible. We can import a package, a module, or just a definition within a

module. When we try to import a module from a package, we can either use `import

packageA.moduleB', or `from package A import module B'. When using `from

package import item', the 'item' can be either a module/sub-package of the package,

or some other names defined in the package, like functions, classes or variables. It's

worth taking a while to introduce the modules used in this example amply, because

Page 52: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

51

these modules or packages will be frequently encountered in GNU Radio. The top-

level package of GNU Radio is 'gnuradio', which includes all GNU Radio related

modules. It is located at

/usr/local/lib/python2.4/site-packages

By default, this directory is not included in the Python's search path, we need to

export the path to the environment variable 'PATHONPATH'. So we usually add the

following line to the users' .bash_profile file:

export PATHONPATH=/usr/local/lib/python2.4/site-packages

to make sure the Python interpreter could find the gnuradio package.

gr is an important sub-package of gnuradio, which is the core of the GNU Radio

software. The type of ‘flow graph' classes is defined in gr and it plays a key role in

scheduling the signal flow [13].

eng notation is a module designed for engineers' notation convenience, in which many

words and characters are endowed with new constant values according to the

engineering convention. The module audio provides the interfaces to access the sound

card, while usrp provides the interfaces to control the USRP board. audio and usrp are

often used as the signal source and sink. blks is a sub-package, which is almost an

empty folder if we check its directory. It actually transfers all its tasks to another sub-

package blksimpl in gnuradio, as described in the __init__.py file. blksimpl provides

the implementation of several useful applications, such as FM receiver, GMSK, etc.

For this example, the real signal processing part of the FM receiver is performed in

this package [13].

Let us look at the next line, which is more interesting:

from gnuradio.eng_option import eng_option

This is exactly what we mentioned just now, we can either import a complete

module/sub-package, or, just a function, class or variable definition from this module.

In this case, eng option is a class defined in the module gnuradio.eng option. We don't

need the whole module to be imported, but just a single class definition. gnuradio.eng

Page 53: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

52

option module does nothing but adding support for engineering notation to

optparse.OptionParser [13].

This line appears to have a similar format:

from gnuradio.wxgui import stdgui, fftsink

But the meaning is a little bit different; gnuradio.wxgui is a sub-package, not a

module, while stdgui and fftsink are two modules in this sub-package. It's not

necessary to import the whole sub-package, so we just import what we want

explicitly. gnuradio.wxgui provides visualization tools for GNU Radio, which is

constructed based on wxPython. The importing operations in Python provide us

great flexibility and convenience [13].

Finally, optparse, math, sys, wx are all Python or wxPython's built-in modules or sub-

packages, which are not part of the GNU Radio.

At this point, let us emphasize again, these modules imported above may

contain executable statements as well as the function or class definitions. The

statements will be executed immediately after the modules are imported. After

importing the modules and packages, a lot of variables, classes and modules defined

in them have been initialized.

C.3 Class definition

In this example, a large part of the code is the definition of a class 'wfm_rx_graph'.

The statement

class wfm_rx_graph (stdgui.gui_flow_graph):

defines a new class ‘wfm_rx_graph’, which is inherited (derived) from the base class,

or the so called 'father class' -- ‘gui_flow_graph’. The father class is defined in the

module stdgui we have just imported from gnuradio. By the rules of the namespace,

we use stdgui.gui_flow_graph to refer to it [13].

C.4 The family of 'FLOW GRAPH' classes

Page 54: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

53

Here an important category of classes, which play a key role in GNU Radio should

receive particular attention: the 'flow graph' classes. There are a series of 'GRAPH'

related classes defined in GNU Radio. We can find that stdgui.gui_flow_graph is

derived from gr.flow_graph, which is defined in the sub-package gr. Further,

gr.flow_graph is derived from the 'root' class gr.basic_flow_class. In GNU Radio,

there are also many other classes derived from gr.basic_flow_graph. This big

'GRAPH family' makes GNU Radio programming neat and simple, also makes the

scheduling of the signal processing clear and straightforward [13].

In our example, wfm_rx_graph is such a graph class belonging to this family, with

GUI support. Later we will see it glues the necessary blocks in FM receiver together

using the method 'connect'.

C.5 The initialization function: _ _init_ _

Then we implement the method (or function) '__init__' of the class wfm_rx_graph.

The syntax for defining a new method is

def funcname(arg1 arg2 ...)

__init__ is an important method for any class. After defining the class, we may use

the class to instantiate an instance. This special method __init__ is used to create an

object in a known initial state. Class instantiation automatically invokes __init__ for

the newly created class instance. Actually in this example, __init__ is the only method

defined in the class wfm_rx_graph.

We notice that in this piece of code, there are no explicit signs for where a definition

of a class or a function starts and ends. Usually in other programming languages such

as C++ , we use 'begin' and 'end' pair, or a pair of '' and '' explicitly to denote the

two ends of a group of statements. However, in Python, this is no longer the case.

There are NO such signs. In Python, statement grouping is done by indentation

instead of beginning and ending brackets [13].

Now let's see what's going on in the function _ _init_ _.

Page 55: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

54

def __init__(self, frame, panel, vbox, argv):

declares the initialization method __init__ with four arguments. Conventionally, the

first arguments of all methods are often called self. This is nothing more than a

convention: the name self has absolutely no special meaning to Python. However,

methods may call other methods by using method attributes of the self argument, such

as 'self.connect( )' we will meet later.

The first thing __init__ does, is to call the initialization method of

stdgui.gui_flow_graph, its 'father class', with exactly the same four arguments [13].

stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)

We may like to take a look at stdgui.gui_flow_graph's initialization method. Since

wfm_rx_graph is derived from it, we can safely think of wfm_rx_graph as a 'special'

gui_flow_graph. So it's natural that this 'son class' should do something to make

himself look like his father first, then do something fancy to make himself a different

guy.

C.6 Defining constants

From the next line, we kind of start to see real signals coming in.

(options, args) = parser.parse_args()

This sets the frequency, sample rate etc from the return value of the function

parser.parse_args(). The function parseargs is defined after the definition of the class

wfm_rx_graph. It accepts the user’s input arguments when the program is executed in

shell [13].

C.7 The signal source

The following several lines provide a very high level abstraction for the signal

processing procedure, which basically includes three components: the signal source,

Page 56: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

55

the signal sink, and a series of signal processing blocks. This example gives those

signal processing blocks a very nice name: guts.

The signal source for the FM receiver is the USRP board in this example

# usrp is data source

self.u = usrp.source_c( )

OK, let's look at the code. usrp is the module we've imported at the beginning. The

usrp module is located at [13]:

/usr/local/lib/python2.4/site-packages/gnuradio/usrp.py

It tells us the module usrp is a wrapper for the USRP sinks (transmitting) and sources

(receiving). When a sink or a source is instantiated, the usrp module first probes the

USB port to locate the requested board number, then use the appropriate version

specific sink or source. ‘source_c’ is a function defined in usrp module. It returns a

class object that represents the data source. The suffix ‘_c’ means the data type of the

signal is `complex', because the signal coming into the computer is complex (actually

in real/imag pair). In contrast, we also have source_s method in the usrp module,

which is designed for 16-bit short integer data type [13].

Where are these methods defined? Actually all these methods are implemented using

C++. The SWIG provides the interfaces between C++ and Python, so that we can call

these functions directly in Python, without worrying about the implementation details

in C++. Boost, a smart pointer system, is also used here to facilitate the interaction

between C++ and Python.

The top level interfaces to the USRP are usrp_standard_rx and

usrp_standard_tx. Also we should take a look at their base classes, usrp_basic_rx,

usrp_basic_tx and usrp_basic. There are many other methods, to control and interact

with the USRP board [13].

Besides, we may have noticed that Python doesn't require variable or argument

declarations. This is totally different with the `declare before use' concept in C.

Page 57: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

56

adc_rate = self.u.adc_rate() # 64 MS/s

This line defines the sampling frequency of the AD converter, which should be set to

64MHz for the USRP users. According to Nyquist theorem, the maximum frequency

component of the interested signal should be less than 32MHz in order not to loose

spectrum information after sampling.

usrp_decim = 200

usrp_rate = adc_rate / usrp_decim # 320 kS/s

Decimation is a concept in DSP world. After sampling the analog signal, we get a

digital signal with very high data rate, which is a heavy burden for the CPU and

storage. Usually, we can down-sample the digital sequence (decimation) without

losing the spectrum information. In this example, the decimation rate is chosen to be

200 so that the resulting data rate is 320K samples per second, which is quite

reasonable and acceptable for our CPU speed. quad_rate represents for quadrature

data rate [13].

audio_decimation = 10

audio_rate = demod_rate / audio_decimation # 32 kHz

After processing the digital FM signal, we wish to play the signal using the sound

card of the computer. However, the data rate that a sound card can adopt is rather

limited. 320 kHz is usually too high and more than necessary. So we need to further

decimate the data rate. 32 kHz is a common choice for most sound cards.

OK, now let's design the FIR decimation filter. The GNU Radio block gr.fir_filter_ccf

gives us an FIR filter with float input, float output, and float taps. Its constructor takes

two arguments: the first one is the decimation factor; the second one is the filter

coefficients (taps) vector [13].

chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)

Page 58: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

57

If we need an FIR filter without changing the data rate, then we just simply set the

decimation rate to be 1. If we need an interpolation filter rather than a decimation

filter, then the GNU Radio block gr.interp_fir_filter_xxx is what we should choose.

The filter coefficients chan_filt_coeffs are obtained using the FIR filter design block

optfir.low_pass( ) is a static public function defined in the class optfir. Similarly, it

also has high_pass( ), band_pass( ), band_reject() functions. We use these functions to

design the FIR filter taps, provided the filter parameters and specifications. The

syntax for design a low-pass filter is [13]:

chan_filt_coeffs = optfir.low_pass (1, # gain

usrp_rate, # sampling rate

80e3, # passband cutoff

115e3, # stopband cutoff

0.1, # passband ripple

60) # stopband attenuation

The meaning of each argument is quite obvious In our example, we select the audio

decimation factor (audio_decimation) to be 10, so that the resulting data rate for the

sound card is 32kHz.

C.8 The big signal processing 'gut'

There is a long story behind

self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)

`guts' is the central processing block of this FM receiver. blks is a package in

gnuradio. It almost does nothing but refers to another package blksimpl. All signal

processing blocks, such as deemphasizing, noncoherent demodulation are glued

together in this `gut'. wfm_rcv is a class defined in /gnuradio/blksimpl/wfm_rcv.py

[13]. Also refer [Appendix F].

/usr/local/lib/python2.4/site-packages/gnuradio/blksimpl/wfm rcv.py

Page 59: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

58

wfm_rcv is a class defined in the module blksimpl. Its base class is hier_block,

defined in the module gr.hier_block. gr.hier_block can be thought as a sub-graph,

containing several signal processing blocks, which is used as a single sophisticated

block in another bigger graph. In this statement, we create an object `self.guts' as the

instantiation of the class wfm_rcv. All real signal processing is done within this big

block [13].

C.9 The signal sink

Finally, we will play the demodulated FM signal using the sound card. So the audio

device is the signal sink in this example:

# sound card as final sink

audio_sink = audio.sink (int (audio_rate),

options.audio_output,

False) # ok_to_block

sink is a global function defined in the module audio. It returns an object as the signal

sink block. audio_rate is a parameter describing the data rate of the signal entering the

sound card, which is 32kHz in our example. OK! Our FM receiver is complete! The

signal is at the door of the sound card and is ready to be played [13].

C.10 Gluing them together

The next two lines finally complete our signal flow graph

# now wire it all together

self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)

Just now we have talked about the family of the flow graph classes, to which the new

class wfm_rx_graph belong. All those flow graph classes are derived from the `root'

class gr.basic_flow_graph. The connect method is defined in gr.basic_flow_graph.

This method is designed for the flow graph to bind all the blocks together [13].

The signal flow graph is done at this point!

Page 60: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

59

To run the ‘usrp_wfm_rcv.py’ program, we use the following commands in the shell:

$ cd gnuradio/gnuradio-examples/python/usrp

$ ./usrp_wfm_rcv.py -f 96M -g 75 - o 48000

We can choose the options from the shell by using the following: “-f” to select the

frequency of interest, “-g” to select the gain and “–o” to select the sampling rate of the

audio output device.

Figure 17 shows the output of the above script.

Figure 17. Shows the received FM station at 96 MHz and its post demodulated signal

OK, here ends the explanation of our FM Receiver program. In the following few

sections, we will see the various applications of our GNU Radio and USRP, and we

shall end this paper with some future work and conclusion.

Page 61: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

60

IX. PROMISES OF GNU RADIO AND USRP

A. Significance of USRP

The Universal Software Radio Peripheral (USRP) enables engineers to rapidly design

and implement powerful, flexible software radio systems. A large community of

developers and users have contributed to a substantial code base and provided many

practical applications for the hardware and software. The true value of the USRP is in

what it enables engineers and designers to create on a low budget and with a

minimum of effort. The powerful combination of flexible hardware, open-source

software and a community of experienced users makes it the ideal platform for our

software radio development [12].

A.1. Benefits

• Low cost, flexible platform

• Large community of developers

• Close coupling with the GNU Radio software framework forms a flexible and

powerful platform

• Reduced parts inventory

• DSP can compensate for cheaper RF

• Multiple Input Multiple Output(MIMO) systems

A.2. Applications

The USRP product family is in use all over the world in a wide variety of

applications. While the USRP is often used for rapid prototyping and research

applications, it has been deployed in several real-world commercial and defense

Systems.

Page 62: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

61

Figure 18. The USRP is in use in all 38 of the countries colored red in this map.

A.2.1 Commercial Applications

There are many applications for the USRP in commercial systems. System

development and prototyping is ideally done on a software radio. And when an

application does not have the volume to justify a custom hardware design, the

flexibility of the USRP enables a cost effective, deployable system.

As an example, Path Intelligence Ltd., uses the USRP product family to track

pedestrian foot traffic in shopping malls. The phased-array capabilities of the USRP

allow Path Intelligence to determine the locations of shoppers by receiving the

control-channel transmissions of cell phones [12].

A.2.2 Defense and Homeland Security

The USRP product family is being used by all branches of the U.S. military and

intelligence services, many large defense contractors and other NATO nations. The

USRP motherboard and daughterboards enable rapid prototyping and deployment of

sophisticated wireless systems on a low budget. Some applications include [12]:

• Battlefield networks, survivable networks

Page 63: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

62

• JTRS research

• Public safety communications bridges

• Emergency low-power beacons

• Mine safety and underground communications

• Passive radar

Figure 19. JTRS Seal

A.2.3 Wireless Research

Numerous researchers in wireless networks are using the USRP product family to

study such diverse topics as [12]:

• MIMO systems

• Ad-hoc and mesh networking

• MAC-layer protocols

• Spectrum occupancy, spectrum sensing

• Cognitive radio

The open and easy to use USRP product family enables rapid prototyping of

innovative new communication systems. The low cost allows deployment of

significant numbers of nodes in a test-bed for studying large-scale network effects.

B. Significance of GNU Radio

GNU Radio is a free/open-source software toolkit for building software radios. GNU

Radio has a large worldwide community of developers and users that have contributed

to a substantial code base and provided many practical applications for the hardware

Page 64: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

63

and software. It provides a complete development environment to create our own

radios, handling all of the hardware interfacing, multithreading, and portability issues

for us. GNU Radio has libraries for all common software radio needs, including

various modulations (GMSK, PSK, OFDM, etc.), error-correcting codes (Reed-

Solomon, Viterbi, Turbo Codes), signal processing constructs (optimized filters,

FFTs, equalizers, timing recovery), and scheduling [12].

GNU Radio provides functions to support implementing spectrum analyser, an

oscilloscope, concurrent multi-channel receiver and an ever-growing collection of

modulators and demodulators.

B.1 GNU Radio Applications

Projects under investigation or in progress include [3]:

• Time Division Multiple Access (TDMA) waveforms.

• A passive radar system that takes advantage of broadcast TV for its signal

source. For those of us with old TVs hooked to antennas, think about the

flutter we see when airplanes fly over.

• Radio astronomy.

• TETRA transceiver.

• Digital Radio Mundial (DRM).

• Software GPS.

• Distributed sensor networks.

• Distributed measurement of spectrum utilization.

• Amateur radio transceivers.

• Ad hoc mesh networks.

• RFID detector/reader.

• Multiple input multiple outputs (MIMO) processing.

Page 65: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

64

X. RELATED AND FUTURE WORK

In this academic semester, we built the environment of GNU radio, got familiar with

it, and learnt how to use the existing libraries to receive a Frequency Modulated signal

using our GNU Radio Software and the USRP Hardware. Some of the future

objectives of this project include: a) Implementation of a complete VHF and UHF

receiver system based on a TV tuner module using the TVRX daughterboard and

GNU Radio; b) Implementation of recovering the original message signal, for

example voice or music, from our FM demodulated signal is another future objective.

Implementing these functions in our demo will give us more convenience to deploy

future research project and stimulate us to develop more functions based on GNU

Radio environment.

XI. SUMMARY AND CONCLUSIONS

Researchers are currently using software radio–based systems to help them work on

problems in realms that include radio astronomy, telecommunications, and medical

imaging. Already a number of commercial products rely on software radio.

While software radio is still very much a work in progress, and general-

purpose processors still lack the computing power to fulfil all the dreams of

enthusiasts, we can get a taste of the future with the USRP. The hardware works in

concert with the software developed by the GNU Radio project, an international

collaboration of programmers who donate their time and skills. Software Radio is an

exciting field and definitely a nice system.

In this paper, we first introduce the concept of software-defined radio and the capacity

of GNU Radio and USRP. Afterward, we describe the related hardware support and

development environment respectively. We have introduced the FM receiver

techniques based on our demo, and how they are implemented using GNU Radio. At

last we present some possible future work. Through this project, we build up a

systematical knowledge and experience for developing GNU Radio applications and it

is very helpful for us to deploy a research-oriented project next.

Page 66: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

65

XII. REFERENCES

[1] "GNU." Wikipedia, The Free Encyclopedia. This page was last modified

19:09, 2 November 2007. <http://en.wikipedia.org/wiki/GNU>.

[2] “The GNU Operating System.” GNU’s Not Unix! - Free Software, Free

Society. <http://www.gnu.org/>.

[3] Blossom, Eric. “Exploring GNU Radio.” 29 November 2004, The GNU

software radio documentation.

<http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html#intro>.

[4] Ettus, Matt. “Ettus Research, LLC” <www.ettus.com>.

[5] Shen, Dawei “SDR Documentation” Software-Defined Radio JNL Research

Group. University of Notre Dame, May 19 2005.

<http://www.nd.edu/~jnl/sdr/docs/>.

[6] “USRP FPGA.” The GNU software radio documentation wiki.

<http://www.gnuradio.org/trac/wiki/UsrpFPGA>.

[7] “Windows Installation.” The GNU software radio documentation wiki.

<http://www.gnuradio.org/trac/wiki/WindowsInstall>.

[8] “Ubuntu Installation Options.” The GNU software radio documentation wiki.

<http://www.gnuradio.org/trac/wiki/UbuntuInstall>.

[9] Haykin, Simon. An Introduction to Analog and Digital Communication.

McMaster University, John Wiley & Sons, Inc, 1989.

[10] Proakis, John. Manolakis, Dimitris. “Digital Signal Processing Principles,

Algorithims and Applications”, 3 rd Ed.

Page 67: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

66

[11] Blossom, Eric. “Listening to FM Radio in Software, Step by Step.” Linux

Journal. 1 Sep. 2004. <www.linuxjournal.com/article/7505>.

[12] “USRP Brochure.” Ettus Research LLC.

<http://www.ettus.com/Download.html>.

[13] Shen, Dawei “Tutorial 5: Getting Prepared for Python in GNU Radio by

Reading the FM Receiver Code Line by Line-Part I.” Software-Defined Radio

JNL Research Group. University of Notre Dame, 27 May 2005.

<http://www.nd.edu/~jnl/sdr/docs/tutorials/5.html>.

Page 68: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Software Defined Radio University of Western Australia

Sameer – 20184885 Project Report

67

XIII. SOURCES OF ILLUSTRATIONS

[Figure 1] “A GLONASS Receiver.” Online Image. Wikipedia, The Free

Encyclopedia. This page was last modified 02:08, 5 October 2007.

<http://en.wikipedia.org/wiki/Image:Glonass-reciever.jpg>

[Figure 2] “A GPS Receiver.” Online Image. Wikipedia, The Free

Encyclopedia. This page was last modified 02:08, 1 November 2007.

<http://en.wikipedia.org/wiki/Image:Magellan_GPS_Blazer12.jpg>

[Figure 6] “USRP and components.” Online Image. Ettus Research LLC.

<http://www.ettus.com/images/USRP.jpg>

[Figure 8] “USRP Daughterboard: BasicRX.” Online Image. GNU Radio.

<http://www.gnuradio.org/trac/wiki/UsrpDBoardBasicRX>

[Figure 9] “USRP Daughterboard: BasicTX.” Online Image. GNU Radio.

<http://www.gnuradio.org/trac/wiki/UsrpDBoardBasicTX>

[Figure 14] “Frequency Modulation” Online Image. Wikipedia, The Free

Encyclopedia. This page was last modified 02:08, 30 October 2007.

< http://en.wikipedia.org/wiki/Image:Frequency-modulation.png>

[Figure 18] “USRP around the world.” Online Image. GNU Radio.

<http://www.gnuradio.org/trac/wiki/USRP>

[Figure 19] “Joint Tactical Radio System” Online Image. Wikipedia, The Free

Encyclopedia. This page was last modified 02:08, 2 November 2007.

Page 69: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDICES

Page 70: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX A

The FPGA and USB details:

Probably understanding what goes on the FPGA is the most important part for GNU

Radio users. As shown in Figure 5, all the ADCs and DACs are connected to the

FPGA. This piece of FPGA plays a key role in the GNU Radio system. Basically

what it does is to perform high bandwidth math, and to reduce the data rates to

something you can squirt over USB2.0. The FPGA connects to a USB2 interface chip,

the Cypress FX2. Everything (FPGA circuitry and USB Microcontroller) is

programmable over the USB2 bus.

Our standard FPGA configuration includes digital down converters (DDC)

implemented with cascaded integrator-comb (CIC) filters. CIC filters are very high-

performance filters using only adds and delays. The FPGA implements 4 digital down

converters (DDC). This allows 1, 2 or 4 separate RX channels. At the RX path, we

have 4 ADCs, and 4 DDCs. Each DDC has two inputs I and Q. Each of the 4 ADCs

can be routed to either of I or the Q input of any of the 4 DDCs. This allows for

having multiple channels selected out of the same ADC sample stream.

The digital up converters (DUCs) on the transmit side are actually contained in the

AD9862 CODEC chips, not in the FPGA. The only transmit signal processing blocks

in the FPGA are the interpolators. The interpolator outputs can be routed to any of the

4 CODEC inputs.

The multiple RX channels (1, 2, or 4) must all be the same data rate (i.e. same

decimation ratio). The same applies to the 1, 2, or TX channels, which each must be at

the same data rate (which may be different from the RX rate).

Figure 10, The FPGA schematic, shows the block diagram of the USRP's receive path

and Figure 11 shows the diagram of the digital down converter. The MUX is like a

router or a circuit switcher. It determines which ADC (or constant zero) is connected

Page 71: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

to each DDC input. There are 4 DDCs. Each has two inputs. We can control the MUX

using usrp.set_mux() method in Python.

Mux value:

Each 4-bit I field is either 0,1,2,3

Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)

All Q's must be 0xf or none of them may be 0xf

We tell each input (I0, Q0, I1 ... I3, Q3) which ADC is connected to it by using 4 bits

(0, 1, 2, 3 or 0xf). So a 32-bit integer would be enough for all 8 inputs to know which

ADC is connected. Of course an integer in hexadecimal system will be more

convenient if we want to use the set_mux() method. For most real sampling

applications, the Q input of each DDC is constant zero. So quite often we don't need

to modify the standard configuration of the FPGA. Actually it is anticipated that the

majority of USRP users will never need to use anything other than the standard FPGA

configuration.

Now let's see the digital down converter (DDC). What does it do? First, it down

converts the signal from the IF band to the base band. Second, it decimates the signal

so that the data rate can be adapted by the USB 2.0 and is reasonable for the

computers' computing capability. The second part of Figure 3 shows the block

diagram of the DDC. The complex input signal (IF) is multiplied by the constant

frequency (usually also IF) exponential signal. The resulting signal is also complex

and centered at 0. Then we decimate the signal with a factor N.

The decimator can be treated as a low pass filter followed by a downsampler. Suppose

the decimation factor is D. If we look at the digital spectrum, the low pass ¯lter selects

out the band [-¼=D, ¼=D], and then the downsampler spread the spectrum in [-¼=D,

Page 72: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

¼=D] to [-¼, ¼]. So in fact, we have narrowed the bandwidth of the digital signal of

interest by a factor of D. Regarding the bandwidth, we can sustain 32MB/sec across

the USB. All samples sent over the USB interface are in 16-bit signed integers in IQ

format, i.e. 16-bit I and 16-bit Q data (complex), resulting in 8M complex samples/sec

across the USB. This provides a maximum e®ective total spectral bandwidth of about

8MHz by Nyquist criteria. Of course we can select much narrower ranges by

changing the decimation rate. For example, suppose we want to design an FM

receiver. The bandwidth of a FM station is generally 200kHz. So we can select the

decimation factor to be 250. Then the data rate across the USB is 64MHz / 250 =

256kHz, which is well suited for the 200kHz bandwidth without losing any spectral

information. We can set the IF frequency of the DDC using usrp.set_rx_freq() method

and set the decimation factor using usrp.set_decim_rate() method in Python. The

decimation rate must be in [1, 256].

Note that when there are multiple channels (up to 4), the channels are interleaved. For

example, with 4 channels, the sequence sent over the USB would be I0 Q0 I1 Q1 I2

Q2 I3 Q3 I0 Q0 I1 Q1, etc. The USRP can operate in full duplex mode. When in this

mode, the transmit and receive sides are completely independent of one another. The

only consideration is that the combined data rate over the bus must be 32 Megabytes

per second or less.

OK! Finally the I/Q complex signal enters the computer via the USB. That's the

software world! At the TX path, the story is pretty much the same, except that it

happens reversely. We need to send a baseband I/Q complex signal to the USRP

board. The digital up converter (DUC) will interpolate the signal, up convert it to the

IF band and finally send it through the DAC.

Page 73: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX B

Windows Installation

For more information on the Windows Installation scripts and procedures, see also

Reference [7] in the References section.

Windows Porting Issues

Considerable effort has been put into making the GNU Radio code portable among

various operating systems, by the GNU Radio developers, but there are several

reasons why it cannot be "simply" compiled and run under Windows:

• The build and install procedures are based on Linux scripts and tools

• Several third-party libraries are used, each with its own, often system-

dependent, installation procedure

• Most GNU Radio applications must interface to hardware (e.g., a sound card

or USRP) which require system-dependent drivers and installation procedures

• Because GNU Radio is written as an extension to Python, there are potential

problems on Windows if different runtime libraries are used for GNU Radio

and Python

The following sections show how these issues can be addressed.

Installation Options

GNU Radio is designed to be flexible. It has a number of modules, capabilities, and

options that can be enabled or disabled to suit the needs of the user, and the user can

add custom blocks or modules to the system.

To support this flexibility, it comes with a set of files and scripts to be used

with GNU software build tools (sh, make, autoconf, automake, etc.). These tools use

Linux-like commands and filenames that are not normally available on Windows

systems.

Page 74: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Cygwin

Cygwin is a Linux-like environment for Windows. It provides the Linux-like shell,

file naming, and build tools we need and also makes it easy to install many of the

third-party libraries required by GNU Radio. It also provides a Linux programming

interface (API); this is not required by GNU Radio, but it lets us use the better-tested

Linux versions of some functions.

Because the Linux API uses its own C runtime library, it is best to use Cygwin

versions of Python and the third-party libraries when building GNU Radio with

Cygwin.

Installing GNU Radio with Cygwin

The easiest way to install GNU Radio on Windows is to use the Cygwin environment.

Once Cygwin and the required utilities and third-party libraries are installed,

installation of GNU Radio is as easy on Windows as it is on Linux.

To install GNU Radio with Cygwin we need to:

• Install the Cygwin environment

• Install the required utilities and third-party libraries

• Build and install GNU Radio

• Install the driver for the USRP

One way to accomplish each of these steps is described below.

Installing Utilities and Third-Party Libraries

Utilities and third-party libraries are of two types: those that are available as Cygwin

packages and those that must be downloaded and/or built separately.

Installing Cygwin packages

Page 75: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Before installing any of these packages, we need to see the “hints, tips, known

problems, and solutions for Windows” section regarding python.

We will need the following Cygwin packages to build GNU Radio.

• autoconf

• automake1.10 (or automake1.9)

• binutils

• boost-devel

• gcc-core (version 3.4.4-2 or later preferred)

• gcc-g++ (version 3.4.4-2 or later preferred)

• libtool1.5

• make

• Numeric

• patch

• pkg-config

• python (get version 2.4.3-1; version 2.5 doesn't work with GNU Radio yet)

• swig (Note: Building from the SVN trunk requires version 1.3.31 or higher of

swig; until this version is available as a package, we will need to build our

own from source; see the “hints, tips, known problems, and solutions for

Windows” section.)

For the USRP we will also need:

• libusb-win32 (get version 0.1.10.1-3; version 0.1.12.0-1 doesn't work with

GNU Radio yet)

• SDCC (Small Device C Compiler);

To install from SVN we will need:

• subversion

Other libraries and utilities

Page 76: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Some of the libraries and utilities required by GNU Radio are not available as Cygwin

packages. These packages must be installed manually:

• FFTW: the Cygwin package does not include single precision;

• CppUnit: a C++ unit test framework;

• wxPython: not required for all applications, but extremely useful;

• NumPy (Numerical Python): a package of numerical extensions for python;

• Swig: you need version 1.3.31 or higher; see the “hints, tips, known problems,

and solutions for Windows” section.

For simultaneous capture and play of audio from the sound card or have difficulties

with the basic audio support, we may want:

• PortAudio:

Building and Installing GNU Radio

GNU Radio is a large system with many options. The simplest build procedure

configures and builds all the modules that it can, but we can customize our installation

(and maybe save some time) by specifying appropriate options. The sections below

show how to download the GNU Radio source code, build a minimal GNU Radio

system (recommended for the first test), and then how to build and install everything.

Downloading the GNU Radio Source Code

The simplest way to get the GNU Radio source code is to download the tarball from

ftp://ftp.gnu.org/gnu/gnuradio/gnuradio-3.0.4.tar.gz to a convenient working directory

and unpack it with

$ tar zxf gnuradio-3.0.4.tar.gz

to produce the directory gnuradio-3.0.4. The tarball includes stable versions of the

components needed by most users. If we prefer to get the latest versions of

everything, we can check out the code from the Subversion (SVN) repository with:

Page 77: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

$ svn co http://gnuradio.org/svn/gnuradio/trunk gnuradio

$ cd gnuradio

$./bootstrap

This checks out the current version to a tree headed by a directory named gnuradio

and prepares for configuration. The following instructions assume the code is in

gnuradio-3.0.4

We may get warning messages, but unless one of these commands stops with an error

message we should have a working installation of GNU Radio. If we do get errors be

sure to check

.

Building a Minimal GNU Radio System

For a first test, it is helpful to build a minimal GNU Radio. This is done with the

commands:

$ cd gnuradio-3.0.4

$ ./configure --with-boost-include-dir=/usr/include/boost-1_33_1 --disable-

all-components --enable-gnuradio-core --enable-graudio-oss

This disables all components except those explicity enabled, namely gnuradio-core

and gr-audio-oss. To build and install these components we use the commands:

$ cd gnuradio-3.0.4

$ make

$ make check

$ make install

hints, tips, known problems, and solutions for Windows.

Page 78: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

To use GNU Radio we need to tell Python where to find it:

$ export PYTHONPATH=/usr/local/lib/python2.4/site-packages

We can save our self some trouble by adding this line to our ~/.bash profile

This should produce a dialtone through our speakers. If Python gives an error

message, there is a problem with the installation of GNU Radio. If we get no error

messages but no sound, we need to check to see that the speakers are turned on, the

volume is turned up, and that the "Wave" source is enabled in the audio control panel.

We use Ctrl-C to stop the dialtone. If

file.

To actually make GNU Radio do something, we can try this:

$ cd gnuradio-3.0.4/gnuradio-examples/python/audio

$ python dial_tone.py

dial_tone.py stops by itself without producing

sound or gives a Windows error pop-up, then our version of Cygwin may be out of

date (see hints, tips, known problems, and solutions for Windows).

With this minimal GNU Radio system we can capture signals from our sound card,

read signals from a file, or generate signals; process signals; and play signals on our

sound card or save them to a file.

Building a Full GNU Radio System

Building a full GNU Radio system is simpler but takes longer:

$ cd gnuradio-3.0.4

$ ./configure –with-boost-include-dir=/usr/include/boost-1_33_1

Page 79: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

This enables all components for which the required libraries and utilities are available.

To build and install these components we use the commands:

$ cd gnuradio-3.0.4

$ make

$ make check

$ make install

Unless one of these steps fails due to an error, we should have a working GNU Radio

installation. If one of the steps fails, we may be able to disable the component that

failed. We use “./configure –help” to see how the components are named. We look

for the "--enable-..." options and add the corresponding "--disable-..." option to our

./configure

Hints, Tips, Known Problems, and Solutions for Windows

command and repeat the above steps.

Installing the Driver for the USRP

For the USRP we will need to install the driver for it;

The following topics may be useful to users of GNU Radio on Windows.

A. tar.gz or tar.tar?

Sometimes when you download a package (e.g., FFTW or CppUnit) labelled

"thing.tar.gz" it will put on your system with the filename "thing.tar.tar

". I don't know

why this happens, but if it does you will need change any commands that refer to the

downloaded file to use the actual filename on your system.

Page 80: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

B. Python on Cygwin

Python 2.4 is required by Numeric. wxPython also has unresolved issues with python

2.5. However, python 2.4 is no longer carried by the Cygwin mirrors. Therefore

installing it is a little tricky.

• Download a copy of Python 2.4 from

http://cygwin.rtin.bz/release/python/python-2.4.3-1.tar.bz2.

• Go to your cygwin packages directory and edit the setup.ini from the mirror

you use, so that it installs the version of python you downloaded as if it was

the current version. When editing release.ini, first find the section starting "@

python". Remove everything after from [prev] to end of the section. Modify

the "source:" line, so that it points to the package you downloaded. The two

numbers that appear after the package name are the file size (in bytes) and the

md5 checksum. You'll need to correct the file size. You can remove the

checksum altogether.

• Use the cygwin setup.exe to install the python package. Be sure to select

"Install from Local Directory" (not "Install from Internet"), otherwise your

changes to setup.ini will be lost.

• If you use cygwin setup.exe again later, make sure that the action for python is

always set back to "keep", otherwise cygwin may upgrade it to version 2.5.

If you've installed version 2.5 by accident, you may have to start again from scratch.

(Uninstalling didn't work for me.) You might have version 2.5 installed if you've tried

to install boost-devel, Numeric (or any other package that depends on python) before

following this procedure. To check which version you have installed, run cygcheck -c

python.

C. CppUnit on Cygwin

CppUnit is a library that assists in automated testing of GNU Radio. Unfortunately, it

takes a little care to get a working version of CppUnit under Cygwin. This is because:

Page 81: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

• the Cygwin cppunit package version (1.9.14-1) does not work with GNU

Radio

• CppUnit version 1.10.2 requires a patch to the build scripts to install it under

Cygwin

• CppUnit versions 1.11.0 through 1.12.0 cause ‘make check’ to fail in the pmt

D. SWIG 1.3.31 on Cygwin

Building from the latest SVN trunk requires version 1.3.31 or later of SWIG, but (as

of Dec 2006) the latest version available as a Cygwin package is 1.3.29. SWIG 1.3.31

can easily be built from source:

module of GNU Radio because of a problem in the Cygwin g++ library

1. Use Cygwin setup to uninstall any existing version of SWIG

2. Download SWIG 1.3.31 from http://www.swig.org/download.html

3. Build and install with:

tar zxf swig-1.3.31.tar.gz

cd swig-1.3.31

./configure

make

make install

Page 82: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX C

Page 83: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRP User’s and Developer’s GuideMatt Ettus, Ettus Research LLC <[email protected]>

This guide explains both basic usage of the USRP as well as how to expand it.

Table of ContentsIntroduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

SystemRequirements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Getting all the Software. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Usingyour USRP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

FPGA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6Standard FPGA Configuration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Daughterboard Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Logical Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Analog Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8Digital Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8ConnectorPinouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Available Daughterboards. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8BasicRX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9BasicTX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

IntroductionThe Universal Software Radio Peripheral, or USRP (pronounced "usurp") is designed to allow general purposecomputers to function as high bandwidth software radios. In essence, it serves as a digital baseband and IF section ofa radio communication system. In addition, it has a well-defined electrical and mechanical interface to RF front-ends(daughterboards) which can translate between that IF or baseband and the RF bands of interest

The basic design philosophy behind the USRP has been to do all of the waveform-specific processing, like modu-lation and demodulation, on the host CPU. All of the high-speed general purpose operations like digital up- anddownconversion, decimation and interpolation are done on the FPGA.

It is anticipated that the majority of USRP users will never need to use anything other than the standard FPGAconfiguration. However, for those users that wish to, the FPGA design may be changed or replaced. All of theinterfaces are well defined and documented.

Figure 1. USRP with Daughterboards

1

Page 84: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

2

Page 85: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

3

Page 86: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

This USRP has 2 BasicTX and 2 BasicRX boards mounted on it. Notice that the boards on the left are rotated 180degrees.

System RequirementsThe USRP requires a PC or Mac with a USB2 interface.

CapabilitiesTheUSRP has 4 high-speed analog to digital converters (ADCs), each at 12 bits per sample, 64 million samples persecond. There are also 4 high-speed digital to analog converters (DACs), each at 14 bits per sample, 128 millionsamples per second. These 4 input and 4 output channels are connected to an Altera Cyclone EP1C12 FPGA. TheFPGA, in turn, connects to a USB2 interface chip, the Cypress FX2, and on to the computer. The USRP connects tothe computer via a high speed USB2 interface only, and will not work with USB1.1.

Figure 2. Universal Software Radio Peripheral

4

Page 87: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

Getting StartedGetting all the SoftwareThe first step in using your USRP system is to get all of GNU Radio installed. This can sometimes be a dauntingprocess, as there are several other libraries which will need to be installed first.

Library Dependencies

• SWIG

We use SWIG (Simple Wrapper Interface Generator) to tie together the C++ and Python code in the GNU Radiosystem. We require that you have version 1.3.24 or newer. You’ll probably have to compile it from source, whichyou can find here: SWIG [http://www.swig.org]

• FFTW

FFTW is the library which GNU Radio uses for FFTs. GNU Radio requires version 3.0.1 or newer, and it mustbe compiled for single precision. You can get it from the FFTW Homepage [http://www.fftw.org]

• BoostLibrary

Boostprovides several low-level structures used in our C++ code. If it is not included in your OS distribution,you can get it here: Boost [http://boost.org]

• CPPUnit

CPPUnitprovides our unit-testing framework. This creates automated tests to insure that code does not breakwhen changes are made. Get it at the CPP Unit Homepage [http://cppunit.sf.net]

Getting GNU Radio and the USRP code

Thereare several packages of software which make up GNU Radio and the USRP support software. Links to the latestversions of each can be found on the GNU Radio Wiki at Download Links [http://comsec.com/wiki?GnuRadio2.X].Gr-build can greatly simplify the installation process, and its use it highly recommended.

Following CVS Development

Development for the USRP proceeds very quickly at times, so some users may want to keep up with the latest byfollowing the CVS trees. There are three separate software repositories which contain various parts of the USRPsystem.

• USRP-HW, containing the hardware and FPGA designs.

All of the schematics in this repository were created in gEDA [http://www.geda.seul.org]. The board layoutswere created in PCB [http://pcb.sf.net]. Verilog designs are compiled in Quartus II Web Edition from Altera[http://www.altera.com].

• USRP-SW [https://sourceforge.net/cvs/?group_id=22397], USRP-SW, containing firmware and host drivers forthe USRP

Host side drivers and firmware which runs in the USB2 interface chip on the board.

5

Page 88: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

• GNU Radio/gr-usrp [http://comsec.com/wiki?CvsAccess] which contains the GNU Radio interface to the USRP

Using your USRP

Mechanical Connection

The USRP ships with a complete set of standoffs, nuts and bolts. There are 20 standoffs, M3x10mm M-F, of which 4are intended to be used as "feet" for the USRP. Place them in the 4 corner holes on the main board, inserting the malepart from below. The remaining 16 are used to hold the daughterboards in place. Four of them should be connectedto the male portion of the 4 standoffs already inserted from below. The remaining 12 should be connected to theboard with the 12 M3x6mm screws from below. At this point there should be 16 standoffs on the board with the maleends up to serve as a guide for the daughterboards. The 16 M3 nuts are used to fasten the daughterboards down to themain board.

TheUSRP accomodates 2 TX and 2 RX daughterboards. The placement of the standoffs is designed to prevent theaccidental incorrect connection of daughterboards. The 2 sides of the USRP have their daughterboard slots rotated180 degrees. The USRP should not be operated without standoffs, and daughterboards should never be connected orremoved while power is applied.

Electrical Connections

The USRP is powered by a 6V 4A power converter included in the kit. The converter is capable of 90-260 Vac, 50/60Hz operation, and so should work in any country. If there is a need to use another power supply, the connector is astandard 2.1mm/5.5mm DC power connector. The USRP itself only needs 5V at 2A, but a 6V supply was chosen toaccomodate future daughterboards. Extra power supplies are available from Ettus Research.

The included USB cable should be connected to a USB2-capable socket on a computer. The USRP does not supportUSB 1.1 operation at this time.

Troubleshooting

When first powered up, an LED on the USRP should be flashing at about 3-4x per second. This indicates that theprocessor is running, and has put the device in a low power mode. Once firmware has been downloaded to the USRP,the LED will blink at a slower rate. If there is no blinking LED, check all power connections, and check for continuityin the power fuse (F501, near the power connector). If the fuse needs replacement, it is size 0603, 3 amps.

FPGAStandard FPGA ConfigurationIn the standard fpga configuration, usrp_std, all samples sent over the USB interface are in 16-bit signed integers inIQ format. When there are multiple channels (up to 4), the channels are interleaved. For example, with 4 channels,the sequence would be I0 Q0 I1 Q1 I2 Q2 I3 Q3 I0 Q0, etc.

The USRP can operate in full duplex mode. When in this mode, the transmit and receive sides are completelyindependent of one another. The only consideration is that the combined data rate over the bus must be 32 Megabytesper second or less. The multiple RX channels (1,2, or 4) must all be the same data rate (i.e. same decimation ratio).The same applies to the 1,2, or TX channels, which each must be at the same data rate (which may be different fromthe RX rate).

On the RX side, each of the 4 ADCs can be routed to either of I or the Q input of any of the 4 downconverters. Thisallows for having multiple channels selected out of the same ADC sample stream.

6

Page 89: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

The digital upconverters (DUCs) on the transmit side are actually contained in the AD9862 CODEC chips, not in theFPGA. The only transmit signal processing blocks in the FPGA are the interpolators. The interpolator outputs can berouted to any of the 4 CODEC inputs.

Figure 3. Digital Down Converter Block Diagram

Daughterboar d InterfacePowerDaughterboards are provided with clean regulated 3.3V for the analog and digital sections. Additionally there is a 6Vconnection straight from the wall supply which is intended to supply a 5V LDO regulator. All daughterboards maydraw a combined total of 1.5 A.

Logical Interface7

Page 90: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

There are slots for 2 TX daughterboards, labeled TXA and TXB, and 2 corresponding RX daughterboards, RXA andRXB. Each daughterboard slot has access to 2 of the 4 high-speed data converter analog signals (DAC outputs for TX,ADC inputs for RX). This allows each daughterboard which uses real (not IQ) sampling to have 2 independent RFsections, and 2 antennas (4 total for the system). If IQ sampling is used, each board can support a single RF section,for a total of 2 for the whole system.

No antialias or reconstruction filtering is provided on the USRP motherboard. This allows for maximum flexibilityin frequency planning for the daughterboards. The analog input bandwidth of the ADCs is over 200 MHz, so IFfrequencies up to that high may be chosen. If several decibels of loss is tolerable, and IF frequency as high as 500MHz can be used.

Every daughterboard has an I2C EEPROM (24LC024 or 24LC025) onboard which identifies the board to the system.This allows the host software to automatically set up the system properly based on the installed daughterboard. TheEEPROM may also store calibration values like DC offsets or IQ imbalances. If this EEPROM is not programmed, awarning message is printed every time USRP software is run.

Analog InterfaceEach RX daughterboard has 2 differential analog inputs (VINP_A/VINN_A and VINP_B/VINN_B) which aresampled at a rate of 64 MS/s. The input impedance is approximately 1Kohm. The motherboard has a software-controllable programmable gain amplifier on these inputs, with 0 to 20 dB of gain. With gain set to zero, full scaleinputs are 2 Volts peak-to-peak differential. When set to 20 dB, only .2 V pk-pk differential is needed to reach fullscale.

If signals are AC-coupled, there is no need to provide DC bias as long as the internal buffer is turned on. It willprovide an approximately 2V bias. If signals are DC-couple, a DC bias of Vdd/2 (1.65V) should be provided to boththe positive and negative inputs, and the internal buffer should be turned off. VREF provides a clean 1 V reference.

Each TX daughterboard has a pair of differential analog outputs which are updated at 128 MS/s. The signals(IOUTP_A/IOUTN_A and IOUTP_B/IOUTN_B) are current-output, each varying between 0 and 20 mA. Sincethey are high-impedance, they can be converted into differential voltages with a resistor.

In addition to the high-speed signals, each daughterboard has exclusive access to 2 low-speed ADC inputs (labeledAUX_ADC_A and AUX_ADC_B) which can be read from software. These are useful for sensing RSSI signal levels,temperatures, bias levels, etc. Additionally, each board has shared access to 4 low-speed DAC signals, labeledAUX_DAC_A through AUX_DAC_D. RXA and TXA share one set of these 4 lines, and RXB and TXB sharetheir own independent set. These signals are useful for controlling gain of variable-gain amplifiers, for example.AUX_ADC_REF provides a reference level for gain setting if it is necessary.

Digital Interface

Connector Pinouts

Table 1. RX DBoard ConnectorPin # Name Description1 power This is powerc1 c4d1 d4 d5

8

Page 91: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

USRPUser’s and Devel-oper’s Guide

Available DaughterboardsBasicRX

BasicTX

9

Page 92: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX D

The source code of the “dial_tone.py” program:

#!/usr/bin/env python

from gnuradio import gr

from gnuradio import audio

from gnuradio.eng_option import eng_option

from optparse import OptionParser

class my_graph(gr.flow_graph):

def __init__(self):

gr.flow_graph.__init__(self)

parser = OptionParser(option_class=eng_option)

parser.add_option("-O", "--audio-output", type="string", default="",

help="pcm output device name. E.g., hw:0,0 or /dev/dsp")

parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,

help="set sample rate to RATE (48000)")

(options, args) = parser.parse_args ()

if len(args) != 0:

parser.print_help()

raise SystemExit, 1

sample_rate = int(options.sample_rate)

ampl = 0.1

src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)

src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)

dst = audio.sink (sample_rate, options.audio_output)

self.connect (src0, (dst, 0))

self.connect (src1, (dst, 1))

if __name__ == '__main__':

try:

my_graph().run()

except KeyboardInterrupt:

pass

Page 93: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX E

The source code of the FM Receiver (usrp_wfm_rcv.py) program:

#!/usr/bin/env python

from gnuradio import gr, gru, eng_notation, optfir

from gnuradio import audio

from gnuradio import usrp

from gnuradio import blks

from gnuradio.eng_option import eng_option

from gnuradio.wxgui import slider, powermate

from gnuradio.wxgui import stdgui, fftsink, form

from optparse import OptionParser

from usrpm import usrp_dbid

import sys

import math

import wx

def pick_subdevice(u):

"""

The user didn't specify a subdevice on the command line.

Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.

@return a subdev_spec

"""

return usrp.pick_subdev(u, (usrp_dbid.TV_RX,

usrp_dbid.TV_RX_REV_2,

usrp_dbid.TV_RX_REV_3,

usrp_dbid.BASIC_RX))

class wfm_rx_graph (stdgui.gui_flow_graph):

def __init__(self,frame,panel,vbox,argv):

stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)

parser=OptionParser(option_class=eng_option)

Page 94: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,

help="select USRP Rx side A or B (default=A)")

parser.add_option("-f", "--freq", type="eng_float", default=100.1e6, help="set

frequency to FREQ", metavar="FREQ")

parser.add_option("-g", "--gain", type="eng_float", default=40, help="set gain in dB

(default is midpoint)")

parser.add_option("-V", "--volume", type="eng_float", default=None, help="set volume

(default is midpoint)")

parser.add_option("-O", "--audio-output", type="string", default="", help="pcm

device name. E.g., hw:0,0 or surround51 or /dev/dsp")

(options, args) = parser.parse_args()

if len(args) != 0:

parser.print_help()

sys.exit(1)

self.frame = frame

self.panel = panel

self.vol = 0

self.state = "FREQ"

self.freq = 0

# build graph

self.u = usrp.source_c() # usrp is data source

adc_rate = self.u.adc_rate() # 64 MS/s

usrp_decim = 200

self.u.set_decim_rate(usrp_decim)

usrp_rate = adc_rate / usrp_decim # 320 kS/s

chanfilt_decim = 1

demod_rate = usrp_rate / chanfilt_decim

audio_decimation = 10

audio_rate = demod_rate / audio_decimation # 32 kHz

if options.rx_subdev_spec is None:

options.rx_subdev_spec = pick_subdevice(self.u)

self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))

Page 95: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)

print "Using RX d'board %s" % (self.subdev.side_and_name(),)

chan_filt_coeffs = optfir.low_pass (1, # gain

usrp_rate, # sampling rate

80e3, # passband cutoff

115e3, # stopband cutoff

0.1, # passband ripple

60) # stopband attenuation

#print len(chan_filt_coeffs)

chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)

self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)

self.volume_control = gr.multiply_const_ff(self.vol)

# sound card as final sink

audio_sink = audio.sink (int (48000),

options.audio_output,

False) # ok_to_block

# now wire it all together

self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)

self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)

if options.gain is None:

# if no gain was specified, use the mid-point in dB

g = self.subdev.gain_range()

options.gain = float(g[0]+g[1])/2

if options.volume is None:

g = self.volume_range()

options.volume = float(g[0]+g[1])/2

if abs(options.freq) < 1e6:

options.freq *= 1e6

Page 96: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

# set initial values

self.set_gain(options.gain)

self.set_vol(options.volume)

if not(self.set_freq(options.freq)):

self._set_status_msg("Failed to set initial frequency")

def _set_status_msg(self, msg, which=0):

self.frame.GetStatusBar().SetStatusText(msg, which)

def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):

def _form_set_freq(kv):

return self.set_freq(kv['freq'])

if 1:

self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",

fft_size=512, sample_rate=usrp_rate)

self.connect (self.u, self.src_fft)

vbox.Add (self.src_fft.win, 4, wx.EXPAND)

if 1:

post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod", fft_size=1024,

sample_rate=usrp_rate, y_per_div=10, ref_level=0)

self.connect (self.guts.fm_demod, post_filt_fft)

vbox.Add (post_filt_fft.win, 4, wx.EXPAND)

if 0:

post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph", fft_size=512,

sample_rate=audio_rate, y_per_div=10, ref_level=-20)

self.connect (self.guts.deemph, post_deemph_fft)

vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)

# control area form at bottom

self.myform = myform = form.form()

hbox = wx.BoxSizer(wx.HORIZONTAL)

hbox.Add((5,0), 0)

Page 97: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

myform['freq'] = form.float_field(

parent=self.panel, sizer=hbox, label="Freq", weight=1,

callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))

hbox.Add((5,0), 0)

myform['freq_slider'] = \

form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(87.9e6,

108.1e6, 0.1e6), callback=self.set_freq)

hbox.Add((5,0), 0)

vbox.Add(hbox, 0, wx.EXPAND)

hbox = wx.BoxSizer(wx.HORIZONTAL)

hbox.Add((5,0), 0)

myform['volume'] = \

form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3,

range=self.volume_range(), callback=self.set_vol)

hbox.Add((5,0), 1)

myform['gain'] = \

form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3,

range=self.subdev.gain_range(), callback=self.set_gain)

hbox.Add((5,0), 0)

vbox.Add(hbox, 0, wx.EXPAND)

try:

self.knob = powermate.powermate(self.frame)

self.rot = 0

powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate)

powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button)

except:

print "FYI: No Powermate or Contour Knob found"

def on_rotate (self, event):

self.rot += event.delta

Page 98: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

if (self.state == "FREQ"):

if self.rot >= 3:

self.set_freq(self.freq + .1e6)

self.rot -= 3

elif self.rot <=-3:

self.set_freq(self.freq - .1e6)

self.rot += 3

else:

step = self.volume_range()[2]

if self.rot >= 3:

self.set_vol(self.vol + step)

self.rot -= 3

elif self.rot <=-3:

self.set_vol(self.vol - step)

self.rot += 3

def on_button (self, event):

if event.value == 0: # button up

return

self.rot = 0

if self.state == "FREQ":

self.state = "VOL"

else:

self.state = "FREQ"

self.update_status_bar ()

def set_vol (self, vol):

g = self.volume_range()

self.vol = max(g[0], min(g[1], vol))

self.volume_control.set_k(10**(self.vol/10))

self.myform['volume'].set_value(self.vol)

self.update_status_bar ()

def set_freq(self, target_freq):

"""

Set the center frequency we're interested in.

@param target_freq: frequency in Hz

Page 99: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

@rypte: bool

Tuning is a two step process. First we ask the front-end to

tune as close to the desired frequency as it can. Then we use

the result of that operation and our target_frequency to

determine the value for the digital down converter.

"""

r = usrp.tune(self.u, 0, self.subdev, target_freq)

if r:

self.freq = target_freq

self.myform['freq'].set_value(target_freq) # update displayed value

self.myform['freq_slider'].set_value(target_freq) # update displayed value

self.update_status_bar()

self._set_status_msg("OK", 0)

return True

self._set_status_msg("Failed", 0)

return False

def set_gain(self, gain):

self.myform['gain'].set_value(gain) # update displayed value

self.subdev.set_gain(gain)

def update_status_bar (self):

msg = "Volume:%r Setting:%s" % (self.vol, self.state)

self._set_status_msg(msg, 1)

self.src_fft.set_baseband_freq(self.freq)

def volume_range(self):

return (-20.0, 0.0, 0.5)

if __name__ == '__main__':

app = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX")

app.MainLoop ()

Page 100: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX F

Page 101: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Tutorial 7: Exploring the FM receiver

Dawei Shen∗

July 12, 2005

Abstract

In tutorial 5, we skip the discussion on how the FM signal is demodulated, leaving the big‘guts’ as a black box. In this article, the real signal processing techniques for demodulating theFM signal are introduced. We will dig into this black box and see how the signal is processed inthe software world.

1 Overview

In previous tutorials, we have introduced the hardware setup of GNU Radio and some programmingtips, which form the basis of a real application in the ‘soft world’. In this article, we will investigate howthe broadcast FM signal is demodulated. The FM receiver is a typical example in GNU Radio. Youare able to hear strong stations using just a piece of wire. In tutorial 5, we skipped the introductionto the big box ‘guts’, where the real magics of the FM detection are. We will show how the signal isprocessed from the air to the sound card in this tutorial.

2 From the air to the computer, from real to complex

In tutorial 3 and 4, we have discussed the operations on the USRP, especially the role of the digitaldown converter (DDC). Basically what the USRP does is to select the part of the spectrum we areinterested in and decimate the digital sequence by some factor N. The resulting signal is complex(gr_complex) with I/Q two channels. So after we finish writing these lines

src = usrp.source_c (0, decim) # decim = 250, so data rate (quad_rate) is 256kHzsrc.set_rx_freq (0, IF_freq) # IF_freq = our input - 128MHzsrc.set_pga(0,20)

we’ve got a ‘complex’ signal, with a data rate 256k samples per second. We name it ‘quadraturerate’ - quad_rate because the complex signal has I/Q quadrature components.

The IF frequency we choose is an interesting and useful point here. IF_freq is equal to the user’sinput minus 128MHz, as the line in function parseargs() indicates:

∗The author is affiliated with Networking Communications and Information Processing (NCIP) Laboratory,Department of Electrical Engineering, University of Notre Dame. Welcome to send me your comments orinquiries. Email: [email protected]

1

Page 102: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

2 Tutorial 7 - Exploring the FM receiver

return freq1 - 128e6

wfm_rcv_gui was written assuming that there was no RF front end doing any down conversion. TheA/D sample rate is 64M. The Nyquist zones are therefore:

[0, 32M] normal[32M, 64M] inverted[64M, 96M] normal[96M, 128M] inverted

etc.

The problem is that 96M, one of the folding points, occurs right in the middle of the broadcastband. This means that 95.0 and 97.0 both alias down to the same frequency and can’t be distinguishedfrom each other. freq1 - 128M will give a valid frequency if freq1 is >= 96M. Bottom line: it’s akludge that sort of works.

3 Getting the instantaneous frequency, from complex to real

It’s time to dig into the heart of the ‘guts’ now, which we left as a big black box in tutorial 5.

guts = blks.wfm_rcv (self, quad_rate, audio_decimation)

blks is a package in gnuradio. It almost does nothing but refers to another package blksimpl.wfm_rcv is a class defined in /gnuradio/blksimpl/wfm_rcv.py, which is real ‘processor’ of the FMreceiver. The source code is appended at the end.

wfm_rcv is derived from gr.hier_block. gr.hier_block describes a series of blocks in tandemin a flow graph. It assumes that there is at most a single block at the head of the chain and a singleblock at the end of the chain. Either head or tail may be None indicating a sink or source respectively.hier_block could be recognized a sub-graph consisting of several blocks connected one after another.To construct a hier_block, we need to specify the flow graph that contains this hierarchical block,the first and the last block in the signal processing chain. A hierarchical block could be treated as acommon block, which could be placed and connected in a flow graph, like these lines demonstrate:

self.connect (src, guts)self.connect (guts, (audio_sink, 0))

The ‘head’ block in the chain is fm_demod, the instance of gr.quadrature_demod_cf. To under-stand the real work within it, we should know a bit about how FM signals are generated. With FM,the instantaneous frequency of the transmitted waveform is varied as a function of the input signal.The instantaneous frequency at any time is given by the following formula:

f(t) = k * m(t) + fc

m(t) is the input signal, k is a constant that controls the frequency sensitivity and fc is thefrequency of the carrier (for example, 100.1MHz). So to recover m(t), two steps are needed. Firstwe need to remove the carrier fc, then we’re left with a baseband signal that has an instantaneousfrequency proportional to the original message m(t). The second step is obviously to compute theinstantaneous frequency of the baseband signal. Thus, our challenge is to find a way to remove thecarrier and compute the instantaneous frequency. Removing the carrier has been done on the FPGA,via the digital down converter (DDC), as introduced in tutorial 3 and 4. We have explained why we

Page 103: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

D. Shen 3

tune to (fc - 128MHz) in the preceding section. The resulting signal coming into the ‘guts’ has alreadybecome a baseband signal and the remaining task is to calculate its instantaneous frequency. If weintegrate frequency, we get phase, or angle. Conversely, differentiating phase with respect to timegives frequency. These are the key insights we use to build the receiver.

We use the gr.quadrature_demod_cf block for computing the instantaneous frequency of thebaseband signal. We approximate differentiating the phase by determining the angle between adjacentsamples. Recall that the digital down converter produces complex numbers on its output. Using abit more trigonometry, we can determine the angle between two subsequent samples by multiplyingone by the complex conjugate of the other and then taking the arc tangent of the product. Once youknow what you want, it doesn’t take much code. gr_quadrature_demod_cf.cc contains the C++implementation of this block. We will talk about how to write a signal processing block using C++in detail in tutorial 10 and 11. But it’s useful to give a shot at the code now. The bulk of the signalprocessing is the three-line loop in sync_work() function.

Part of gr_quadrature_demod_cf.cc...

intgr_quadrature_demod_cf::sync_work (

int noutput_items,gr_vector_const_void_star &input_items,gr_vector_void_star &output_items)

gr_complex *in = (gr_complex *) input_items[0];float *out = (float *) output_items[0];in++; // ensure that in[-1] is validfor (int i = 0; i < noutput_items; i++)gr_complex product = in[i] * conj (in[i-1]);out[i] = d_gain * arg (product);

return noutput_items;

A helpful diagram for the FM receiver can be found here.

fm_demod_gain = quad_rate/(2*math.pi*max_dev)

Note that fm_demod_gain can be treated as a constant controlling the volume. Its real valuedoesn’t matter. Here arg (product) is the phase difference between adjacent samples, if we divideit by the sample interval, i.e. multiply the data rate quad_rate, we get the radian frequency ω,which gives us the instantaneous frequency f if we further divide ω by 2π. Finally we normalize thefrequency by max_dev.

4 Deemphasizer

The second block in the chain is a deemphasizer deemph, an instance of the class fm_deemph. fm_deemphis defined in fm_emph.py, also located in the package blksimpl.

What is deemphasis? Let’s introduce it briefly. It has been theoretically proved that, in FMdetector, the power of the output noise increases with the frequency quadratically. However, formost practical signals, such as human voice and music, the power of the signal decreases significantlyas frequency increases. As a result, the signal noise ratio (SNR) at the high frequency end usuallybecomes unbearable. To circumvent this effect, people introduce ‘preemphasis’ and ‘deemphasis’ into

Page 104: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

4 Tutorial 7 - Exploring the FM receiver

the FM system. At the transmitter, we use proper preemphasis circuits to manually amplify the highfrequency components, and do the converse operations at the receiver to recover the original powerdistribution of the signal. As a result, we improve the SNR effectively.

In the analog world, a simple first order RLC circuit usually suffices for preemphasis and deem-phasis. Here is a nice plot of their transfer functions. In our digital signal processing, a first order IIRfilter could be the right choice.

Part of fm_emph.py...

# 1# H(s) = -------# 1 + s## tau is the RC time constant.# critical frequency: w_p = 1/tau## We prewarp and use the bilinear z-transform to get our IIR coefficients.# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis#class fm_deemph(gr.hier_block):

"""FM Deemphasis IIR filter."""def __init__(self, fg, fs, tau=75e-6):

"""@type fs: float@param tau: Time constant in seconds (75us in US, 50us in EUR)@type tau: float"""w_p = 1/tauw_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq

a1 = (w_pp - 1)/(w_pp + 1)b0 = w_pp/(1 + w_pp)b1 = b0

btaps = [b0, b1]ataps = [1, a1]

deemph = gr.iir_filter_ffd(btaps, ataps)gr.hier_block.__init__(self, fg, deemph, deemph)

We start from the transfer function of the analog filter as prototype, and use bilinear transformationto get the digital IIR filter. Note that gr.iir_filter_ffd is the IIR filter block with float input,float output and double taps.

5 Audio FIR decimation filter

After passing the deemphasizer, how does the signal look like now? First, it’s a real signal with adata rate of 256kHz. Second, it’s a baseband signal, with effective frequency range from 0 to about100kHz, containing all the frequency components of a FM station.

As a side note, the bandwidth of a FM station is usually around 2 * 100kHz. This also explains

Page 105: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

D. Shen 5

why we choose 256kHz as the quadrature rate (the decimation rate on the USRP is chosen to be 250).A sample rate of 256kHz is just suitable for the 200kHz bandwidth, without losing any spectruminformation. Maybe you have noticed, in the FM receiver, we never use any low-pass filtering operationto ‘pick out’ the FM station we are interested in. Actually this is done implicitly in the digital downconverter (DDC) on the USRP. Recall that digital down converter can be regarded as a low-pass FIRfilter followed by a downsampler. As a result, the target station is picked out then spread out tothe entire digital spectrum after decimation. Because we choose the right decimation rate, we haveeventually done a lot! The bottom line is, we are operating on a single FM station after the signalgoes through the USRP.

Now we need to resolve two issues. First, the signal rate is 256kHz now, much higher than what thesound card can adopt. The PC sound cards usually sample up to 96,000 Hz maximum. Second, the100kHz spectrum contains several channels, L + R, L - R, pilot tones, etc. To keep our life simpler, wejust want to design a mono receiver low-passing only the L + R signal. So clearly, an FIR decimationfilter is exactly what we want.

To make things clearer, here is a brief introduction to the FM signal band. From 0 to about 16kHzis the left plus right (L + R) audio. The peak at 19kHz is the stereo pilot tone. The left minus right(L - R) stereo information is centered at 2x the pilot (38kHz) and is AM-modulated on top of the FM.Additional subcarriers are sometimes found in the region of 57kHz - 96kHz. We can use the GNURadio built-in fft block with GUI supports to view the spectrum of the demodulated signal (detailswill be introduced in tutorial 8). Here is a nice real plot given by Eric. Here is a good illustration ofthe FM band.

OK, now let’s design the FIR decimation filter. The GNU Radio block gr.fir_filter_fff givesus an FIR filter with float input, float output, and float taps. Its constructor takes two arguments:the first one is the decimation factor, the second one is the filter coefficients (taps) vector.

self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)

If we need an FIR filter without changing the data rate, then we just simply set the decimationrate to be 1. If we need an interpolation filter rather than a decimation filter, then the GNU Radioblock gr.interp_fir_filter_xxx is what we should choose.

The filter coefficients audio_coeffs are obtained using the FIR filter design block gr.firdes.low_pass() is a static public function defined in the class gr_firdes. Similarly, it also has high_pass(),band_pass(), band_reject() functions. We use these functions to design the FIR filter taps, pro-vided the filter parameters and specifications. For example, the syntax for design a low-pass filter is:

vector< float > gr_firdes::low_pass ( double gain,double sampling_freq,double cutoff_freq,double transition_width,win_type window = WIN_HAMMING,double beta = 6.76) [static]

The meaning of each argument is quite obvious. Note that beta is a parameter for Kaiser window.In our example, we select the audio decimation factor (audio_decimation) to be 8, so that theresulting data rate for the sound card is 32kHz. We are only interested in the L + R audio from 0 to16kHz, so we low pass the output of the quadrature demodulator with a cutoff frequency of 16kHz.This gives us a monaural output that we connect to the sound card outputs. In our example, wechoose the cutoff frequency as 15kHz and transition band as 1kHz, which is reasonable.

width_of_transition_band = audio_rate / 32audio_coeffs = gr.firdes.low_pass (volume, # gain (20)

Page 106: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

6 Tutorial 7 - Exploring the FM receiver

quad_rate, # sampling rate (32kHz)audio_rate/2 - width_of_transition_band, (15kHz)width_of_transition_band, (16kHz)gr.firdes.WIN_HAMMING)

OK! Our FM receiver is complete! The signal is at the door of the sound card and is ready to beplayed. Note that the usage of FIR filters, as well as multirate processing is very important in thedigital signal processing.

Finally, we connect these blocks and call the __init__() method of gr.hier_block to completethe __init__() method of the wfm_rcv class. Here we need to specify the head and the tail of thepipeline.

fg.connect (self.fm_demod, self.deemph, self.audio_filter)gr.hier_block.__init__(self,

fg,self.fm_demod, # head of the pipelineself.audio_filter) # tail of the pipeline

6 Conclusion

In this article, we have introduced the FM detection techniques and how they are implemented usingGNU Radio. Now we can see GNU Radio is really a nice system, providing us so many powerful toolsand flexible ways to construct a real application. In next tutorial, we will wrap up the explanation ofwfm_rcv_gui.py, with an emphasis on the GNU Radio GUI tools.

APPENDIX A: The source code

from gnuradio import grfrom gnuradio.blksimpl.fm_emph import fm_deemphimport math

class wfm_rcv(gr.hier_block):def __init__ (self, fg, quad_rate, audio_decimation):

"""Hierarchical block for demodulating a broadcast FM signal.

The input is the downconverted complex baseband signal (gr_complex).The output is the demodulated audio (float).

@param fg: flow graph.@type fg: flow graph@param quad_rate: input sample rate of complex baseband input.@type quad_rate: float@param audio_decimation: how much to decimate quad_rate to get to audio.@type audio_decimation: integer"""volume = 20.

max_dev = 75e3fm_demod_gain = quad_rate/(2*math.pi*max_dev)audio_rate = quad_rate / audio_decimation

Page 107: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

D. Shen 7

# We assign to self so that outsiders can grab the demodulator# if they need to. E.g., to plot its output.## input: complex; output: floatself.fm_demod = gr.quadrature_demod_cf (fm_demod_gain)

# input: float; output: floatself.deemph = fm_deemph (fg, quad_rate)

# compute FIR filter taps for audio filterwidth_of_transition_band = audio_rate / 32audio_coeffs = gr.firdes.low_pass (volume, # gain

quad_rate, # sampling rateaudio_rate/2 - width_of_transition_band,width_of_transition_band,gr.firdes.WIN_HAMMING)

# input: float; output: floatself.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)

fg.connect (self.fm_demod, self.deemph, self.audio_filter)

gr.hier_block.__init__(self,fg,self.fm_demod, # head of the pipelineself.audio_filter) # tail of the pipeline

References

[1] Eric Blossom, Listening to FM Radio in Software, Step by Step,http://www.linuxjournal.com/article/7505

Page 108: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX G

Page 109: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

Tutorial 8: Getting Prepared for Python in GNU Radio by

Reading the FM Receiver Code Line by Line – Part II

Dawei Shen∗

July 13, 2005

Abstract

Let’s continue our discussion on the FM example wfm_rcv_gui.py. The usage of the GUItools in GNU Radio, which are built upon wxPython, will be shown. We will also introduce someuseful programming tips on argument parsing. If you are interested in using or even developingthe GUI tools, this article would be helpful.

1 Overview

In this article, we will complete our discussion on the FM receiver code wfm_rcv_gui.py. One excitingfeature of GNU Radio, is it incorporates powerful GUI tools for displaying and analyzing the signal,emulating the real spectrum analyzer and the oscillograph. We will introduce the usage of the GUItools, which are built upon wxPython. Next we will talk about how to handle the command linearguments in Python.

2 GUI tools in GNU Radio

The most intuitive and straightforward way to analyze a signal is to display it graphically, both intime domain and frequency domain. For the applications in the real world, we have the spectrumanalyzer and the oscillograph to facilitate us. Fortunately, in the software radio world, we also havesuch nice tools, thanks to wxPython, which provides a flexible way to construct GUI tools.

2.1 The ‘Spectrum Analyzer’ - fft sink

Let’s continue to read the code:

if 1:pre_demod, fft_win1 = \

fftsink.make_fft_sink_c (self, panel, "Pre-Demodulation",

∗The author is affiliated with Networking Communications and Information Processing (NCIP) Laboratory,Department of Electrical Engineering, University of Notre Dame. Welcome to send me your comments orinquiries. Email: [email protected]

1

Page 110: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

2

512, quad_rate)self.connect (src, pre_demod)vbox.Add (fft_win1, 1, wx.EXPAND)

This is the ‘soft spectrum analyzer’, based on fast Fourier transformation (FFT) of the digitalsequence. This ‘soft spectrum analyzer’ is used as the signal sink. That’s why it is named as ‘fftsink’.It’s defined in the module wxgui.fftsink.py. The function make_fft_sink_c() serves as the publicinterface to create an instance of the fft sink:

/site-packages/gnuradio/wxgui/fftsink.py...def make_fft_sink_c(fg, parent, title, fft_size, input_rate, ymin=0, ymax=100):

block = fft_sink_c(fg, parent, title=title, fft_size=fft_size,sample_rate=input_rate, y_per_div=(ymax - ymin)/8, ref_level=ymax)

return (block, block.win)

First, we should point out that in Python, a function could return multiple values. make_fft_sink_c()returns two values: block is an instance of the class fft_sink_c, defined in the same modulewxgui.fftsink.py. Another special feature of Python needs to be emphasized: Python supportsmultiple inheritance. fft_sink_c is derived from two classes: gr.hier_block and fft_sink_base.Being a ‘son’ class of gr.hier_block implies that fft_sink_c can be treated as a normal block,which can be placed and connected in a flow graph, as the next line shows:

self.connect (src, pre_demod)

block.win is obviously an attribute of block. In the definition of the class fft_sink_c, wecan find its data type is the class fft_window, a subclass of wx.Window, also defined in the modulewxgui.fftsink.py. We can think of it as a window that is going to be hang up on your screen. Thiswindow block.win will be used as the argument of the method vbox.Add.

2.2 How wxPython plays its role

To understand the other parts thoroughly, we need to know a little bit about wxPython, a GUI toolkitfor Python. Interested readers may visit wxPython’s website or tutorials’ page for more information.It might be time consuming to explore all the technical details about wxPython. The good news is inGNU Radio, we can use the spectrum analyzer and oscillograph pretty much as it is. Just copythose lines anywhere you want with only a few changes.

Let’s invest some time in wxPython’s organism. The first thing to do is certainly to import allwxPython’s components into current workspace, like the line ‘import wx’ does. Every wxPythonapplication needs to derive a class from wx.App and provide an OnInit() method for it. The systemcalls this method as part of its startup/initialization sequence, in wx.App.__init()__. The primarypurpose of OnInit() is to create the frames, windows, etc. necessary for the program to beginoperation. After defining such a class, we need to instantiate an object of this class and start theapplication by calling its MainLoop() method, whose role is to handle the events. In our FM receiverexample, where is such a class defined? Let’s look at the last three lines:

if __name__ == ’__main__’:app = stdgui.stdapp (wfm_rx_graph, "WFM RX")app.MainLoop ()

In fact, such a class, called stdapp has been created when we import the stdgui module.

from gnuradio.wxgui import stdgui, fftsink

Page 111: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

3

The final two lines again will probably be the same for all your wxPython applications. We simplycreate an instance of our application class, and then call its MainLoop() method. MainLoop() is theheart of the application and is where events are processed and dispatched to the various windows inthe application. There are some tricks behind the scene. Don’t worry about that.

Let’s look at the definition of stdapp in /gnuradio/wxgui/stugui.py:

class stdapp (wx.App):def __init__ (self, flow_graph_maker, title="GNU Radio"):

self.flow_graph_maker = flow_graph_makerself.title = title# All our initialization must come before calling wx.App.__init__.# OnInit is called from somewhere in the guts of __init__.wx.App.__init__ (self)

def OnInit (self):frame = stdframe (self.flow_graph_maker, self.title)frame.Show (True)self.SetTopWindow (frame)return True

stdapp is right the class derived from wx.App. Its initialization method __init__() takes twoarguments: flow_graph_maker, a class belonging to the flow graph family (remember the biggest classwfm_rx_graph we created is derived from gr.flow_graph?); title, the title of the whole application(WFM RX in our example). In OnInit() method, these two arguments are further used to create theobject of stdframe.

class stdframe (wx.Frame):def __init__ (self, flow_graph_maker, title="GNU Radio"):

# print "stdframe.__init__"wx.Frame.__init__(self, None, -1, title)

self.CreateStatusBar (2)mainmenu = wx.MenuBar ()

menu = wx.Menu ()item = menu.Append (200, ’E&xit’, ’Exit’)self.Bind (wx.EVT_MENU, self.OnCloseWindow, item)mainmenu.Append (menu, "&File")self.SetMenuBar (mainmenu)

self.Bind (wx.EVT_CLOSE, self.OnCloseWindow)self.panel = stdpanel (self, self, flow_graph_maker)vbox = wx.BoxSizer(wx.VERTICAL)vbox.Add(self.panel, 1, wx.EXPAND)self.SetSizer(vbox)self.SetAutoLayout(True)vbox.Fit(self)

def OnCloseWindow (self, event):self.flow_graph().stop()self.Destroy ()

def flow_graph (self):return self.panel.fg

Page 112: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

4

It’s worth taking a while to understand the layout of a wxPython GUI. In wxPython, a wx.Windowis anything which can take up visual space on the computer screen. Thus, the wx.Window class isthe base class from which all visual elements are derived – including input fields, pull-down menus,buttons, etc. The wx.Window class defines all the behavior common to all visual GUI elements,including positioning, sizing, showing, giving focus, etc. If we’re looking for an object to representa window on the computer screen, don’t look at wx.Window, look at wx.Frame instead. wx.Frame isderived from wx.Window. It implements all behavior specific to windows on the computer’s screen. A‘Frame’ is a window whose size and position can (usually) be changed by the user. It usually has thickborders and a title bar, and can optionally contain a menu bar, toolbar and status bar. A ‘Frame’ cancontain any window that is not a frame or dialog. So to create a ‘window’ on the computer screen,you create a wx.Frame (or one of its sub-classes, such as wx.Dialog), rather than a wx.Window.

Within a frame, you’ll use a number of wx.Window sub-classes to flesh out the frame’s con-tents, such as wx.MenuBar, wx.StatusBar, wx.ToolBar, sub-classes of wx.Control (eg. wx.Button,wx.StaticText, wx.TextCtrl, wx.ComboBox, etc.), or wx.Panel, which is a container to hold yourvarious wx.Control objects. All visual elements (wx.Window objects and their subclasses) can holdsub-elements. A wx.Frame might hold a number of wx.Panel objects, which in turn hold a numberof wx.Button, wx.StaticText and wx.TextCtrl objects.

In our example, stdframe, the subclass of wx.Frame, is used to create the ‘frame’. We make thisframe appear by ‘showing’ it using frame.Show (True). The SetTopWindow() method simply tellsthat this frame is one of the main frames (in this case the only one) for the application. Notice theshape of the constructor of wx.Frame:

wx.Frame(Parent, Id, "title")

Most of the constructors in wxPython have this shape: A parent object as a first parameter and anId in a second parameter. As shown in the example, it’s possible to use respectively None and -1 asdefault parameters, meaning the object has no parent and respectively a system-defined Id.

In stdframe.__init__(), we create a panel and place inside the frame.

self.panel = stdpanel (self, self, flow_graph_maker)

The class stdpanel is derived from wx.Panel:

class stdpanel (wx.Panel):def __init__ (self, parent, frame, flow_graph_maker):

wx.Panel.__init__ (self, parent, -1)self.frame = frame

vbox = wx.BoxSizer (wx.VERTICAL)self.fg = flow_graph_maker (frame, self, vbox, sys.argv)self.SetSizer (vbox)self.SetAutoLayout (True)vbox.Fit (self)

self.fg.start ()

Note that panel’s parent is the frame object we create just now, meaning this panel is a subcom-ponent of the frame. The frame places the panel inside itself using a wx.BoxSizer, vbox. The basicidea behind a box sizer is that windows will most often be laid out in rather simple basic geometry,typically in a row or a column or nested hierarchies of either. A wx.BoxSizer will lay out its itemsin a simple row or column, depending on the orientation parameter passed to the constructor. Inour example, vbox = wx.BoxSizer(wx.VERTICAL) tells the constructor all the items will be placedvertically. The SetSizer() call tells the frame which sizer to use. The call to SetAutoLayout() tells

Page 113: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

5

the frame to use the sizer to position and size your components. And finally, the call to sizer.Fit()tells the sizer to calculate the initial size and position for all its elements. If you are using sizers, thisis the normal process you would go through to set up your window or frame’s contents before it isdisplayed for the first time. The most important and useful method for a sizer is add(), it appendsan item to the sizer. Its syntax looks like:

Add(self, item, proportion=0, flag=0)

‘item’ is what you wish to append to the sizer, usually a wx.Window object. It can also be a childsizer. proportion is related to whether a child of a sizer can change its size in the main orientation ofthe wx.BoxSizer. There are several flags defined in wx, and they are used to determine how the sizeritems behave and the border of the window. wx.EXPAND used in our example means the item will beexpanded to fill the space allotted to the item. Refer to this page for a complete description.

Have you ever had this confusion: we define a ‘big’ class wfm_rcv_graph, but where do we use it?why do we never create an instance of this class? The secret is revealed in stdpanel.__init__().The instance of wfm_rcv_graph is created here and the flow graph is started.

class stdpanel (wx.Panel):def __init__ (self, parent, frame, flow_graph_maker):

......vbox = wx.BoxSizer (wx.VERTICAL)self.fg = flow_graph_maker (frame, self, vbox, sys.argv)self.SetSizer (vbox)self.SetAutoLayout (True)vbox.Fit (self)self.fg.start ()

We put a panel in the frame, but what do we put in the panel? We first create a new sizervbox for the panel. Note that this vbox is different from the one defined in stdframe. Then wecreate an instance of flow_graph_maker (wfm_rcv_graph) with vbox as an argument passed to it(also with frame and the panel itself). In wfm_rcv_graph.__init__(), this vbox will append severalspectrum analyzers or oscillograph (wx.Window objects) to the sizer by using vbox.Add(). Then thepanel uses the sizer vbox position and size all these child-windows. Finally, we start the flow graph:self.fg.start(), the corresponding data would be displayed on the screen dynamically.

Let’s go back to the code of our FM receiver example.

if 1:pre_demod, fft_win1 = \

fftsink.make_fft_sink_c (self, panel, "Pre-Demodulation",512, quad_rate)

self.connect (src, pre_demod)vbox.Add (fft_win1, 1, wx.EXPAND)

and the definition of the make_fft_sink_c() method:

/site-packages/gnuradio/wxgui/fftsink.py...def make_fft_sink_c(fg, parent, title, fft_size, input_rate, ymin=0, ymax=100):

block = fft_sink_c(fg, parent, title=title, fft_size=fft_size,sample_rate=input_rate, y_per_div=(ymax - ymin)/8, ref_level=ymax)

return (block, block.win)

Everything is much clearer now, right? panel is passed to make_fft_sink_c() as the ‘parent’ ofthis fft sink (block.win, a wx.Window object). The return value of block.win is saved in fft_win1and then appended to vbox.

Page 114: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

6

make_fft_sink_c() takes seven parameters. fft_size is the number of samples used to performFFT. input_rate is the sample frequency. ymin and ymax give the vertical range of the plot you wishto display on the screen.

Note that there is a complicated story behind the class fft_sink_c. We didn’t talk about how fastFourier transform is performed and how it is used as a block, but focusing on its interface to Pythonand wxPython. In fact, another Python package called ‘Numeric’ helps a lot here. However, we don’tneed to know all the details. Understanding how it interacts with wxPython and other blocks at thePython level would be sufficient.

2.3 The ‘Oscillograph’- scope sink

Another important GUI tool in GNU Radio is the ‘soft oscillograph’ - scope_sink. It’s not used inour example, but it would be very helpful if you wish to see the waveforms in the time domain. Itsusage is quite similar to the fft_sink:

if 1:scope_input, scope_win1 = \

scopesink.make_scope_sink_f (self, panel, "Title", self.fs)self.connect (signal, scope_input)vbox.Add (scope_win1, 1, wx.EXPAND)

Note that here signal should be a real float signal. If you wish to display a complex signal withI/Q channels, make_scope_sink_c() is the right choice. Copy these lines wherever you think a scopeshould appear, then connect it to the signal as a block. Refer to /site-packages/gnuradio/wxgui/scopesink.pyfor more details.

3 Handling command line arguments

Python fully supports creating programs that can be run on the command line, complete withcommand-line arguments and either short- or long- style flags to specify various options. Remem-ber when we create an instance of wfm_rcv_graph in stdpanel.__init__(), we use:

self.fg = flow_graph_maker (frame, self, vbox, sys.argv)

Each command line argument passed to the program will be saved in sys.argv, which is just a ‘list’. Inthis list, sys.argv[0] is just the command itself (wfm_rcv_gui.py in our example). So actually all thearguments are saved in sys.argv[1:]. That explains why we use IF_freq = parseargs(argv[1:])to process the arguments.

You may want to use short- or long- style flags to add various options like ‘-v’, or ‘--help’. Thenthe optparse module is exactly what you would like to use. optparse is a powerful and flexiblecommand line interpreter. You may see this page to study it. Another example, located at

gnuradio-examples/python/usrp/fsk_r(t)x.py

gives a very good demonstration on how to use this parser.

4 conclusion

This tutorial completes our discussion on the FM receiver example. We mainly talk about howwxPython plays its role in GNU Radio. It might be a little bit involved to understand how those

Page 115: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

7

classes are organized together, but it won’t be that difficult if we are patient enough. Besides, thegood news is we can simple use those codes as templates, without worrying too much about theimplementation details.

References

[1] Python on-line tutorials, http://www.python.org/doc/current/tut/

[2] Python Library Reference - optparse,http://www.python.org/doc/2.3/lib/module-optparse.html

[3] wxPython on-line tutorials, http://wxpython.org/tutorial.php

[4] wxPython wiki, Getting started, http://wiki.wxpython.org/index.cgi/Getting 20Started

Page 116: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

APPENDIX H

Libraries and Modules in GNU radio package:

Inside the site-packages:

gnuradio

blks:

__init__.py This file is required to make Python treat the

directories as packages

blksimpl:

am_demod.py AM demodulation block

dbpsk.py Differential BPSK modulation and demodulation

dqpsk.py Differential QPSK modulation and demodulation

filterbank.py Include both synthesis and analysis

fm_demod.py Generalized FM demodulation block

fm_emph.py FM deemphasis and preemphasis IIR filter

gmsk.py GMSK modulator and demodulator

__init__.py nothing

nbfm_rx.py Narrow band FM receiver

nbfm_tx.py Narrow band FM transmitter

pkt.py mod/demod with packets as i/o (sending packets

and demodulating/deframing packets)

psk.py define different kinds of PSK (BPSK, QPSK,

8PSK)

rational_resampler.py Rational resampling polyphase FIR filter

standard_squelch.py Implement the squelch function

wfm_rev.py Demodulating a broadcast FM signal

wfm_rcv_pll.py Demodulating a broadcast FM signal with stereo

Page 117: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

wfm_tx.py Wide band FM Transmitter

gr

Basic_flow_graph.py Constructs the basic graph and provides basic

operations on the graph

(base class of “flow_graph”)

exceptions.py Exception handling (not finished yet)

flow_graph.py Define the type of flow graph and play an key role

in scheduling the signal control

gnuradio_swig_python.py Automatically created by SWIG

gr_threading.py Choose load gr_threading_23.py or

gr_threading_24.py

gr_threading_23.py Threading module for version 2.3

gr_threading_24.py Threading module for version 2.4

hier_block.py Construct hierarchical blocks for graph (many

non-implemented modules)

__init__.py

Prefs.py

scheduler.py Schedule the threads

gru:

__init__.py

gruimpl:

crc.py CRC generator

Freqz.py Compute frequency response of a digital filter

given the numerator (b) and denominator (a)

gnuplot_freqz.py Plot the frequency response by using gnuplot

hexint.py Convert unsigned masks into signed ints

__init__.py

listmisc.py Return a copy of input ‘x’ that is reverse order

Page 118: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

lmx2306.py Control National IMX2306 (specific hardware)

based frequency synthesizer

mathmisc.py Some math functions (Gcd, Lcm, Log2)

os_read_exactly.py Replace os.read that blocks until it reads exactly

nbytes.

sdr__1000.py Control the DDS(direct digital synthesizer) on the

SDR-1000 (specific hardware)

seq_with_cursor.py

socket_stuff.py Set up socket for TCP/UDP connections

pager:

aypabtu.py Mostly same as usrp_flex.py

flex_demod.py FLEX pager protocol demodulation block

__init__.py

pager_swig.py Automatically created by SWIG

Usrp_flex.py This is an example to demonstrates receiving and

demodulating the FLEX pager protocol

vocoder:

gsm_full_rate.py Automatically created by SWIG

__init__.py Not implemented yet

wxgui:

ftsink.py FFT sink test application

form.py wxgui form demo (Editbox, Int/Float check)

__init__.py

plot.py Demonstrate the drawing function

powermate.py Handler for Griffin PowerMate, Contour

ShuttlePro & ShuttleXpress USB knobs

ra_fftsink.py FFT sink test application

Page 119: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

ra_stripchartsink.py

ra_waterfallsink.py

scopesink.py O’Scope Test Application

slider.py Demonstrate how to control slider

stdgui.py A simple wx gui for GNU Radio application

waterfallsink.py Waterfall sink test application

atsc.py: Automatically created by SWIG

audio.py: Generic audio or soundcard interface

audio_alsa.py: Automatically created by SWIG

audio_oss.py: Automatically created by SWIG

db_base.py: Abstract base class for all daughterboards. This defines

the required operations and interfaces for all d'boards.

db_ = daughterboard

db_basic.py: Handler for basic Tx daughterboards, Basic Rx

daughterboards, Low Freq Rx daughterboards, Low Freq Tx

daughterboards.

db_dbs_rx.py: Control DBS receiver based USRP daughterboard.

db_flexrf: Functions for all flexrf boards.

db_flexrf_mimo.py: Mimo classes for all flexrf boards.

db_instantiator.py: Instantiate for accessing daughterboard

db_tv_rx.py: Control Microtune 4937 based USRP daughterboard

ecc.py: Automatically created by SWIG

eng_notation.py: Change engineering notation (E.g., 5e-9 -> 5n)

eng_option.py: Add support for engineering notation

flexrf_debug_gui.py: Debug GUI for ‘Flexrf’

gr_unittest.py: Add support for unittest

__init__.py:

local_calibrator.py: NO LONGER USED

modulation_utils.py: Miscellaneous utilities for managing modulations

and demodulations

optfir.py: Routines for designing optimal FIR filters

packet_utils.py: Utilities for packet handling

Page 120: UWA M.E Project Report - Implementation of a Software FM Receiver using GNU Radio (Reduced)

ra.py: Automatically created by SWIG

trellis.py: Automatically created by SWIG

tx_debug_gui.py: Debug tool for ‘Tx’

usrp.py: Basic configuration for USRP

usrpl.py: Automatically created by SWIG

usrp_multi.py: Multiple-source handling for USRP

video_sdl.py: Automatically created by SWIG

window.py: Routines for designing window functions

__init__.py:

usrp_dbid.py: Defines USRP daughterboard ID

usrp_fpga_regs.py: Copy everything that starts with FR_ or bmFR_ from

the usrp_prims name space into our name space

usrp_prims.py: Automatically created by SWIG


Recommended