Home > Agriculture > USRP in Python — PySDR: A Guide to SDR and DSP ...

USRP in Python — PySDR: A Guide to SDR and DSP ...

Author: Shirley

Oct. 21, 2024

23 0

Tags: Agriculture

USRP in Python — PySDR: A Guide to SDR and DSP ...

In this chapter we learn how to use the UHD Python API to control and receive/transmit signals with a USRP which is a series of SDRs made by Ettus Research (now part of NI). We will discuss transmitting and receiving on the USRP in Python, and dive into USRP-specific topics including stream arguments, subdevices, channels, 10 MHz and PPS synchronization.

Read more

If you used the standard from-source install, the following command should benchmark the receive rate of your USRP using the Python API. If using 56e6 caused many dropped samples or overruns, try lowering the number. Dropped samples aren&#;t necessarily going to ruin anything, but it&#;s a good way to test the inefficiencies that might come with using a VM or older computer, for example. If using a B 2X0, a fairly modern computer with a USB 3.0 port running properly should manage to do 56 MHz without dropped samples, especially with num_recv_frames set so high.

For more help see Ettus&#; official Building and Installing UHD from source page. Note that there are also methods of installing the drivers that don&#;t require building from source.

For USB type USRPs you&#;ll need to install VM guest additions. Within the VM go to Devices > Insert Guest Additions CD > hit run when a box pops up. Follow the instructions. Restart the VM, then attempt to forward the USRP to the VM, assuming it shows up in the list under Devices > USB. The shared clipboard can be enabled through Devices > Shared Clipboard > Bidirectional.

Under system > processor > choose at least 3 CPUs. If you have an actual video card then in display > video memory > choose something much higher.

Start the VM. It will ask you for installation media. Choose the Ubuntu 22 desktop .iso file. Choose &#;install Ubuntu&#;, use default options, and a pop up will warn you about the changes you are about to make. Hit continue. Choose name/password and then wait for the VM to finish initializing. After finishing the VM will restart, but you should power off the VM after the restart.

Create the virtual hard disk, choose VDI, and dynamically allocate size. 15 GB should be enough. If you want to be really safe you can use more.

While the Python code provided in this textbook should work under Windows, Mac, and Linux, we will only be providing driver/API install instructions specific to Ubuntu 22 (although the instructions below should work on most Debian-based distributions). We will start by creating an Ubuntu 22 VirtualBox VM; feel free to skip the VM portion if you already have your OS ready to go. Alternatively, if you&#;re on Windows 11, Windows Subsystem for Linux (WSL) using Ubuntu 22 tends to run fairly well and supports graphics out-of-the-box.

Receiving samples off a USRP is extremely easy using the built-in convenience function &#;recv_num_samps()&#;, below is Python code that tunes the USRP to 100 MHz, using a sample rate of 1 MHz, and grabs 10,000 samples off the USRP, using a receive gain of 50 dB:

import

uhd

usrp

=

uhd

.

usrp

.

MultiUSRP

()

samples

=

usrp

.

recv_num_samps

(

,

100e6

,

1e6

,

[

0

],

50

)

# units: N, Hz, Hz, list of channel IDs, dB

print

(

samples

[

0

:

10

])

The [0] is telling the USRP to use its first input port, and only receive one channel worth of samples (for a B210 to receive on two channels at once, for example, you could use [0, 1]).

Here&#;s a tip if you are trying to receive at a high rate but are getting overflows (O&#;s are showing up in your console). Instead of usrp = uhd.usrp.MultiUSRP(), use:

usrp

=

uhd

.

usrp

.

MultiUSRP

(

"num_recv_frames="

)

which makes the receive buffer much larger (the default value is 32), helping to reduce overflows. The actual size of the buffer in bytes depends on the USRP and type of connection, but simply setting num_recv_frames to a value much higher than 32 tends to help.

For more serious applications I recommend not using the convenience function recv_num_samps(), because it hides some of the interesting behavior going on under the hood, and there is some set up that happens each call that we might only want to do once at the beginning, e.g., if we want to receive samples indefinitely. The following code has the same functionality as recv_num_samps(), in fact it&#;s almost exactly what gets called when you use the convenience function, but now we have the option to modify the behavior:

