[[TOC(Tutorials/k0SDR*, depth=3)]] == Working with USRP2 - Universal Software Radio Peripheral == === Description === In this tutorial we'll use the 2 USRPs on Sandbox 3 to transmit and receive a single frequency over the air to demonstrate the use of ''Universal software Radio peripheral'' Hardware Drivers (UHD) which is used standalone to configure and enable the USRPs. This tutorial can be run on other USRP2s available of the grid as well. For details on available USRPs on the grid, please see [wiki:Hardware/fDevices/cSDR/gUSRP#GRID available USRP hardware in the grid]. === Hardware / Software Resources utilized === 1. Sandbox 3 - consists of two nodes (node1-1 & node1-2). Each node has a USRP2 connect via Ethernet. 2. ''baseline-sdr.ndz'': disk image loaded onto nodes. This image has all the precompiled - software required to configure the USRPs and analyze recorded data. The USRP2's interface with the node is already configured. 3. omf: used to image to nodes 4. octave: GNU version of MATLAB === Set up === * Before you can access the testbed, you need to [https://www.orbit-lab.org/schedule make a reservation] and get it approved by the [wiki:Documentation/Scheduler reservation service]. After receiving the reservation's confirmation (approval) email: * [[CollapsibleStart(Login into reserved domain: ssh username@sb3.orbit-lab.org)]][[Include(Documentation/Short/Login)]][[CollapsibleEnd]] * [[CollapsibleStart(Load an image on the nodes: omf load -i baseline-sdr.ndz -t system:topo:all)]] [[Include(Documentation/Short/LoadImage)]][[CollapsibleEnd]] * [[CollapsibleStart(Turn on the nodes: omf tell -a on -t all)]] [[Include(Documentation/Short/TellOn)]][[CollapsibleEnd]] === Usage === * Once the nodes are imaged, open a separate SSH session to each node. Use the USRP2 on node1-1 as the transmitter and USRP2 on node1-2 as receiver.[[BR]] ** SSH into node1-1 from the sb3 console: {{{ username@console.sb3:~$ ssh root@node1-1 }}} ** Type the following to edit `/etc/netplan/00-netplan.yaml` {{{ sudo nano /etc/netplan/00-netplan.yaml }}} ** After adding the following lines, hit CTRL-O to save, hit enter again to confirm, and CTRL-X to exit. Remember, indentation matters and you must use spaces, not tabs. {{{ enp4s0: dhcp4: false addresses: [192.168.10.1/24] }}} ** Apply the new configuration {{{ root@node1-1:~# netplan apply }}} ** Go to the UHD examples folder: {{{ root@node1-1:~# cd uhd/host/build/examples/ }}} or {{{ root@node1-1:~# cd /usr/local/lib/uhd/examples/ }}} ** SSH into node1-2 from the sb3 console: {{{ username@console.sb3:~$ ssh root@node1-2 }}} ** Repeat the previous step to add the following lines to `/etc/netplan/00-netplan.yaml` {{{ enp4s0: dhcp4: false addresses: [192.168.10.1/24] }}} ** Apply the new configuration {{{ root@node1-2:~# netplan apply }}} ** Go to the UHD examples folder: {{{ root@node1-2:~# cd uhd/host/build/examples/ }}} or {{{ root@node1-2:~# cd /usr/local/lib/uhd/examples/ }}} * The directory content should look like the following in both nodes {{{ root@node1-1:~/uhd/host/build/examples# ls benchmark_rate latency_test rx_samples_to_file test_pps_input tx_waveforms CMakeFiles Makefile rx_samples_to_udp tx_bursts cmake_install.cmake network_relay rx_timed_samples tx_samples_from_file CTestTestfile.cmake rx_multi_samples test_messages tx_timed_samples }}} * Once inside the node verify that the node can talk to the USRP {{{ root@node1-1:~/uhd/host/build/examples# uhd_find_devices }}} * It should return something like the following: {{{ root@node1-1:~/uhd/host/build/examples# uhd_find_devices linux; GNU C++ version 4.8.4; Boost_105500; UHD_003.009.001-0-unknown -------------------------------------------------- -- UHD Device 0 -------------------------------------------------- Device Address: type: usrp2 addr: 192.168.10.2 name: serial: F297B6 }}} * Probe the device {{{ root@node1-1:~/uhd/host/build/examples# uhd_usrp_probe linux; GNU C++ version 4.8.4; Boost_105500; UHD_003.009.001-0-unknown -- Opening a USRP2/N-Series device... -- Current recv frame size: 1472 bytes -- Current send frame size: 1472 bytes _____________________________________________________ / | Device: USRP2 / N-Series Device | _____________________________________________________ | / | | Mboard: N210r4 | | hardware: 2577 | | mac-addr: 00:80:2f:0a:cc:db | | ip-addr: 192.168.10.2 | | subnet: 255.255.255.255 | | gateway: 255.255.255.255 | | gpsdo: none | | serial: F297B6 | | FW Version: 12.4 | | FPGA Version: 11.1 | | | | Time sources: none, external, _external_, mimo | | Clock sources: internal, external, mimo | | Sensors: mimo_locked, ref_locked | | _____________________________________________________ | | / | | | RX DSP: 0 | | | Freq range: -50.000 to 50.000 MHz | | _____________________________________________________ | | / | | | RX DSP: 1 | | | Freq range: -50.000 to 50.000 MHz | | _____________________________________________________ | | / | | | RX Dboard: A | | | ID: SBX (0x0054) | | | Serial: E5R1CSBXS | | | _____________________________________________________ | | | / | | | | RX Frontend: 0 | | | | Name: SBXv3 RX | | | | Antennas: TX/RX, RX2, CAL | | | | Sensors: lo_locked | | | | Freq range: 400.000 to 4400.000 MHz | | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB | | | | Bandwidth range: 40000000.0 to 40000000.0 step 0.0 Hz | | | | Connection Type: IQ | | | | Uses LO offset: No | | | _____________________________________________________ | | | / | | | | RX Codec: A | | | | Name: ads62p44 | | | | Gain range digital: 0.0 to 6.0 step 0.5 dB | | | | Gain range fine: 0.0 to 0.5 step 0.1 dB | | _____________________________________________________ | | / | | | TX DSP: 0 | | | Freq range: -50.000 to 50.000 MHz | | _____________________________________________________ | | / | | | TX Dboard: A | | | ID: SBX (0x0055) | | | Serial: E5R1CSBXS | | | _____________________________________________________ | | | / | | | | TX Frontend: 0 | | | | Name: SBXv3 TX | | | | Antennas: TX/RX, CAL | | | | Sensors: lo_locked | | | | Freq range: 400.000 to 4400.000 MHz | | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB | | | | Bandwidth range: 40000000.0 to 40000000.0 step 0.0 Hz | | | | Connection Type: QI | | | | Uses LO offset: No | | | _____________________________________________________ | | | / | | | | TX Codec: A | | | | Name: ad9777 | | | | Gain Elements: None }}} If the commands ''uhd_find_devices'' & ''uhd_usrp_probe '' return No UHD Devices Found, please refer to the troubleshooting section. * On node1-1 use the waveform generator to continuously transmit a single frequency sine wave with a frequency of 1MHz sampled at a rate of 5 MSamples / second and modulated to 1800MHz {{{ root@node1-1:~/uhd/host/build/examples# ./tx_waveforms --wave-freq 1e6 --wave-type SINE --freq 1800e6 --rate 5e6 --gain 10 --ampl 0.2 linux; GNU C++ version 4.8.4; Boost_105500; UHD_003.009.001-0-unknown Creating the usrp device with: ... -- Opening a USRP2/N-Series device... -- Current recv frame size: 1472 bytes -- Current send frame size: 1472 bytes Using Device: Single USRP: Device: USRP2 / N-Series Device Mboard 0: N210r4 RX Channel: 0 RX DSP: 0 RX Dboard: A RX Subdev: SBXv3 RX TX Channel: 0 TX DSP: 0 TX Dboard: A TX Subdev: SBXv3 TX Setting TX Rate: 5.000000 Msps... Actual TX Rate: 5.000000 Msps... Setting TX Freq: 1800.000000 MHz... Actual TX Freq: 1800.000000 MHz... Setting TX Gain: 10.000000 dB... Actual TX Gain: 10.000000 dB... Setting device timestamp to 0... Checking TX: LO: locked ... Press Ctrl + C to stop streaming... }}} * Now set up the USRP2 on node1-2 to sniff the spectrum at 1800MHz using the rx_ascii_art_dft tool {{{ root@node1-2:~/uhd/host/build/examples# ./rx_ascii_art_dft --freq 1800e6 --gain 10 --rate 5e6 --frame-rate 10 --ref-lvl -30 --dyn-rng 70 }}} * The output should display a frequency spectrum in the terminal using the ascii art! This plot is showing a peak at 1800MHz. Note that this peak is composed of the carrier which is centered at 1800 MHz and the sine waveform at 1800 MHz + 1MHz. {{{ : | :| -40 || || || || || | ||! -60 !| | ||| || | ||| || | ||| || |! ||| || || !|||: || || .||||| ||! || |||||| -80 ||| !|| |||||| ||| ||| ||||||! ||| ||| . ||||||| ||| . !| : |||: : | .| !!|||||||| . ! : . . ||| | |. .||| : | ||||| :|!!.|. . ||. |. ! ||||||||||| .! ||!!|: : | | :|: | : . | : !|! :||| || . :|! :.|!||:||||.| !| |||||.||||||| . ::| ||| ||::|!!|||||||||||!. : :| ||:| . | .! :! .|| . . -100 .!| ||||||| : !|!|!. | ||||:|| . |!| .|.:.|.||| !|||| : ||.|:||| |!|||||||||||||:|| ||||||||||||| !|| |||.|||:||||||||||||||||||||| ||||| |!||||| ! | :|:||| :!||||||||: | |: dBfs 1798MHz 1798.5MHz 1799MHz 1799.5MHz 1800MHz 1800.5MHz 1801MHz 1801.5MHz 1802MHz }}} * Now going back to node1-1, turn off the waveform generator so nothing is transmitted. That is do a ''ctrl-c'' in the node1-1 terminal. The frequency spectrum display on node1-2 should display the noise floor {{{ -40 -60 . | -80 | || : .||: : . |! || ..||||. . .. ||. . | .. | .. .|. .|| . ||!||||||| || |||!.. . . :|:| ! ! .! ..: !|| |: :|: . : |! .. ||| |.:| |. . || .!!| || .! .| : ||| ||||.||::| ||||||||||:.|| |||||| | !|:|.|: |:|||| | |: || ||| !|||!|| |! |||. | |: ! . -100 :||!.|: .|||| .. !:||| ||||!||.! | || !||||||| |||||| . || ||| ! |||||||||| ||||||||||||||||||||||| ||||||| ||||||!|| ||::||!.! .||| ||||||| || ||||| |||| . || ||. !! !: dBfs 1798MHz 1798.5MHz 1799MHz 1799.5MHz 1800MHz 1800.5MHz 1801MHz 1801.5MHz 1802MHz }}} * Now generate a 500 kHz ramp (ie. sawtooth) waveform with the carrier centered at 1800 MHz. {{{ root@node1-1:~/uhd/host/build/examples# ./tx_waveforms --wave-freq 500e3 --wave-type RAMP --freq 1800e6 --rate 5e6 --gain 5 --ampl 0.1 }}} * Multiple peaks separated by 500 kHz should be present in the frequency spectrum of the receiving node. The peaks correspond to the spectral characteristics of the saw tooth waveform. {{{ -40 : |! || -60 . :| : || | || | || | . |! || | || :| || . || || | || || |! || . | || ||| :! | || || || || || || !|| ||| ||| .|| || || .|| || || :|| ||| .||| ||| ||| !|| ||! ||| ||: : -80 || .||| .|||! ||||. :|||! |||: |||| :||| |||: !||| | ||. ||||| ||||| .||||| |||||! |||||| !||||! .|||||: |||||.. |||| | ||| !||||||. .. . ||||||. : .:||||||.: : !||||||:. !|||||||. . |||||||| ! :::|||||||. . !|||||||: !|||||!. | |||: !||||||||!|| ||!||||||| : .:..| ||||||||||. : :!||||||||||| .:::|||||||||!! ||!|!!|||||||||.:|| :||||||||||||.:.|. .| :|||||||||!!|.| !|||||||||! !| ||||.!: ..|:.||||||||||||.!|!:||||||||||||||||||||||||||||||!.!|||||||||||||||.:::|||||||||||||||.|||||||||||||||||||!!||||||||||||||||||!||:|||||||||||||||.:|||||||||||!|. :!|| |||||||:||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||:!: |.|||| -100 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||:|||||| dBfs 1798MHz 1798.5MHz 1799MHz 1799.5MHz 1800MHz 1800.5MHz 1801MHz 1801.5MHz 1802MHz }}} * Play around with the options on tx_waveforms - vary the tx_waveforms amplitude (--ampl option) and the waveform frequency (--wave-freq); verify the corresponding change in the received frequency spectrum. To view all options do the following: {{{ root@node1-1:~/uhd/host/build/examples# ./tx_waveforms --help }}} === Capture waveform and record to file & add time-domain plot of waveform === * Now record the received signal to an OCTAVE / MATLAB file. From node1-1 transmit a waveform with the following attributes {{{ root@node1-1:~/uhd/host/build/examples# ./tx_waveforms --wave-freq 1e6 --wave-type SINE --freq 1800e6 --rate 5e6 --ampl 0.5 }}} * On node1-2, use the rx_sample_to_file utility to dump the received samples into a file. {{{ root@node1-2:~/uhd/host/build/examples# ./rx_samples_to_file --freq 1800e6 --rate 5e6 --type float }}} * The samples will be recorded into the file ''usrp_samples.dat''. Upload this file into octave and plot the time-domain samples. On node1-2, start up octave {{{ root@node1-2:~/uhd/host/build/examples# octave GNU Octave, version 3.8.1 Copyright (C) 2014 John W. Eaton and others. This is free software; see the source code for copying conditions. There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, type 'warranty'. Octave was configured for "x86_64-pc-linux-gnu". Additional information about Octave is available at http://www.octave.org. Please contribute if you find this software useful. For more information, visit http://www.octave.org/get-involved.html Read http://www.octave.org/bugs.html to learn how to submit bug reports. For information about changes from previous versions, type 'news'. octave:1> }}} * From the Octave prompt verify received signal in the file. The function ''read_float_binary'' used below can be downloaded from the attachment. {{{ octave:5> c=read_float_binary('usrp_samples.dat'); octave:6> creal = c([1:2:length(c)]); octave:7> cimage = c([2:2:length(c)]); octave:8> subplot(211) ; plot(creal(100:230)) ; title('real') ; axis([0 140 -0.010 0.010]) ; octave:9> subplot(212) ; plot(cimage(100:230)) ; title('imag') ; axis([0 140 -0.010 0.010]) }}} * An octave plot window displaying the sine wave should be similar to the following. || [[Image(SineWave1MHz.png, width=500px)]] || || Plot of received sine wave|| === Troubleshooting === * ''uhd_find_devices'' & ''uhd_usrp_probe '' return '''No UHD Devices Found''' If problems arise when trying find and probe the device, it's most likely the case that interface between the node and USRP2 needs to be reconfigured. In most scenarios, if finding the USRP2s fails it should return the following for ''uhd_find_devices'' {{{ root@node1-1:~# uhd_find_devices linux; GNU C++ version 4.8.4; Boost_105500; UHD_003.009.001-0-unknown No UHD Devices Found }}} The USRP2 has an ethernet interface (ip address: 192.168.10.2) to the node's eth2 interface (ip address: 192.168.10.1). To verify the nodes interface configuration: {{{ root@node1-1:~# ifconfig eth2 eth2 Link encap:Ethernet HWaddr 00:03:1d:07:49:5c inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0 inet6 addr: fe80::203:1dff:fe07:495c/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:10 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:370 (370.0 B) TX bytes:862 (862.0 B) Interrupt:17 Memory:fdce0000-fdd00000 }}} If the interface is not configured, then do then following: {{{ root@node1-1:~# ifconfig eth2 192.168.10.1 netmask 255.255.255.0 up }}} The USRP2 ip-address is 192.168.10.2. Now try pinging the USRP2. {{{ root@node1-1:~# ping 192.168.10.2 PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data. 64 bytes from 192.168.10.2: icmp_req=1 ttl=32 time=1.04 ms 64 bytes from 192.168.10.2: icmp_req=2 ttl=32 time=1.00 ms 64 bytes from 192.168.10.2: icmp_req=3 ttl=32 time=1.04 ms 64 bytes from 192.168.10.2: icmp_req=4 ttl=32 time=1.05 ms 64 bytes from 192.168.10.2: icmp_req=5 ttl=32 time=1.04 ms }}} At this point the node and USRP2 are able to see each other. Now retry finding and probing the USRPs.