RoadTest: Digilent 1x1 USB Software-Defined Radio Platform
Author: avnrdf
Creation date:
Evaluation Type: Test Equipment
Did you receive all parts the manufacturer stated would be included in the package?: True
What other parts do you consider comparable to this product?: LimeSDR, bladeRF, ADALM-Pluto
What were the biggest problems encountered?: USB 3.0 interface dropping samples at moderate-high sample rates
Detailed Review:
I'd like to start by thanking the element14 community & Digilent for giving me an opportunity to test out the Ettus USRP B205mini-i: 1x1 70MHz-6GHz SDR/Cognitive Radio.
The USRP B205mini-i is a credit-card sized software-defined radio that supports a frequency range of 70 MHz to 6 GHz and has a USB 3.0 interface for streaming of data to and from the the host computer. It has transmit and receive capabilities and uses an industrial-grade Xilinx Spartan-6 FPGA, Analog Devices AD9364 RF Transceiver and a Cypress Semi FX3 USB 3.0 controller.
In the recent years SDRs have been getting more popular and accessible to hobbyists, and we now have a plethora of devices to choose from - right from $20 to more than $2000 (or even $20000)!
I've used SDRs with the AD936x series of RF transceivers in the past, but this is the first model I've used that has a USB 3.0 interface. Most entry level SDRs tend to use converters with limited sampling rates and bandwidths, and even devices with converters that are capable of moderate-high sample rates tend to be bottlenecked by the USB 2.0 interface. The B205 has a USB 3.0 interface, so I spent a lot of time measuring the transfer rates on different systems to see what sampling rates the B205's USB 3.0 interface can handle.
Packaging, Unit & Accessories
I received an element14 cardboard box which had a NI-branded (National Instruments) cardboard box inside it protected well with packing paper.
The NI box is very simple, and inside it was an ESD bag containing the USRP, a USB 3.0 cable and some leaflets. The ESD bag had another cardboard box inside it, which had the USRP board in it protected well with foam.
{gallery} Unboxing |
---|
NI box |
Inside the NI box: SDR in the ESD bag, some documents and a USB 3.0 cable |
Box containing the SDR |
B205 inside the black box |
Accessories like cable kits or the enclosure kit which includes an aluminum case, feet, screws can be purchased from the Ettus website.
Product Overview & First Impressions
Ettus Research (acquired by National Instruments in 2010) is well known for its URSP (Universal Software Radio Peripheral) brand of software-defined radios. The USRP range of SDRs covers a wide range of devices: the entry-level, compact devices like the B205mini which sell for <$1000, as well as significantly more complex devices that cost thousands of dollars.
UHD (USRP Hardware Driver) is a common set of software that allows users to interact with the hardware - it takes care of the low-level details like loading bitstreams and packetizing data on the USB, Network or PCIe interfaces and exposes a simple set of C++ & Python APIs for developers to use. A relatively new feature is the RFNoC (RF Network-on-Chip) - a framework that allows DSP functions (that would normally occur in software as a GNURadio block) to be implemented in the FPGA fabric - which offloads a lot of the intensive processing to the hardware. We won't be looking the RFNoC in this review, but I will be taking a look at the URSP B205mini-i and UHD.
Highlights from the Marketing Material
The product page of the USRP B205mini-i has a nice summary:
Here's an excerpt from the datasheet:
Competing Products
I won't go into the details, but I've added a high-level comparison of the B205 to other popular SDRs on the market. The comparison might not be very fair since most of these cost less than half of what the B205 does, but I think the target audience of Ettus products tends to be a little different - I've seen these systems used in more formal (non-hobbyist) COTS system that can be integrated into other systems (like a rocket in this case: https://twitter.com/FccSpace/status/1390156877795930113 ) where things like the extended temperature range are a premium worth paying for.
There is a comprehensive comparison table on the GNU Radio Wiki: https://wiki.gnuradio.org/index.php/Hardware, but I've added a concise summary:
HackRF | RTL-SDR | ADALM-Pluto | Lime SDR Mini | bladeRF 2.0 micro xA4 THERMAL | Ettus B205 | |
---|---|---|---|---|---|---|
RF Chipset(s) | MAX2837 + MAX5864 | R820T | AD9363 | LMS7002M | AD9361 | AD9364 |
Frequency | 1 MHz to 6 GHz | 24 MHz to 1.7 GHz | 325 MHz to 3.8 Ghz (unlockable) | 10 MHz - 3.5 GHz | 47MHz - 6GHz | 70 MHz - 6 GHz |
Operation | Tx/Rx - Half-duplex | Rx | Tx/Rx - Full-duplex | Tx/Rx - Full-duplex | 2x Tx/Rx - Full-duplex | Tx/Rx - Full-duplex |
Sampling Rate & Resolution | 20 MSPS, 8-bit. | Upto 3.2MSPS, 8-bit | Upto 61.44 MSPS, 12-bit. Streams at around 8 MSPS | 30.72MSPS, 12-bit | Upto 61.44 MSPS, 12-bit. | Upto 61.44 MSPS, 12-bit. Stream rate >20MSPS, host-dependent. |
Interface Chipset | NXP LPC43xx + CPLD | RTL2832U | Zynq-7000 (2x CA9 + FPGA) DDR3 RAM | Intel MAX10 | Altera Cyclone V + Cypress FX3 | Cypress FX3 |
Interface | USB 2.0 | USB 2.0 | USB 2.0 | USB 3.0 | USB 3.0 | USB 3.0 |
Price | $400 | Around $20 | $149 | $159 | $1025 | $846 |
The B205 uses a similar platform as the significantly cheaper ADALM-Pluto, but uses a Spartan-6 instead of the Zynq-7000. It also has a faster USB 3.0 interface. The price difference does seem like a lot, but when the B205 is compared to the bladeRF with an extended temperature range, the gap seems a lot smaller. The bladeRF is $200 more expensive, but unlocks the second set of the Rx/Tx channels on the AD936x, has a more capable FPGA/SoC.
Other USRPs
The B-series (Bus) that the B205mini-i is Ettus' entry-level range of SDRs. There are a few differences between the different B-series products, but the AD936x, Spartan-6 and FX3 controller are common to all.
The E (Embedded) series is slotted in above the B series, and these use the AD9361 (2x2 RF TRx) and a Zynq-7000 SoC. These come with 1/10 GbE connectivity, DDR3 RAM and a GPS receiver.
The N (Networked) series comes with more channels, wider bandwidth, a larger FPGA etc.
And finally, the X series comes with slots for daugherboards, PCIe and significantly larger FPGAs.
Documentation
I'm happy to say that there is no shortage of documentation - both Digilent & Ettus have pages of documentation. The Digilent reference page has a few examples, but for more details you will need to refer to the comprehensive documentation on the Ettus website.
Ettus even publishes a RF test report which contains Rx & Tx characteristics like NF, output power etc across all frequencies and gain settings: https://kb.ettus.com/images/a/ae/B200mini_B205_RF_Performance_Data_20160119.pdf
The B205-mini is well documented, but I find that information on the Ettus sites is scattered and a little hard to find - there's information in the knowledgebase, application notes, doxygen documentation as well as the examples.
Luckily, Digilent did a very good job of adding a list of almost all the relevant links to the USRP B205mini-i reference page, and since I'm reviewing the Digilent B205 today, I will count this as well documented!
Getting Started & Setup
Setting up the hardware
The B205mini- is very easy to set up: all you need to do is connect an antenna and use the included USB 3.0 cable to connect the USRP to a computer.
It shows up as a USB device but doesn't contain the actual firmware/bitstream that's needed at runtime, so UHD will load the firmware/bitstream the first time it connects to a device.
All of this is done automatically, so there's nothing much that users need to do.
Installing drivers, software and tools
Ettus hosts a user manual at https://files.ettus.com/manual/index.html
UHD (USRP Hardware Driver) is available can be built from source, but I decided to use the binary installers. I installed UHD on Windows 10 and Ubuntu based systems , and the installation process was straightforward. The USB driver for the B205 isn't bundled with UHD and needs to be downloaded separately.
UHD includes:
I will go into more depth in a later section.
Hardware Overview
Teardown
Well, this part was easy. I was shipped a 'board-only' version without the case, which meant that there was nothing to teardown - you're greeted by the internals of the B205mini-i as soon as soon as you open the box!
The build quality seems to be very good - the PCB, silkscreen, soldering etc. are spot on and even the quality of the cap plugs and stickers is some of the best I have seen.
The top of the PCB has most of the components and there are a few passives of the back.
That being said, I'll need to figure out a way to build a case for the B205. The industrial-grade enclosures are quite expensive (and frankly, overkill for general use), and there doesn't seem to be a cheaper option. While the build quality is very good, there are a lot of delicate components on the board that might be damaged in the course of general use. Something else that I'd be worried about is the USB 3.0 port - while the legs seem to be soldered well into the PCB's mounting holes, the port doesn't have much support and might come off the PCB.
Moving on to an analysis of the components on the board:
Left to Right: The SMA connectors, Analog Devices AD9364, Xilinx Spartan-6, Cypress FX3 FIFO-USB 3.0 interface. There's also the PA below the AD9364, and the VCTXO is below the FPGA. The USB port is on the right and the header at the top has GPIO/JTAG.
{gallery} B205MINI-I Board Pictures |
---|
Front: All the main components |
Back: Nothing much |
Ettus Research has published the schematic of the USRP B205mini-i as a PDF. It also includes a very convenient block diagram (below) which offers a high-level overview of the main components and makes it easy to figure out how the whole thing comes together.
Starting on the left:
The Ettus knowledgebase has a list of the main components on the board. Here's a more detailed take:
Software Overview
Tools included in UHD
The utilities and tools that I explore in this section are precompiled binaries that come with the UHD installer. Using the tools is straightforward - just open up the terminal and invoke the executable with the required arguments.
On Windows I did see a couple of errors when I tried running them at first and the fix involved moving uhd.dll to a different folder and downloading the the libusb.dll.
Utilities
UHD includes a tool "uhd_find_devices" which can be used to discover connected USRPs. UHD will scan the system for supported devices and prints out all devices it discovers.
C:\Program Files\UHD\lib\uhd\examples>uhd_find_devices [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [INFO] [B200] Loading firmware image: C:\Program Files\UHD\share\uhd\images\usrp_b200_fw.hex... -------------------------------------------------- -- UHD Device 0 -------------------------------------------------- Device Address: serial: 3xxxxxx name: B205i product: B205mini type: b200
Another executable "uhd_usrp_probe" can be used to print out more detailed information:
C:\Program Files\UHD\lib\uhd\examples>uhd_usrp_probe [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [INFO] [B200] Detected Device: B205mini [INFO] [B200] Loading FPGA image: C:\Program Files\UHD\share\uhd\images\usrp_b205mini_fpga.bin... [INFO] [B200] Operating over USB 3. [INFO] [B200] Initialize CODEC control... [INFO] [B200] Initialize Radio control... [INFO] [B200] Performing register loopback test... [INFO] [B200] Register loopback test passed [INFO] [B200] Setting master clock rate selection to 'automatic'. [INFO] [B200] Asking for clock rate 16.000000 MHz... [INFO] [B200] Actually got clock rate 16.000000 MHz. _____________________________________________________ / | Device: B-Series Device | _____________________________________________________ | / | | Mboard: B205mini | | revision: 3 | | product: 30522 | | name: B205i | | serial: 3xxxxxx | | FW Version: 8.0 | | FPGA Version: 7.0 | | | | Time sources: none, internal, external | | Clock sources: internal, external | | Sensors: ref_locked | | _____________________________________________________ | | / | | | RX DSP: 0 | | | | | | Freq range: -8.000 to 8.000 MHz | | _____________________________________________________ | | / | | | RX Dboard: A | | | _____________________________________________________ | | | / | | | | RX Frontend: A | | | | Name: FE-RX1 | | | | Antennas: TX/RX, RX2 | | | | Sensors: temp, rssi, lo_locked | | | | Freq range: 50.000 to 6000.000 MHz | | | | Gain range PGA: 0.0 to 76.0 step 1.0 dB | | | | Bandwidth range: 200000.0 to 56000000.0 step 0.0 Hz | | | | Connection Type: IQ | | | | Uses LO offset: No | | | _____________________________________________________ | | | / | | | | RX Codec: A | | | | Name: B205mini RX dual ADC | | | | Gain Elements: None | | _____________________________________________________ | | / | | | TX DSP: 0 | | | | | | Freq range: -8.000 to 8.000 MHz | | _____________________________________________________ | | / | | | TX Dboard: A | | | _____________________________________________________ | | | / | | | | TX Frontend: A | | | | Name: FE-TX1 | | | | Antennas: TX/RX | | | | Sensors: temp, lo_locked | | | | Freq range: 50.000 to 6000.000 MHz | | | | Gain range PGA: 0.0 to 89.8 step 0.3 dB | | | | Bandwidth range: 200000.0 to 56000000.0 step 0.0 Hz | | | | Connection Type: IQ | | | | Uses LO offset: No | | | _____________________________________________________ | | | / | | | | TX Codec: A | | | | Name: B205mini TX dual DAC | | | | Gain Elements: None
"usrp_list_sensors" returns the status of the Rx & Tx LOs, temperatures and received RSSI.
C:\Program Files\UHD\lib\uhd\examples>usrp_list_sensors.exe Creating the USRP device with: [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [INFO] [B200] Detected Device: B205mini [INFO] [B200] Operating over USB 3. [INFO] [B200] Initialize CODEC control... [INFO] [B200] Initialize Radio control... [INFO] [B200] Performing register loopback test... [INFO] [B200] Register loopback test passed [INFO] [B200] Setting master clock rate selection to 'automatic'. [INFO] [B200] Asking for clock rate 16.000000 MHz... [INFO] [B200] Actually got clock rate 16.000000 MHz. Device contains 1 motherboard(s). _____________________________________________________ / | Sensors for motherboard 0: | | * Ref: unlocked | _____________________________________________________ | / | | RX Sensors: | | | | Chan 0: | | * temp: 47.777779 C | | * RSSI: -50.750000 dB | | * LO: locked | | _____________________________________________________ | / | | TX Sensors: | | | | Chan 0: | | * temp: 47.485382 C | | * LO: | | * LO: lockedlocked
Performance profiling/benchmarking tools
Latency tester:
C:\Program Files\UHD\lib\uhd\examples>latency_test.exe [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [INFO] [B200] Detected Device: B205mini [INFO] [B200] Operating over USB 3. [INFO] [B200] Initialize CODEC control... [INFO] [B200] Initialize Radio control... [INFO] [B200] Performing register loopback test... [INFO] [B200] Register loopback test passed [INFO] [B200] Setting master clock rate selection to 'automatic'. [INFO] [B200] Asking for clock rate 16.000000 MHz... [INFO] [B200] Actually got clock rate 16.000000 MHz. [INFO] [B200] Asking for clock rate 25.000000 MHz... [INFO] [B200] Actually got clock rate 25.000000 MHz. Actual TX Rate: 25.000000 Msps... Actual RX Rate: 25.000000 Msps... .L.L.L.L.L..L...L.L.L.L.L.L.L..L.L...L..L.L..L.L.L..L...L.L.L.L.L.L....L.....L.L.L..L.L.L.L.L.L...L..L.L.L.L.L.L...L.L.L.L...L.L..L.L.L..L.L.L.L.L.L.L.L.L.L...L.L.L.L..L.L.L..L.L..L..L..L..L.L.L....L.L.L.L.L.L.L.L..L....L.L....L.L.L.L.L.L.L.L..L.L..L.L...L.L..L.L.L.L....L.L.L..L.L.L.L.L.L.L.L..L....L.L.L.L.L.L..L.L.L.L.L.L.L.L.L.L....L.L.L.....L.L.L.L.L.L..L.L.L..L....L........L..L.L..L.L...L...L.L.L.L...L.L.L.L.L.L.L..L.L..L......L.L.L..L.L.L.L.L.L.L.L.L..L....L...L.L....L.L.L...L..L.L.L.L.L..L....L....L.......L.L.L..L..L.L.L.L...L...L.L.L.L.L..L...L.L.L.L..L....L.L.L.L..L.L..L.L.L.L.L.L....L.L.L.L.....L.L.L.L.L.L..L.L.L.L.L.L..L.L.L.L..L......L........L..L.L.L.L.L....L.L..L.L.L..L..L.L.L.L.L.L...L...L.L..L.L..L.L.L.L.L..L..L.L..L.L...L.L...L.....L.L.L.L.L.L..L.L..L.L.L..L.L..L.L.L.L....L.......L...L.L.....L..L..L.L..L.L.L...L..L.L.L.L.L...L.L.L.L.L.L..L...L.L.L..L....L..L.L.L.L.L.L..L.L.L.L.L.L..L.L.L.L.L.L.L.L.L..L.L.L..L.L....L.L........L.L..L.L.L..L.L.L.L.L...L.L..L.L..L.L...L.L.L.L.L.L..L...L.L.L.L.L...L.L.L.L.L.L.L.L.L..L.L.L.L.L.L..L.L.L.L.L...L...L.L.L.L.L.L..L.L.....L.L...L..L.L.L.L..L.L.L.L.L.L.L...L.L.L.L..L.L..L..L.L.L.L.L..L.L.L.L...L.L.....L.L...L...L.L.L.L.L...L.L.L.L.L.L..L.L.L.L...L.L.L..L.L.L.L.L...L....L......L.L.L.L..L....L.L.L.L...L.L.L.L..L..L...L.L.L.L..L..L.L..L.L....L.L.L...L.L.L..L.L.L.L.L.L.L.L.L..L.L.L.L..L...L.L.L.L.L..L.L..L.L.L....L.L.......L....L..L.L.L.L.L.L.L.L.L.L.L.L....L....L.L.L.L...L.L...L.L..L.L.L..L..L.L.L..L.L.L.....L.L..L.L.L.L.L.L..L..L.L.L.L.L.L.L.L.L.....L.....L...L..L.L.L.L.L.L..L.L.L.L.L.L..L.L.L.L.L.L.L.L.L..L.L.L..L...L.L..L.L.L.L.L...L..L.L.L.L..L.L.L Summary ================ Number of runs: 1000 RTT value tested: 1 ms ACKs received: 371/1000 Underruns: 0 Late packets: 629 Other errors: 0
Transfer rate benchmark:
C:\Program Files\UHD\lib\uhd\examples>benchmark_rate --duration 10 --rx_otw sc8 --rx_rate 32e6 [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [00:00:00] Creating the usrp device with: ... [INFO] [B200] Detected Device: B205mini [INFO] [B200] Operating over USB 3. [INFO] [B200] Initialize CODEC control... [INFO] [B200] Initialize Radio control... [INFO] [B200] Performing register loopback test... [INFO] [B200] Register loopback test passed [INFO] [B200] Setting master clock rate selection to 'automatic'. [INFO] [B200] Asking for clock rate 16.000000 MHz... [INFO] [B200] Actually got clock rate 16.000000 MHz. Using Device: Single USRP: Device: B-Series Device Mboard 0: B205mini RX Channel: 0 RX DSP: 0 RX Dboard: A RX Subdev: FE-RX1 TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: FE-TX1 [00:00:03.674287] Setting device timestamp to 0... [INFO] [B200] Asking for clock rate 32.000000 MHz... [INFO] [B200] Actually got clock rate 32.000000 MHz. [00:00:04.145604] Testing receive rate 32.000000 Msps on 1 channels O[00:00:05.130458] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:06.163601] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:07.101864] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:07.202120] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:07.202120] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:08.229281] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:08.241538] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:09.268167] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:10.305596] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:11.338659] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:11.338659] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:11.353672] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:12.161520] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:12.375947] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:13.418160] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) O[00:00:13.431127] Timestamp after overrun recovery ahead of error timestamp! Unable to calculate number of dropped samples.(Delta: -2176 ticks) [00:00:14.200005] Benchmark complete. Benchmark rate summary: Num received samples: 316056845 Num dropped samples: 16 Num overruns detected: 16 Num transmitted samples: 0 Num sequence errors (Tx): 0 Num sequence errors (Rx): 0 Num underruns detected: 0 Num late commands: 0 Num timeouts (Tx): 0 Num timeouts (Rx): 0 Done!
I spent a lot of time playing around with the transfer rate benchmark, and ran it on 4 different systems (2 desktops, 1 ultrabook and 1 laptop) and different operating systems (Windows 10 and Ubuntu). All 4 systems are what I would consider fast, and I even kept a watch on the CPU utilization and throttling behavior.
3 of the 4 systems couldn't stream samples reliably at 32 MSPS - there were occasional drops, and reducing the sampling rate a little lower usually helped. One system managed to stream samples at 37 MSPS, but would drop samples at higher rates. This tests doesn't write samples to the disk, so that eliminates the disk write speed from the equation - though all systems had high-speed SSDs.
Something else that I noticed was that UHD 4.0 (the latest release) performed noticeably worse that UHD 3.15. I installed UHD 4.0 on all systems because it was the latest release, but the B205 would drop samples at low rates. I tried out UHD 3.15 on one system and when I noticed that it worked better, I installed 3.15 on all 4 systems. All testing used UHD 3.15 as a consequence.
The Ettus website claims that the B205 should be able to stream samples at the maximum rate of 61.44 MSPS over USB 3.0, but they also have a note that says that it depends on the system and the USB 3.0 controller. I tested out the B205 with 3 different Intel platforms from 3 different generations - the oldest was 8 years old and used an external USB 3.0 controller, while the other two were 2 to 3 years old and used the integrated Intel controller. These were high-performance systems with USB 3.1 Gen1, Thunderbolt etc and I have seen the USB interfaces sustain high rates during file transfers (though this is comparing apples and oranges). The last system was brand new AMD platform, and I used the USB 3.1 Gen (10 Gbps) port which is wired directly to the CPU (bypassing the chipset etc) to eliminate any bottlenecks. This system performed better, but only marginally.
None of the systems showed high CPU usage in the Windows/Linux task manager, and none of them were power/thermally limited.
I was a little disappointed that the B205 dropped samples even at rates below 40 MSPS - I was really hoping to be able to sustain >50 MSPS to enable me to capture larger portions of bands, and the USB 3.0 interface was one of the things that caught my attention on the B205. Other SDRs like the ADALM-Pluto can sample at 61.44MSPS, but cannot stream continuously above ~8 MSPS due to the USB 2.0 interface. The USB 3.0 interface on the B205 is a significant improvement in that regard, but it seems like it the performance depends on the system and effort that goes into fine-tuning the system. I plan on spending more time investigating this more.
60 MSPS seems to drop roughly the same amount of samples as 30 MSPS, so it's unlikely it's a bandwidth problem - it's more likely that the 3.0 controller/driver/UHD gets backed up every once in a while and due to the lack of buffering, the USRP drops samples.
An alternative architecture that might have helped to some extent would have been the addition of a DRAM buffer on the B205. I might be wrong, but it seems like the USB 3.0 interface has enough bandwidth for steady-state transfers even at high sampling rates but might drop samples due to intermittent hiccups - and a having a smaller buffer on the hardware might just be enough to smoothen things out.
I tried the 'otw' (over-the-wire) options included in UHD which allows users to reduce the bits used by each sample (8, 12 or 16) in order to reduce the bandwidth requirements at the cost of resolution, but these options were a hit or a miss - 'sc8' helped a little on some systems and performed better than sc12 and sc16, but had the opposite effect on the AMD system where sc16 worked but sc8/12 would cause overruns.
I must not forget to mention that even though samples are dropped, UHD is verbose and provides a means of detecting these sample drops. Some other SDRs do not have a means of detecting this, or they don't generate alerts/notifications when this occurs, making it more difficult to detect this. The protocol that the USRP uses to send data to UHD includes metadata like timestamps and start/end-of frame flags, making it easy to detect dropped samples. It upto the application to handle the drop - another transfer can be initiated, but the sample could process, or discard samples.
Examples:
While most of tools and examples are bundled as compiled executables, the source code is available and serve as examples of how the UHD APIs are to be used.
Saving received samples to a file:
C:\Program Files\UHD\lib\uhd\examples>rx_samples_to_file.exe --file "./file.dat" --skip-lo --duration 6 --rate 29e6 --wirefmt sc8 --progress --stats --sizemap --args num_recv_frames=256 Packet size tracking enabled - will only recv one packet at a time! Creating the usrp device with: num_recv_frames=256... [INFO] [UHD] Win32; Microsoft Visual C++ version 1920; Boost_107000; UHD_3.15.0.0-release [INFO] [B200] Detected Device: B205mini [INFO] [B200] Operating over USB 3. [INFO] [B200] Initialize CODEC control... [INFO] [B200] Initialize Radio control... [INFO] [B200] Performing register loopback test... [INFO] [B200] Register loopback test passed [INFO] [B200] Setting master clock rate selection to 'automatic'. [INFO] [B200] Asking for clock rate 16.000000 MHz... [INFO] [B200] Actually got clock rate 16.000000 MHz. Using Device: Single USRP: Device: B-Series Device Mboard 0: B205mini RX Channel: 0 RX DSP: 0 RX Dboard: A RX Subdev: FE-RX1 TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: FE-TX1 Setting RX Rate: 29.000000 Msps... [INFO] [B200] Asking for clock rate 29.000000 MHz... [INFO] [B200] Actually got clock rate 29.000000 MHz. Actual RX Rate: 29.000000 Msps... Setting RX Freq: 0.000000 MHz... Setting RX LO Offset: 0.000000 MHz... Actual RX Freq: 35.500000 MHz... Press Ctrl + C to stop streaming... Got an overflow indication. Please consider the following: Your write medium must sustain a rate of 116.000000MB/s. Dropped samples will not be written to the file. Please modify this example for your purposes. This message will not appear again. O 28.7049 Msps O 28.6862 Msps OOO 28.5068 Msps O 28.7146 Msps O 26.7212 Msps OO Received 169939335 samples in 6.000008 seconds 28.3232 Msps Packet size map (bytes: count) 2175: 9 4080: 41647 Done!
Even with an SSD in the system that's capable of write speed far higher than 116MB/s, samples are dropped because of the USB 3.0 interface.
Using the UHD APIs
Ettus provides a C++, C & Python APIs that allow users to interface with the hardware. Most of the examples and utilities that I looked at in the previous sections actually serve as examples of how the APIs should be used.
While UHD supports C & Python APIs, they did not seem to be in the 'binary' installers of the UHD that I used, but if you build UHD from source there are instructions on which C-Make flags need to be enabled in order to generate the C & Python APIs.
The Ettus documentation states that the APIs are similar to the primary C++ API (I believe they're wrappers), so the usage will probably be the same - barring any minor differences and performance.
Ettus has two app-notes in their knowledgebase that serve as a good starting point for using the C++ and Python APIs of UHD. However, these do not cover all functions, so users need to refer to the sources of the examples and the Doxygen documentation for more details. I was initially planning on using the Python API (Python APIs tend to be easier to work with), but since it was not included in the binary installer, I went with the C++ API.
Getting started with the UHD C++ API
I opted to use Microsoft Visual Studio because that was already installed on my PC.
I created a Win32 Console Project, and added the include paths of the UHD header, path of the UHD lib and linker includes. I had to download the Boost C++ libraries and then add those header and .lib paths to the Visual Studio Project options as well. I took me a couple of hours to download, extract, search for errors online etc - but I guess it might have had something to do with the fact that I was new to Visual Studio and was using a non-standard approach. I think that this process might be simpler if you build UHD from source since most pieces will already be in place.
I used the code in the Ettus knowledge base C++ example as a starting point and decided to explore a little after I managed that to get that to build and execute.
A closer look at the UHD C++ API
Using the UHD API doesn't require too many components:
The paths go into the project options, and you import the header files:
#include <uhd/utils/thread_priority.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> #include <uhd/exception.hpp> #include <uhd/types/tune_request.hpp> #include <boost/program_options.hpp> #include <boost/format.hpp> #include <boost/thread.hpp> #include <iostream>
Like all C++ programs, you create a main(), and declare variables etc.
int UHD_SAFE_MAIN(int argc, char *argv[]) { //Set the scheduling priority on the current thread uhd::set_thread_priority_safe();
To find connected devices, you can give UHD a 'hint' to narrow the scope of the search: an IP address, a serial number, a USRP class/model, or just leave it empty to find all connected devices.
UHD will return a vector of device addresses that contain details.
/* Find connected devices*/ uhd::device_addr_t hint; uhd::device_addrs_t device_addrs = uhd::device::find(hint); /* Print details */ if (not device_addrs.empty()) { std::cout << "Type: " << device_addrs.at(0).get("type", "") << std::endl; std::cout << "Name: " << device_addrs.at(0).get("name", "") << std::endl; std::cout << "Product: " << device_addrs.at(0).get("product", "") << std::endl; }
After this, you can connect to the USRP, which returns a device handle.
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(hint);
This handle has many get/set APIs to probe the device, read and control it:
To read back the antennas that can be used to receive and to select one, you could use this:
/* Print Rx Antennas */ std::cout << "Rx Antennas: " << std::endl; std::vector<std::string> antenna_list; antenna_list = usrp->get_rx_antennas(); for (int i = 0; i<antenna_list.size(); ++i) std::cout << antenna_list[i] << std::endl; std::cout << std::endl; /* Select an antenna */ std::string ant("TX/RX"); std::cout << boost::format("Setting RX Antenna: %s") % ant << std::endl; usrp->set_rx_antenna(ant); std::cout << boost::format("Actual RX Antenna: %s") % usrp->get_rx_antenna() << std::endl << std::endl;
The antenna corresponds to the silkscreen next to the SMA connector on the USRP, which makes it easy to map settings to the physical port - all without going through a datasheet and schematics to figure out which channel of the ADRF9364 is connected to which port via the switch network etc.
Similarly, you can set the sampling rate, gain and bandwidth:
/* Sampling rate */ double freq = 2467e6; usrp->set_rx_rate(rate); /* LO frequency */ uhd::tune_request_t tune_request(freq); usrp->set_rx_freq(tune_request); /* Rx BW */ usrp->set_rx_gain(gain);
UHD uses the concept of streams for transmitting and receiving samples:
First, you create some stream arguments that are used to get an instance of a stream from UHD. Next, you create a stream command that has type of stream, number of samples, starting time etc:
/* Set stream commands - select the otw and cpu format of the samples */ /* The cpu format is the format of the samples that will be returned in the buffer/memory: fc32 = complex float, sc16 = complex int16_t etc */ /* The otw format is the format of the samples between the host and the USRP. Using narrow widths like sc8 or sc12 instead of sc16 should reduce the bandwidth required vs sc32, but at a cost of sample SNR */ uhd::stream_args_t stream_args("sc16", "sc16"); uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
Next, I asked for 32M samples at a particular 'device time' in the future.
uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); /* Or something like STREAM_MODE_START_CONTINUOUS or STREAM_MODE_NUM_SAMPS_AND_MORE */ stream_cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0u, 0.5); stream_cmd.num_samps = 32 * 1024 * 1024; stream_cmd.stream_now = false;
Get the max. number of samples per packet, and create a buffer. Also create some variables to use as counters and a metadata variable:
size_t max_samps_per_packet = rx_stream->get_max_num_samps(); std::vector<std::complex<short>> buff(128 * 1024 * 1024); volatile size_t nSamples = 0UL; volatile size_t num_rx_samps = 0; uhd::rx_metadata_t md;
Now, we send the command that starts the capture and keep calling the streams recv() function to read back the data.
/* Start the capture */ rx_stream->issue_stream_cmd(stream_cmd); /* Keep calling trying to receive until we get all the samples we wanted */ while (nSamples < stream_cmd.num_samps) { /* Call recv() which is a blocking call. Give it the address, samples, metadata, timeout */ num_rx_samps = rx_stream->recv(&buff.front(), max_samps_per_packet, md, 1, false); nSamples += num_rx_samps; /* For now, if we get any error code, break out */ if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::cout << num_rx_samps; std::cout << md.to_pp_string(); break; } /* This is where you'd typically check for error codes like ERROR_CODE_OVERFLOW , ERROR_CODE_BAD_PACKET , ERROR_CODE_TIMEOUT etc. Also check for end of/start of burst flags, sequence, fragments, timestamps etc. */ }
After running this code, complex samples were copied to the buffer. Like some of the other examples, there were overflows at high streaming rates. Users are free to go and build applications on top of UHD - all you need to do is call a few APIs and UHD populates a buffer with I/Q samples. I planned on building a spectrum analyzer from scratch using UHD, but ran into a couple of roadblocks with GUI and haven't finished enough of it to include in this review. On the plus side, I managed to get enough of it working and covered everything that was relevant to the USRP and UHD APIs.
Using the Ettus B205mini-i
GNU Radio
2.4 GHz Wi-Fi
{gallery} Looking at 2.4 GHz Wi-Fi |
---|
GNURadio: WX FFT and Waterfall sinks displaying a 20 MHz Wi-Fi channel |
GNURadio: QT FFT sink displaying a 20 MHz Wi-Fi channel |
2.4 GHz Bluetooth
Here, I tuned to one of the Bluetooth advertising channels and enabled the search mode on a Bluetooth device.
{gallery} Attempt at capturing FSK signals in the 2.4 GHz band |
---|
GNURadio Flowgraph: USRP block, squelch (to remove noise), a LPF, quadrature demod block (converts I/Q to fdev). |
GNURadio capture: Top: Demodulated FSK. Bottom (filtered I/Q samples) |
GNURadio capture (zoomed-in): Top: Demodulated FSK (unfiltered). Bottom (filtered I/Q samples) |
50MHz of the 2.4 GHz ISM band: a 20 MHz Wi-Fi channel at 2.455 GHz and multiple Bluetooth channels at the lower frequencies |
GNURadio has all the blocks that are needed to demodulate (G)FSK signals like Bluetooth. I have experimented with flowgraphs which used the quadrature demodulator to convert I/Q into frequency deviations, timing recovery to align symbol boundaries etc, and at the end of it you get a stream of 0s and 1s which can be processed to find the sync word, address etc.
Cellular bands: 850/900 MHz
For this, I ran Speedtest and captured the spectrum during the upload test as this would have a lot of uplink activity. The red in the spectogram is uplink channel, and it disappears towards the end when the test concludes.
{gallery} Cellular Links |
---|
LTE Uplink: Activity on the LTE Uplink with Speedtest upload test running. |
900 MHz band: a mix of cellular and other frequencies |
FM Radio Receiver Example
I followed the Ettus FM radio receiver example and managed to pickup some stations (visible in the FFT), and the audio was pretty clear. I was using a 2.4 GHz antenna for this, but it worked well.
UHD was dropping samples even at 10MSPS - but that might have been because of the FFT being plotted in realtime + the audio process & playback. All 4 CPU cores were below 50% utilization.
Since the B205 has transmit capabilities, you can even try out the FM transmitter example.
Exporting Captures
In many cases, you might want to save the raw I/Q data to a file for analysis at a later point rather than analyzing it in realtime.
The GNURadio filesync or the UHD example which saves samples to a file can be used for this.
Note that due to the high sampling rates hundreds of MB are generated and written to the storage medium every second, so having a fast SSD is important. The USB 3.0 interface will bottleneck before a SATA 6G interface does, so a decent SATA SSD should work fine. I tend to use Inspectrum (by Miek) to analyze I/Q data, and in this case I think I picked up two Bluetooth packets and (probably) Wi-Fi towards the end. I was using close to the max. sampling rate (59MSPS) so while the USRP did drop samples, I think that there will be large chunks of uninterrupted data.
{gallery} Captures | |
---|---|
| |
A closer look |
Other software
USRPs are among some of the most widely supported SDRs out there. Examples of third-party software are:
I did not test all of these with the B205, but I've used some of them in the past and they've worked very nicely.
Some Extras
The FPGA Image
My initial plan for the road-test review included a section where I explore the design of the gateware on the FPGA, and maybe even try to modify it by adding something like a filter.
However, I made a mistake when looking up the specs of the B205mini-i. I confused it with the B200mini-i (which has a Spartan-6 XC6SLX75), but the difference between the two is that the B205mini-i includes a Xilinx Spartan-6 XC6SLX150 which is the largest of the Spartan-6 series and is not supported by Xilinx ISE Design Suite: WebPACK Edition (which is free). I don't have a license for ISE, so I won't be able to build the FPGA image.
Ettus provides build documentation, scripts and even the verilog sources, so let's take a look at how things are organized and what options are present:
uhd\fpga-src\usrp3\top\b2xxmini contains some project files and the 3 top level verilog files. Based on how things are usually setup, these will pull-in the sources for the other common modules which tend to be structured as libraries common to different platforms.
b205.v seems to be the top level file, with the I/O and module instantiations:
b205_ref_pll.v seems to be in charge of clock control which is used to tune the VCTCXO. There seems to be a state machine that tracks edges in the reference inputs and based on the delta between the expected/actual number of sample clock cycles, it attempts to estimate the ppm error of the reference clock. The state machine then adjusts the reference voltage to the DAC appropriately (approximating the ppm per DAC code using the VCTCXO's ppm/volt adjustment factor).
b205_core.v is a wrapper than instantiates some of the lower-level modules that control the radio, registers and other interfaces.
uhd\fpga-src\usrp3\lib has a lot more modules - AXI interfaces, a crossbar, some DSP modules, FIFOs, the GPFI interface, radio core, RFNoc etc.
Synchronization
The B205mini-i has a voltage controlled temperature compensation crystal oscillator, and a DAC that feeds the voltage control port of the VCTCXO - allowing the FPGA to make fine adjustments to the output frequency of the VCTCXO using an accurate PPS of 10 MHz source as a reference. As expected, the reference clock error measurement and adjustment is done in hardware.
Besides fine tuning the reference clock, the PPS/10 MHz input can be used to synchronize multiple USRPs. Synchronization and phase alignment between different devices is important for MIMO systems, but while you'd typically never do something that complex with the B205, synchronization is still useful because it can be used for timestamping.
According to the USRP documentation, you first set the time source to external using set_time_source. Once this is setup, the host then waits until it receives a NMEA message from the GPS receiver. After parsing it, increment the time by 1, and use the set_time_next_pps API, which makes the USRP latch the next rising edge and tag it with the GPS derived time. Once the USRP's internal sense of time is in sync with the 'true' GPS time, these timestamps can be used to trigger (eg start Rx/Tx at time 't') or tag events, since received packets have timestamps. Since this is enforced in the FPGA, any inaccuracies due to delays on the host/USB interface are automatically taken care of. Timed commands (like triggering rx/tx or GPIOs) can be very useful when you need to synchronize events executed by the USRP with other systems.
I didn't try this out because I didn't have a use case, I could see why this might be useful when you'd like to synchronize captures
Conclusion
The B205mini is the best performing portable SDR I've used to date. It's easy to use, setup, is entirely bus-powered and is very compact making it a great fit for space constrained or portable applications.
The USB 3.0 interface helps the B205 edge past other SDRs that have a USB 2.0 interface, allowing it to support significantly higher sampling rates. The Ettus documentation states that the B205 should be able to stream at upto 61.44MSPS, but I never quite managed to get it to work without packet drops at that rate - in general it seems that half of that rate might work marginally well on most systems, with some systems working better than others (as Ettus says..).
Moving to the hardware - the B205mini-i ships without an enclosure and while the enclosure needs to be purchased separately, a it would have been nice to have a lower-cost enclosure that can be used to protect the B205 during general lab use. The RF transceiver has a wide frequency range of 70 MHz to 6 GHz, which covers most of the common bands - FM, multiple sub-GHz ISM bands, 2.4G Wi-Fi/BLE, cellular and 5G Wi-Fi. The B205 has duplex capabilities - the transmit path has a decent onboard PA, and the front-end has 2 connectors as well as software-controllable port assignment which makes it easy to switch between half and full-duplex modes. The clock/ 1PPS sync input makes in combination with the VCTCXO and DAC allows the clock on the FPGA to be disciplined and synchronized which can be a very useful feature to have in certain niche applications.
The extended temperature rating (and special case) might not be of use for general-purpose lab use, but should prove to be useful for outdoor applications where the Ettus needs to be placed close to an external outdoor antenna. One aspect about these types of deployments is that they usually tend to run a long cable between the antenna/SDR which is on the roof to the other hardware which is inside the building. Gigabit Ethernet is ideal for these types of applications because of the long cable length, but USB 3.0 tends to be limited to a couple of meters at most. On the other hand, USB 3.0 is significantly faster - but due to the limited cable length the B205mini is probably geared to a slightly different type of application where the case, temperature rating and portable form factor allow it to be used in outdoors or in harsh environments where the host might not be located too far apart.
USRP ships with stable drivers and works well with most software. UHD takes care of loading the firmware/bitstream to the FX3/Spartan 6 and included tools make it easy to find devices and benchmark transfer rates. The C++ API is well documented and is accompanied with a nice set of reference examples. Using some of the lower-level, detailed settings requires looking at code and searching for information on the forums, but the higher-level, general APIs are easy to get up-to speed with. Users have the option of building applications from scratch using the UHD APIs, or using any of the other programs that come with built-in support for the B205 - GNURadio, Matlab, gqrx etc to name a few. Since UHD is common to all USRPs, users could start prototyping with a smaller entry-level device like the B205 and upgrade to more capable hardware if required without needing to modify too much software. Ettus provides the sources for everything: the FX3 firmware, FPGA sources, schematics, UHD, USB drivers and so on, so users are free to make modifications if they feel like doing so - whether it is to fix a bug, add a feature or improve performance.
On the whole, the B205mini has capable hardware, stable software and 'just works'. The cost seems high when compared to other entry-level SDRs for general-purpose use, but the B205 has features that might be required for certain applications - and is backed by solid hardware and widely supported software.
Top Comments
nice review, I specifically like the part which describes the hardware in detail, including your analysis of the FPGA image.
Gerrit