import

uhd

import

numpy

as

np

usrp

=

uhd

.

usrp

.

MultiUSRP

()

num_samps

=

# number of samples received

center_freq

=

100e6

# Hz

sample_rate

=

1e6

# Hz

gain

=

50

# dB

usrp

.

set_rx_rate

(

sample_rate

,

0

)

usrp

.

set_rx_freq

(

uhd

.

libpyuhd

.

types

.

tune_request

(

center_freq

),

0

)

usrp

.

set_rx_gain

(

gain

,

0

)

# Set up the stream and receive buffer

st_args

=

uhd

.

usrp

.

StreamArgs

(

"fc32"

,

"sc16"

)

st_args

.

channels

=

[

0

]

metadata

=

uhd

.

types

.

RXMetadata

()

streamer

=

usrp

.

get_rx_stream

(

st_args

)

recv_buffer

=

np

.

zeros

((

1

,

),

dtype

If you want to learn more, please visit our website Highmesh.

Additional reading:
Sodium Ion Battery vs. Lithium Ion Battery
What is FSK insulation facing?
How to Choose What Is The Process of Lost Foam or Expandable Pattern Casting?

=

np

.

complex64

)

# Start Stream

stream_cmd

=

uhd

.

types

.

StreamCMD

(

uhd

.

types

.

StreamMode

.

start_cont

)

stream_cmd

.

stream_now

=

True

streamer

.

issue_stream_cmd

(

stream_cmd

)

# Receive Samples

samples

=

np

.

zeros

(

num_samps

,

dtype

=

np

.

complex64

)

for

i

in

range

(

num_samps

//

):

streamer

.

recv

(

recv_buffer

,

metadata

)

samples

[

i

*

:(

i

+

1

)

*

]

=

recv_buffer

[

0

]

# Stop Stream

stream_cmd

=

uhd

.

types

.

StreamCMD

(

uhd

.

types

.

StreamMode

.

stop_cont

)

streamer

.

issue_stream_cmd

(

stream_cmd

)

print

(

len

(

samples

))

print

(

samples

[

0

:

10

])

With num_samps set to 10,000 and the recv_buffer set to , the for loop will run 10 times, i.e., there will be 10 calls to streamer.recv. Note that we hard-coded recv_buffer to but you can find the maximum allowed value using streamer.get_max_num_samps(), which is often around -something. Also note that recv_buffer must be 2d because the same API is used when receiving multiple channels at once, but in our case we just received one channel, so recv_buffer[0] gave us the 1D array of samples that we wanted. You don&#;t need to understand too much about how the stream starts/stops for now, but know that there are other options besides &#;continuous&#; mode, such as receiving a specific number of samples and having the stream stop automatically. Although we don&#;t process metadata in this example code, it contains any errors that occur, among other things, which you can check by looking at metadata.error_code at each iteration of the loop, if desired (errors tend to also show up in the console itself, as a result of UHD, so don&#;t feel like you have to check for them within your Python code).

Receive Gain¶

The following list shows the gain range of the different USRPs, they all go from 0 dB to the number specified below. Note that this is not dBm, it&#;s essentially dBm combined with some unknown offset because these are not calibrated devices.

  • B200/B210/B200-mini: 76 dB

  • X310/N210 with WBX/SBX/UBX: 31.5 dB

  • X310 with TwinRX: 93 dB

  • E310/E312: 76 dB

  • N320/N321: 60 dB

You can also use the command uhd_usrp_probe in a terminal and in the RX Frontend section it will mention the gain range.

When specifying the gain, you can use the normal set_rx_gain() function which takes in the gain value in dB, but you can also use set_normalized_rx_gain() which takes in a value from 0 to 1 and automatically converts it to the range of the USRP you&#;re using. This is convenient when making an app that supports different models of USRP. The downside of using normalized gain is that you no longer have your units in dB, so if you want to increase your gain by 10 dB, for example, you now have to calculate the amount.

Automatic Gain Control¶

Some USRPs, including the B200 and E310 series, support automatic gain control (AGC) which will automatically adjust the receive gain in response to the received signal level, in an attempt to best &#;fill&#; the ADC&#;s bits. AGC can be turned on using:

usrp

.

