|
|
(8 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| = Tutorial: Using GNU Radio with Hardware =
| | <!-- "Using GNU Radio with Hardware" --> |
| | | <!-- 16 May 2020 --> |
| == Objectives ==
| |
| | |
| * How GNU Radio helps bridge Simulation and the Real World
| |
| * What can you do and what are you allowed to do?<br />
| |
| | |
| == Prerequisites ==
| |
| | |
| * General familiarity with C++ and Python
| |
| * Radio/RF knowledge
| |
| ** [[SuggestedReading|Our Suggested Reading]] list
| |
| ** The ARRL Handbook
| |
| * Previous tutorials recommended:
| |
| ** [[Guided_Tutorial_Introduction|A brief introduction to GNU Radio, SDR, and DSP]]
| |
| ** [[Guided_Tutorial_GRC|Intro to GR usage- GRC and flowgraphs]]
| |
| * If looking to follow the QPSK example
| |
| ** [[Guided_Tutorial_GNU_Radio_in_Python|Programming GR in Python]]
| |
| ** [[Guided_Tutorial_GNU_Radio_in_C++|Programming GR in C++]]
| |
| | |
| | |
| ----- | |
| | |
| == Introduction == | | == Introduction == |
|
| |
|
| So far, all of the tutorials in this series have centered around using GNU Radio as a prototyping & development platform through simulation. One of the great strengths of GNU Radio, though, is how easy it is to move from simulation to real-world operation. In this tutorial, we will build on what you have learned so far and create real-world transmitters and receivers.
| | One of the more basic (and also incredibly useful) things you can do in GNU Radio with a receiver is to create a software radio spectrum analyzer. This is also a great first step because it will verify that your hardware has basic functionality. |
| | |
| In this tutorial, we will take your previous QPSK design and turn it into an actual transmitter. We will also build, from-scratch, a complete FM radio receiver that you can use to listen to your local FM radio stations. Along the way, we will discuss a number of considerations that come into play when working with real-world radio hardware.
| |
| | |
| == Simulation vs The Real World ==
| |
| | |
| Moving from simulation to real-world operation also brings a host of new challenges to solve. Radio and RF engineering are very complex disciplines, and there is a lot to consider when building an actual radio system. Along with the challenges of designing the theory of your communications system, you now also need to deal with impairments from your radio hardware, issues introduced by your physical medium (i.e., your wireless or wire channel), synchronization design, etc.,
| |
| | |
| To learn more about real-world radio impairments, a great place to start is the ~45 minute tutorial that Matt Ettus teaches at conferences occasionally. You can find a video of it, here: [https://www.youtube.com/watch?v=wqKNUXDdIvU YouTube: Practical Software Radio]
| |
| | |
| If you want to learn more about radio impairments directly in GNU Radio, check out the hardware impairments models in [https://github.com/gnuradio/gnuradio/tree/master/gr-channels/grc /gr-channels/grc.]
| |
|
| |
|
| == What Will I Need? == | | == What Will I Need? == |
|
| |
|
| If you don't have an actual radio to work with, this tutorial is still useful. The first section (transmitting) will teach you the basics of interfacing with hardware. For the second section, you can simply use a recording from an actual radio, with nothing done to the data. We have provided a recording, which you can find [https://github.com/gnuradio/gr-tutorial/blob/master/examples/tutorial6/fm_101.8MHz_1Msps.cfile in the gr-tutorials repository]. You can use this in your flowgraph to simulate hardware passing you samples.
| | There is a large and growing number of SDRs that have GNU Radio support. They span from very cheap ($20) receivers like the RTL-SDR to very high-performance tens-of-thousands-of-dollars systems. Examples of four popular devices are presented below. Other devices are listed in [[Hardware]]. |
| | |
| This tutorial will be most useful, though, if you have a piece of radio hardware that you can use with GNU Radio. There is a large and growing number of vendors that provide hardware with GNU Radio drivers, and they span from very cheap $20 receivers to very high-performance tens-of-thousands-of-dollars sort of systems.
| |
| | |
| The entirety of this tutorial is possible with a simple, low-bandwidth, half-duplex radio. Most of the tutorial is possible if you have a radio that can only receive, assuming it can tune to the FM bands. Most countries allot between ~87 MHz and ~108 MHz to FM broadcast radio, with some slight variations on the floor and ceiling of the range.
| |
| | |
| == Legal Considerations ==
| |
| | |
| In this tutorial, we will be transmitting a signal, but you should directly connect your transmit antenna port to a spectrum analyzer or some other test equipment. If you do not directly wire your radio to a receiving device, you will be emitting over-the-air. If you do not have any sort of load attached to your transmit antenna, and you accidentally transmit with too much power, you risk high-power reflections damaging your radio hardware. In general, you should err on the side of caution and put an attenuator in your signal path before directly connecting any cables to antenna inputs on any hardware.
| |
| | |
| You are responsible for complying with the relevant laws in your country / state of operation. Not transmitting is the only guaranteed way to stay legal. Transmitting directly to an analyzer is another great option. If you do not have an analyzer, I recommend simply reading through the transmit section, but not actually executing the flowgraph.
| |
| | |
| == Using UHD Blocks ==
| |
| | |
| The author is using an [http://b200.ettus.com Ettus Research USRP B200], which uses the [https://github.com/EttusResearch/uhd USRP Hardware Driver (UHD)]. Thus, the hardware sources & sinks used in this tutorial will be [https://github.com/gnuradio/gnuradio/tree/master/gr-uhd/grc gr-uhd] blocks.
| |
| | |
| If you are using a different piece of hardware, you should use the blocks suggested by your hardware vendor. Another set of popular HW blocks, for example, is [http://sdr.osmocom.org/trac/wiki/GrOsmoSDR gr-osmosdr].
| |
| | |
| In order to use UHD blocks, you must have UHD installed. There are a number of ways to install UHD, which you can read about [http://code.ettus.com/redmine/ettus/projects/uhd/wiki here]. If you built GNU Radio from source, you should have seen '''gr-uhd''' in the list of components being built in the CMake output. If GNU Radio successfully found your UHD installation, you should see a group of UHD blocks in the GNU Radio Companion:
| |
| | |
| [[File:grc_uhd_blocks.png|250px|]]
| |
| | |
| == Building a QPSK Transmitter ==
| |
| | |
| {|
| |
| | Please read the '''Legal Considerations''' section, above, before starting this section. You are solely responsible for your actions over-the-air.
| |
| |}
| |
| | |
| === Picking Up QPSK Again ===
| |
| | |
| We will start by hacking on the QPSK flowgraph that you made in [[Guided_Tutorial_GNU_Radio_in_Python|the Python programming tutorial]]. In that tutorial, you demodulated a QPSK signal and saved it to a file. Here, instead of demodulating the signal, we are going to transmit the QPSK signal you were generating.
| |
| | |
| Let's start by removing your demodulator and file sink, but leave the QT Constellation Sink. This should leave you with a flowgraph that looks something like this:
| |
| | |
| [[File:qpsk_tutorial_4.png|600px|]]
| |
| | |
| You can also just [https://raw.githubusercontent.com/gnuradio/gr-tutorial/master/examples/tutorial6/gr-tutorial-qpsk-tx.grc download the flowgraph pictured above to get rolling]
| |
| | |
| If you execute that flowgraph, you should be looking at the symbol constellation for your QPSK signal (with some simulated noise).
| |
| | |
| [[File:qpsk_simulated.png|600px|]]<br />
| |
| | |
| | |
| === Moving from Simulation to Real TX ===
| |
| | |
| Now, let's move from simulation to actually transmitting! First, connect your transmit antenna to your spectrum analyzer (if you intend to actually transmit).
| |
| | |
| Since we are no longer simulating a signal, let's get rid of that noise source and the adder. Because we have an actual hardware source providing rate control, we no longer require the throttle block. In fact, keeping the throttle block in the flowgraph might actually impede its performance by conflicting with the rate of the UHD device (for more on this, read this note in the [[FAQ#When-do-I-use-a-throttle-block]]).
| |
| | |
| Changing our program from being a simulation to an operational software radio is now as easy as dropping a new ''sink'' block into your flowgraph. Find the 'UHD Sink' block, add it to your flowgraph, and connect it to your modulator's output.
| |
| | |
| === Configuring the UHD Sink Parameters ===
| |
| | |
| It is generally a good idea to create variable blocks for parameters you may tweak down the road. Let's go ahead and make a few for our radio parameters. Copy & paste your ''samp_rate'' variable block twice, and create variables for ''freq'' and ''gain''. Set ''freq'' and ''gain'' to something that your hardware supports. I chose 2.421 GHz for the center frequency. Set your gain to something in the lower range of your device. I set mine to 30 dB, which is 1/3 of the available TX gain in my device.
| |
| | |
| Now, let's use our new variable blocks as actual transmit parameters in the UHD sink. Open up the properties for the UHD sink block (double-click on it, or right click and then click 'Properties'), and you should see a property window come up with a list of parameters to tweak. There are a lot more properties here than we need to touch. Scroll down to the bottom of the list. Set-up the following properties accordingly:
| |
| | |
| * '''Samp Rate (Sps):''' samp_rate
| |
| * '''Ch0: Center Freq (Hz:''' freq
| |
| * '''Ch0: Gain (dB):''' gain
| |
| * '''Ch0: Antenna:''' "TX/RX"
| |
| * '''Ch0: Bandwidth (Hz):''' samp_rate
| |
| | |
| A very important aspect to keep in mind is that a value of 1.0 going into the UHD sink will saturate the digital-to-analog converter completely. Any value larger than 1 will cause '''clipping''', which means the amplitude is 'clipped off' above of 1.0. In general, you want to back off from 1.0. In this example, we'll simply multiply the output of the multiplier by 0.5 to make sure we are definitely in the right amplitude range.
| |
| | |
| At this point, your flowgraph is ready to run! It should look like this:
| |
| | |
| [[File:qpsk_tx_uhd_constsink.png|600px|]]
| |
| | |
| If you have had trouble following the instructions above, [https://raw.githubusercontent.com/gnuradio/gr-tutorial/master/examples/tutorial6/gr-tutorial-qpsk-tx-uhd.grc download the flowgraph here and compare it to your own]
| |
| | |
| === A Working Software Radio Transmitter ===
| |
| | |
| If you execute your flowgraph, you should see the usual initialization and GUI launch - except, instead of everything being simulation, you are actually transmitting your QPSK signal. Because we have our TX signal going to both the 'QT Constellation Sink' and 'UHD Sink', we can look at the symbol constellation as GNU Radio sees it, and the constellation as the analyzer sees it (if your analyzer has a QPSK demod function).
| |
| | |
| If we look at just the spectrum on the analyzer, you should be able to clearly see your signal at the frequency you selected. If you can't see it, double-check your parameters, and also try turning up your radio gain.
| |
| | |
| [[File:qpsk_tx_specan.jpg|600px|]]
| |
| | |
| Congratulations! You have built a complete QPSK software radio transmitter!
| |
| | |
| == Building an FM Radio Receiver ==
| |
| | |
| In this section, we will build a working FM radio receiver that you can use to listen to your local FM broadcast stations. This content is based on the tutorial slide series prepared by Balint Seeber, available here: [http://files.ettus.com/tutorials/ files.ettus.com/tutorials]
| |
| | |
| === Creating a Software Radio Spectrum Analyzer ===
| |
| | |
| One of the more basic (but also incredibly useful) things you can do in GNU Radio with a receiver is simply plot a real-time FFT of what your receiver sees. It's a software radio spectrum analyzer. This is also a great first step because it will verify that your hardware is working correctly, and we can use it to identify broadcast stations in your area that we will tune to later on.
| |
| | |
| Create a new flowgraph. Drop a 'UHD: USRP Source' and 'QT GUI Sink' into the canvas. In the previous section, we used static variables for frequency and gain. Here, let's make them changeable on-the-fly. Find the 'QT GUI Range', and add two of them to your flowgraph. Open each of them, and fill out the following fields as appropriate for your hardware. Mine are filled out, below, to match the capabilities of the USRP B200:
| |
| | |
| '''''QT GUI Range 1:'''''
| |
| | |
| * '''ID:''' freq
| |
| * '''Label:''' freq
| |
| * '''Default Value:''' 1e9
| |
| * '''Start:''' 70e6
| |
| * '''Stop:''' 6e9
| |
| * '''Step:''' 10e6
| |
| | |
| '''''QT GUI Range 2:'''''
| |
| | |
| * '''ID:''' gain
| |
| * '''Label:''' gain
| |
| * '''Default Value:''' 0
| |
| * '''Start:''' 0
| |
| * '''Stop:''' 74
| |
| * '''Step:''' 1
| |
| | |
| Change your 'samp_rate' variable block value to something interesting. I set mine to 32 MSps. Now, open up the properties for the 'UHD: USRP Source'. Just as we used our variable blocks in the previous section for our radio parameters, we will do the same here. Use the 'ID's from the 'range blocks', above, to set the 'UHD Source' parameters:
| |
| | |
| * '''Samp Rate (Sps):''' samp_rate
| |
| * '''Ch0: Center Freq (Hz):''' freq
| |
| * '''Ch0: Gain (dB):''' gain
| |
| * '''Ch0: Antenna:''' "TX/RX"
| |
| * '''Ch0: Bandwidth (Hz):''' samp_rate
| |
| | |
| When you are done, your flowgraph should look something like this:
| |
| | |
| [[File:simple_spec_an.png|500px|]]
| |
| | |
| You can also [https://raw.githubusercontent.com/gnuradio/gr-tutorial/master/examples/tutorial6/gr-tutorial-simple-spec-an.grc download this flowgraph if you want the reference file].
| |
| | |
| You should be all set!
| |
| | |
| === Using Your Software Radio Spectrum Analyzer ===
| |
| | |
| Go ahead and run your flowgraph. You should see your received spectrum in real-time. Play with the sliders and values, and you should see everything update in real-time, as well. The default GNU Radio QT FFT sink has a number of useful features, such as averaging and peak-hold. Take some time to get familiar with them, now.
| |
| | |
| === Building a Broadcast FM Receiver ===
| |
| | |
| Now that you have a basic receiver application running with a real-time display of your received data, let's build a useful application! Leave your current flowgraph in place. We will simply add more functionality into the flowgraph rather than replacing what is already there.
| |
| | |
| First, as you might have guessed, we will need to add a few more blocks to the flowgraph. Locate and add the following blocks:
| |
| | |
| * 1x Rational Resampler
| |
| * 1x WBFM Receiver
| |
| * 1x Audio Sink
| |
| * 2x Variable
| |
| | |
| Our flow of data will be the USRP Source -> Rational Resampler -> WBFM Receiver --> Audio Sink. Go ahead and connect the blocks together in that order. GNU Radio will likely highlight a lot of fields in red, indicating errors. We will now go through and configure the parameters, which will resolve these.
| |
| | |
| First, let's set-up those two new variable blocks you added. Create the following two variables with them:
| |
| | |
| '''''Variable:'''''
| |
| | |
| * '''ID:''' audio_interp
| |
| * '''Value:''' 4
| |
| | |
| '''''Variable:'''''
| |
| | |
| * '''ID:''' audio_rate
| |
| * '''Value:''' 48e3
| |
| | |
| Let's also go back and tune our sample rate variable, which we had previously. Change that variable to '''250e3''' (250 kHz).
| |
| | |
| '''''Variable:''''' samp_rate
| |
| | |
| * '''ID:''' samp_rate
| |
| * '''Value:''' 250e3
| |
| | |
| Now, let's configure your other three new blocks.
| |
| | |
| '''''Audio Sink'''''<br />
| |
| This block is fairly straight-forward. It takes a stream of samples and plays them through your speakers. This block is installed with the ''gr-audio'' library, which is part of the core GNU Radio distribution. There are a few common / default rates that sound cards use - one of the most common is 48 kHz, which is what we will use, here (hence your configuration of the 'audio_rate' variable, above).
| |
| | |
| Open up the parameters of the Audio Sink. Make the following changes:
| |
| | |
| * '''Sample Rate:''' audio_rate
| |
| * '''OK to Block:''' "No"
| |
| | |
| Now, we just need to turn the samples from your hardware into something that you can play through your speakers! Let's go two blocks back up the chain, next.
| |
| | |
| '''''Rational Resampler'''''<br />
| |
| The USRP Source is streaming at a rate of 'samp_rate', which we just set to 250e3. The Audio Sink is configured for a sample (consumption) rate of 'audio rate', which is 48e3. But, we have a problem: our source sample rate isn't an integer multiple of the audio rate: 250000 / 48000 = 5.208. To fix this problem, we will 'resample' the stream. Think of resampling here as impedance-matching. We have to convert from the rate of the input stream to the rate of the output stream.
| |
| | |
| The rational resampler block allows you to adjust the rate of a data stream. It does this by interpolating or decimating to achieve a desired sample rate. Open up the properties of this block, and let's tune the parameters.
| |
| | |
| Set the 'Type' to 'Complex->Complex', thus telling the block to use complex taps. Now we need to tune the actual rates. There is some intelligence built into this block - if we give it the different non-divisable sample rates, the code will calculate the GCD and make it all 'just work' for us. We know the incoming rate is 250 kSps, so let's enter that into 'Decimation'. But, this parameter must be an integer, and our 'samp_rate' is a float. Thus, we need to use the Python function 'int()' to convert it.
| |
| | |
| Now we need to set the 'Interpolation' rate. There is a 'gotcha' here, because the WBFM block further down our chain will actually perform an additional decimation-by-four, so we need to actually tell this block to output a rate four times what we want. We know what we actually want is 'audio_rate', so use your 'audio_interp' variable to set the actual rate.
| |
| | |
| At this point, you should have made these settings:
| |
| | |
| * '''Type:''' Complex->Complex (Complex Taps)
| |
| * '''Interpolation:''' audio_rate * audio_interp
| |
| * '''Decimation:''' int(samp_rate)
| |
|
| |
|
| By leaving the 'Taps' parameter blank, we tell the block that we want it to compute the taps automatically. The 'Fractional BW' parameter affects the shape of the low-pass filter that is generated when no filter taps are supplied. By leaving this set to zero, we will just use a reasonable default.
| | == Creating a Software Radio Spectrum Analyzer == |
|
| |
|
| '''Note:''' Depending on the accuracy of the clock references in your hardware, you may need to tune the ''Interpolation'' field, above. This is one of the many hardware impairments that you may need to deal with. When I first ran this flowgraph, I heard a lot of noise. I then tuned that ''Interpolation'' rate, and it cleaned up. My final numbers were:
| | This example uses an [[USRP Source]] block, so it should work for almost all USRP SDRs, such as the [https://kb.ettus.com/B200/B210/B200mini/B205mini USRP B series] which have a continuous frequency coverage from 70 MHz to 6 GHz and a maximum sample rate of 56 MHz. |
|
| |
|
| * '''Interpolation:''' int(1.05 * (audio_rate * audio_interp))
| | In order to use UHD blocks, you must have UHD installed, although most methods of installing GNU Radio come with UHD. See [https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux Installing the USRP] for more info. |
| * '''Decimation:''' int(samp_rate)
| |
|
| |
|
| Now, let's configure our last block!
| | Using gnuradio-companion (GRC), build the following flowgraph.<br> |
|
| |
|
| '''''WBFM Receiver'''''<br />
| | [[File:HW_tutorial_fg.png]] |
| At this point, configuring our last block is pretty simple. Open up the block's parameters. There are only two parameters to set: the rate of incoming samples, and the decimation rate. Well, we know both of these. We just configured the output rate of the rational resampler, and we know that rate divided-by-four equals our 'audio_rate'. Thus, you want:
| |
|
| |
|
| * '''Quadrature Rate:''' audio_rate * audo_interp
| | === Setting Parameters === |
| * '''Audio Decimation:''' audio_interp
| |
|
| |
|
| === A Working Software Radio Broadcast FM Receiver ===
| | The USRP Source parameters are set as shown below. |
|
| |
|
| And that should be it! You should now no longer see any red in your flowgraph, and you should be able to build your flowgraph without errors. The final result should look like this:
| | Note that we want the Automatic Gain Control (AGC) to be disabled, because we will be browsing spectrum that often will be empty, and it's tough to tell when a signal is present or not when the AGC is constantly adjusting the gain so that the received samples are always at a constant level. You can think of AGC like something automatically adjusting the volume knob. AGC being enabled is better suited for applications when you know a signal exists on the frequency you are tuned to. |
|
| |
|
| [[File:broadcast_fm_rx_flowgraph.png|600px|]] | | [[File:HW_tutorial_p1.png|400px]] [[File:HW_tutorial_p2.png|400px]] |
|
| |
|
| You can also [https://raw.githubusercontent.com/gnuradio/gr-tutorial/master/examples/tutorial6/gr-tutorial-broadcast-fm-rx.grc download this flowgraph, for reference].
| | === Tuning and Using the Spectrum Analyzer === |
|
| |
|
| Executing your flowgraph should bring up a GUI that looks something like what you see below. Changing the frequency and tuning to a local broadcast FM station should play the demodulated radio through your computer speakers.
| | Set the following parameters in the [[QT_GUI_Sink|QT GUI Sink block]]: |
| | * Center Frequency (Hz): tuning |
| | * Bandwidth (Hz): samp_rate |
| | * Show RF Freq: Yes |
| | * Show Msg Ports: True |
|
| |
|
| | The analyzer can be tuned with the Frequency control widget. If you check the "Display RF Frequencies" box in the run-time GUI window, then the scale on the 'Frequency Display' and 'Waterfall Display' tabs will show the actual frequencies with the tuned frequency in the center. Keep in mind that the IQ samples coming from the SDR are at baseband, i.e. at 0 Hz, the signal was down-converted to baseband before it was sampled by the Analog to Digital Converter (ADC). |
|
| |
|
| [[File:broadcast_fm_running.png|600px|]]<br />
| | With the message output of the QT GUI Sink block (freq) connected to the message input (command) of the USRP Source, you can double click the display on the Frequency or Waterfall screens and it also will tune to the selected frequency. This is useful for centering on a signal. Before you click, the frequency will be displayed with the cursor. |
|
| |
|
| == Conclusion ==
| | You can adjust the Sample Rate to see more or less spectrum at a time (because these SDRs use quadrature sampling, the amount of bandwidth we see at once is equal to the sample rate). This trace shows four FM stations. |
|
| |
|
| Congratulations! You have successfully built real-word transmitter and receiver software radios using GNU Radio! While these applications were relatively simple, they do demonstrate the flexibility and power that GNU Radio provides when it comes to interfacing directly with hardware. It also demonstrated how easy it is to move an application from simulation to real-world operation.
| | [[File:HW_tutorial_freq.png|800px]] |
|
| |
|
| == Quiz == | | == Hardware Considerations == |
|
| |
|
| 1. Given a radio source that streams data at 1 Msps to an audio device working at 32 kHz, what are the interpolation and decimation values required by the rational_resampler to resample the incoming data stream?
| | Setting the sample rate involves several factors to consider. |
| | * The various hardware devices have limits on what sample rates they can deliver. Some, such as the FunCube Pro+, have a fixed sample rate of 192kHz. Setting the flowgraph sample rate must be within the limitations of the device. |
| | * The computer hardware and operating system you are using will set limitations on the data throughput, such as: |
| | ** USB2 vs USB3 |
| | ** processor speed |
| | ** number of CPU cores |
| | * If you are using a USRP, data overruns are indicated by the letter 'O' displayed on the terminal screen. These are because the input data stream is producing data faster than the computer can consume it, so it could be due to a USB bottleneck, or the flowgraph is trying to do too much with those samples, or the CPU is not powerful enough, etc. Adjusting the sample rate and/or the input buffer size (where available) may alleviate the problem. |
|
| |
|
| 2. What if the audio device was at 44.1 kHz? Are there reasonable interpolation and decimation integers to satisfy this resampling? How could you use the [http://gnuradio.org/doc/doxygen/classgr_1_1filter_1_1kernel_1_1pfb__arb__resampler__ccf.html PFB arbitrary resampler] instead?
| | == Building an FM Receiver == |
|
| |
|
| | Now that you have a tested input device, you can build an FM Receiver with it. See the following flowgraphs. |
|
| |
|
| ----- | | * [[:File:USRP FM fg.png|USRP FM Receiver flowgraph]] |
| | * [[:File:Pluto FM fg.png|PlutoSDR FM Receiver flowgraph]] |
| | * [[:File:Broadcast FM fg.png|FunCubePro+ FM Receiver flowgraph]] |
| | * [[:File:RTLSDR receive fg.png|RTL-SDR FM Receiver flowgraph]] |
|
| |
|
| [[Category:Guided Tutorials]] | | For audio considerations, see [[Audio_Sink]]. |