Build your own Software Defined Radio (SDR)

This project describes the construction of a Software Defined Radio (SDR).
The descriptions starts from the signal received from the antenna, continues with a simple mixer for down conversion, the read in into an ADC and the demodulation in GNU Radio of a received FM signal.

The schematic block diagram of the hardware part from the antenna up to the FPGA looks the following:

It can be seen that the received signal from the antenna is amplified by a Mini Circuits ERA-3SM+ MMIC amplifier. The amplified signal goes next into a SA612A mixer from NXP, where it is mixed with a signal from the Raspberry Pi PLL. This is doing a up/down conversion. Next comes another amplification step using the ERA-3SM+ amplifier. Since we are only interested in the down converted part of the mixed signal a low pass filter is used to select the signal.
A low pass filter which has in practice 1-2 MHz cutoff frequency is used. A OpAmp is used to lift the filtered signal to a level which the ADC can sample. The ADC has a 1Vpp Analog Input Range. The ADC samples the filtered and amplified signal and communicates it to the FPGA. The FPGA is read out by a computer running GNU Radio for further processing.

The whole setup looks the following. All blocks are connected by Coax-cables.

The Mini Circuits ERA-3SM+ MMIC amplifier

The ERA-3SM+ amplifier is used in the setup two times. The first time directly after the antenna in order to amplify the received signal from the antenna before it is passed to the mixer. The second time directly after the mixer in order to get again some more voltage before running through the low pass filter. The ERA-3SM+ is a MMIC (Monolithic Microwave Integrated Circuit) amplifier with an amplification range from DC to 3 GHz and a gain >20 dB. It is produced by Mini Circuits and has good availability on EBAY. One nice thing with this amplifier is that it does not need many external components which makes it very simple to use. The above drawing shows the use of the ERA-3SM+ on a 5 V supply. Detailed specifications can be found in the datasheet [3].

The NXP SA612A mixer

The SA612A mixer is a very popular double balanced mixer with an input frequency range up to 500 MHz. It can be used for many things and is used in this setup for the down conversion of the received signal. Also this IC can be used without the need of too many external components.
The input and output ports have an impedance of 1.5 kOhm which gives in double balanced mode 3 kOhm, which means that the 50 Ohm input should be transformed to 3 kOhm using a transformer for best power transfer. At the time of writing I have only coupled the input and output with a capacitor, which is not optimal and has a lot of power loss, but I don’t have a transformer available at the moment. But it works and does it’s job as a proof of concept. In principle one should match the input and output impedance with a 1:7.7 transformer.
In terms of mixing the input signal can be mixed with a signal from a local oscillator or by directly driving the mixer from an external signal generator. The later is done in this setup using a PLL signal from a Raspberry Pi.

Using a Raspberry Pi as a PLL for the Mixer
The Raspberry Pi is a very nice small computer when playing with electronics. In particular the GPIO port is very useful. So also in this project. The Raspberry Pi has a clock out on GPIO Pin 4. This clock out can be driven by a PLL which can be locked at frequency from 0.13 to 250 MHz. The reason why I don’t use the PLL from the FPGA which would go even higher is that the PLL in the Raspberry Pi is much easier to configure.

With the program from Jan Panteltje [1] one is able to simply set the Raspberry Pi PLL frequency on the terminal. This is very convenient.

The oscillator input on the NXP SA612A mixer should have a level of 200-300 mV. The Raspberry Pi GPIO pins are driven by 3.3V logic levels. This means that one needs a level shifter from the 3.3V logic to the 200-300mV input level of the mixer.
I simply used two resistor voltage divider, with 19k Ohm and 1.9k Ohm. This does the job.

3.3V -> 19k -> Mixer -> 1.9k -> GND

It should be kept in mind that the PLL of the Raspberry Pi produces square waves, and not only a sine wave. This means that one additionally gets multiples of the set output frequency!

The Low pass filter

A low pass filter in front of the ADC is needed in order to avoid aliasing and to remove frequencies above half the sampling rate. This filter is called an anti-aliasing filter, and is essential for a practical ADC system that is applied to analog signals with higher frequency content.

The signal which is feed into the low pass filter comes directly from the mixer and has a wide spectrum of frequencies, much higher than the Nyquist frequency which need to be removed.

A Chebyshev 5th-order low pass filter was designed for the filtering.

LTSpice from Linear Technology [2] was used for the simulation of the filter.

The ADC OpAmp driver

After the low pass filter we are left with a filtered signal, the down converted signal. This signal needs to be amplified again in order to have voltage swings big enough for the ADC to detect. The ADCs input voltage range is 1Vpp. So one should come close to this span in order to use as much resolution of the ADC as possible. To drive the ADC a Microchip MCP660 OpAmp is used. This OpAmp has a Gain Bandwidth Product of 60 MHz and a sufficient good noise figure. The package of this IC used on the SDR setup contains three amplifiers which are used as a three stage driver. A potentiometer is connected on one of the OpAmps in the IC in order to be able to adjust the gain in case of drive voltage gets above the 1Vpp.

The received signal in GNU Radio

After all steps of receiving, mixing, amplification and sampling with the ADC, the received signal is passed from the FPGA into the computer for further processing. GNU Radio is used for the further signal processing. To test the functionality in this example I was listening to FM Radio. In the above FFT two local stations here in Uppsala/Sweden can bee seen [4].

Mix Megapol @ 105,3 MHz
RIX FM @ 106,5 MHz

The stations are received by mixing their received signal from the antenna with a 104 MHz signal from the PLL. This makes the two radio signals appear after mixing and low pass filtering at:

105,3 -> 1.3 MHz
106,5 -> 2.5 MHz

This is where they are also found the the FFT. This down converted signals are received in the FTDI read source block (see GNU Radio flow graph).
From there they are converted to complex data type and throttled to 10M samples, the used clock speed for the ADC. At this stage the FFT spectrum is shown. In order to select the exact desired frequency the signal is mixed in software again with a sine wave. The sine wave can be frequency changed in order to tune in the right frequency. If mixing with 1.3 MHz one receives the Mix Megapol station.

For further selection the signal is passed through a low pass filter in software which is also doing a decimation by a factor of 20. This reduces the sample rate from 10 M samples to 500 k samples. Reducing the amount of CPU power needed for processing. The next step is the demodulation of the FM signal. This is done with the WBFM receive block. The output from this block is the audio signal at a too high sample rate for the sound card. Therefore another decimation is done, down to 48 kHz. This signal is passed to the sound card and the sound from the radio channel can be heard.