set_rx_agc

(

True

,

0

)

# 0 for channel 0, i.e. the first channel of the USRP

If you have a USRP that does not implement an AGC, an exception will be thrown when running the line above. With AGC on, setting the gain won&#;t do anything.

Stream Arguments¶

In the full example above you&#;ll see the line st_args = uhd.usrp.StreamArgs("fc32", "sc16"). The first argument is the CPU data format, which is the data type of the samples once they are on your host computer. UHD supports the following CPU data types when using the Python API:

Stream Arg

Numpy Data Type

Description

fc64

np.complex128

Complex-valued double-precision data

fc32

np.complex64

Complex-valued single-precision data

You might see other options in documentation for the UHD C++ API, but these were never implemented within the Python API, at least at the time of this writing.

The second argument is the &#;over-the-wire&#; data format, i.e. the data type as the samples are sent over USB/Ethernet/SFP to the host. For the Python API, the options are: &#;sc16&#;, &#;sc12&#;, and &#;sc8&#;, with the 12 bit option only supported by certain USRPs. This choice is important because the connection between the USRP and host computer is often the bottleneck, so by switching from 16 bits to 8 bits you might achieve a higher rate. Also remember that many USRPs have ADCs limited to 12 or 14 bits, using &#;sc16&#; doesn&#;t mean the ADC is 16 bits.

For the channel portion of the st_args, see the Subdevice and Channels subsection below.

What a Difference 10 Years Makes

By NI | September 14,

10 Years of GNU Radio Conference

is the 10th annual GNU Radio Conference. What a great 10 years! NI and Ettus Research have been a major supporter of this community event since its inception.

We are also proud to celebrate 10 years since NI acquired Ettus Research. The acquisition kicked off a revolution of SDR products, hacking, and wireless application enthusiasm together.

A History to Be Proud Of

The past 10 years has delivered many advancements and milestones in open-source SDR hardware, software, and systems. The USRP started as a project in Matt Ettus&#;s garage back in , and it has now become a well-known name known in the SDR community. At GRCon , we gave away the last of the original USRP1 devices. The USRP has evolved since then into the N-Series, X-Series, and E-Series devices which have advanced capabilities. It is amazing to see all the great ways the USRP is being used to define our wireless future.

In , the USRP X310 was a major technology component of the DARPA SC2 Colosseum System which turned SDR and wireless into a spectator sport showing a bright future of wireless and AI.

256 USRP X310s used in DARPA SC2 (the largest channel emulator ever built)

The USRP has been heavily adopted into many defense applications and drone defense is notably a popular one where the USRP is helping to protect commercial space launches as well as soldiers on the battlefield.

USRP X310 used for drone defense by SkySafe

The great things you are building with the USRP keep us passionate about building better technology to enable you. The best is yet to come&#;we are hard at work building the next generation of wireless devices to enable even more advanced wireless applications.

A History of Ettus Research SDR

There is one constant in the universe&#; change&#;

You may have noticed a visual change to the company previously known as &#;National Instruments&#;. Before this year, &#;NI&#; was a nickname for &#;National Instruments&#; and now it is officially the company name. The global nature of our business deems &#;National&#; inaccurate, and &#;Instruments&#; is no longer a holistic representation of what we offer&#;our Ettus Research branded SDR products are a great example of this fact. We are happy to see NI and Ettus Research names both in green this year at the GNU Radio Conference.

Over the past 3 years, NI has evolved and so has our Ettus Research SDR product line. This technology continues to be an area of development in our Aerospace and Defense industry focus as well as for wireless researchers and commercial application developers.

While NI has a new look, the same name Ettus Research is alive and well and we are excited to connect at GNU Radio Conference this year.

Let&#;s Connect Digitally in

This year, we are proud to contribute to the great body of technical content at GNU Radio conference with:

  • 4 technical presentations
  • 2 FPGA workshops
  • 5 SDR demos.

To learn more about the great sessions visit: https://www.ettus.com/event/grcon/

Reach out to Haydn Nelson, , and we&#;ll set you up with one of our SDR experts to talk about how we can help you with your wireless application.

Reach out to Sales at .

Are you interested in learning more about USRP N Series? Contact us today to secure an expert consultation!

Comments

0