== USRP2 configuration and data collection with OEDL script == [[TOC(Tutorials/k0SDR*)]] === Description === In this tutorial we'll demonstrate exactly what the title says. === Hardware / Software Resources utilized === 1. 3 grid nodes with a USRP2 connect via Ethernet. 2. ''ubuntu-12-04-uhd-daemon.ndz'': node image with all the pre-compiled software required to configure the USRPs. 3. ''uhd_exp1.rb'' - OEDL script executed on the console. This script configures the USRPs for data collection at specified frequencies, sampling rate, etc... 4. ''uhd_daemon'' - a node background process that bridges the gap between OMF commands and USRP2. === Set up === * To get started first make a reservation on the [https://www.orbit-lab.org/schedule/ Orbit Scheduler]. * Let's pick 3 nodes with a USRP2. For a current list of nodes with USRPs, go to the [https://www.orbit-lab.org/schedule/ Orbit Scheduler], click on ''Status Page'' under ''Quick Links''. Select the ''Grid'' Tab and filter by ''SDR'' and USRP_N210 or SBX. This will give a topology list of nodes (below) that can be used with the OMF commands: {{{ [node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org, node2-1.grid.orbit-lab.org,node2-2.grid.orbit-lab.org,node2-19.grid.orbit-lab.org,node2-20.grid.orbit-lab.org, node19-1.grid.orbit-lab.org,node19-19.grid.orbit-lab.org,node19-20.grid.orbit-lab.org,node20-1.grid.orbit-lab.org, node20-19.grid.orbit-lab.org,node20-20.grid.orbit-lab.org,node1-1.sb3.orbit-lab.org,node1-2.sb3.orbit-lab.org] }}} * After logging into grid console, make sure all nodes are turned off {{{ nilanjan@console.grid:~$ omf tell -a offh -t node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org }}} * Verify state of node before continuing. Make sure all nodes are in the POWEROFF state. {{{ nilanjan@console.grid:~$ omf stat -t node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org }}} * Image nodes {{{ nilanjan@console.grid:~$ omf load -i ubuntu-12-04-uhd-daemon.ndz -r 20 -t node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org }}} * After nodes are imaged, verify that nodes are in POWEROFF state. Otherwise issue the following to turn them off for a reboot {{{ nilanjan@console.grid:~$ omf tell -a offh -t node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org }}} * Turn nodes back on and verify they are in POWERON state {{{ nilanjan@console.grid:~$ omf tell -a on -t node1-1.grid.orbit-lab.org,node1-2.grid.orbit-lab.org,node1-19.grid.orbit-lab.org,node1-20.grid.orbit-lab.org }}} * Download the OEDL experiment script [http://www.orbit-lab.org/raw-attachment/wiki/Tutorials/GNURadio/OmfExperiment1/uhd_exp1.rb uhd_exp1.rb] to your local directory on the console. Executing this script will command one USRP2 to transmit a carrier frequency at random frequency offsets while commanding the others to continually take FFT snapshots and record the measurements to an database file. The contents of the uhd file is shown with additional comments: {{{ nilanjan@console.grid:~/UHD$ cat uhd_exp1.rb defProperty('freq', 1500e6, "Starting rx frequency") defProperty('dwell', 3, "Number of seconds at each frequency step") defGroup('txnode', 'node2-2.grid.orbit-lab.org') { |n| } defGroup('rxnode', 'node1-1.grid.orbit-lab.org,node20-20.grid.orbit-lab.org') { |n| } onEvent(:ALL_UP) do |event| info "Give machines some time to warm up" wait 4 info "activate" allGroups.uhd.u0.activate # starts UHD daemon wait 3 info "set tx parameters" group("txnode").uhd.u0.txfreq = property.freq # set tx frequency (Hz) group("txnode").uhd.u0.txrate = "8e6" # set tx sampling rate group("txnode").uhd.u0.txgain = "30" # set tx gain (dB) group("txnode").uhd.u0.txampl = "0.7" # set tx wavform amplitude #group("txnode").uhd.u0.txwavefreq = "1e6" group("txnode").uhd.u0.txwavetype = "CONST" # set type of waveform to transmit = {CONST, SINE, RAMP} group("txnode").uhd.u0.transmit # start transmitting group("rxnode").uhd.u0.rxfreq = property.freq # set rx frequency group("rxnode").uhd.u0.rxrate = "8e6" # set rx sampling rate group("rxnode").uhd.u0.rxgain = "25" # set rx gain group("rxnode").uhd.u0.numbins = "128" # number of fft points group("rxnode").uhd.u0.avgwinlen = "32" # set averaging window size for each fft bin across time. group("rxnode").uhd.u0.omlfile = "spectrum.grid" # oml database file name to store fft data group("rxnode").uhd.u0.omlserver = "idb2:3003" # oml server group("rxnode").uhd.u0.record # start recording (0..30).each { |i| # set up loop offset = (rand()*4).to_f # find next transmit frequency cf = property.freq + (offset*1e6) group("txnode").uhd.u0.txfreq = cf # set new transmit frequency wait property.dwell # wait for a few seconds } allGroups.uhd.u0.stop # stop transmitting and stop recording allGroups.uhd.u0.deactivate # stop UHD daemon info "Finish it." Experiment.done end }}} === Execute script and view recorded data === * To run the experiment script: {{{ nilanjan@console.grid:~/UHD$ omf exec uhd_exp1.rb }}} * Once the script finishes, check the contents of the database file. The data should be recorded in ''spectrum.grid.sq3'' on the oml server ''idb2''. {{{ nilanjan@console.grid:~/UHD$ ssh idb2 nilanjan@idb2:~$ cd /var/lib/oml2 nilanjan@idb2:/var/lib/oml2$ nilanjan@idb2:/var/lib/oml2$ ls -l spectrum.grid.sq3 -rw-r--r-- 1 oml2 oml2 753561600 May 14 10:41 spectrum.grid.sq3 }}} * Dump the contents of ''spectrum.grid.sq3'' to have a quick look inside the sql file. {{{ nilanjan@idb2:/var/lib/oml2$ sqlite3 spectrum.grid.sq3 ".dump" PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE _senders (name TEXT PRIMARY KEY, id INTEGER UNIQUE); INSERT INTO "_senders" VALUES('node20-20',1); INSERT INTO "_senders" VALUES('node1-1',2); CREATE TABLE _experiment_metadata (key TEXT PRIMARY KEY, value TEXT); INSERT INTO "_experiment_metadata" VALUES('start_time','1369071050'); CREATE TABLE "spectrum_data" (oml_sender_id INTEGER, oml_seq INTEGER, oml_ts_client REAL, oml_ts_server REAL, "samplin g" INTEGER, "cfreq_MHz" REAL, "gain_dB" INTEGER, "FFTLength" INTEGER, "FFTNum" TEXT, "FFTBins" BLOB); INSERT INTO "spectrum_data" VALUES(1,1,0.534819999709725,211.009485,7692307,1500000000.0,25,128,'---',X'84B7C43E2146863DC912F53CC851933CF23EA93CCEC6AC3CEFF5EE3C7578D83CE054723C8C1D873C9F57F73C72CD1F3DF7C1BD3C7D75CC3CD972FA3C1A5B053DB973133DA6541E3D5ED0563DD8F0563DFA9E4B3D256B883DF368B03D02F2B43D77C1F53D403B2F3E2654A23E021EE33F690FFB3E7C7A613E7F6B093E49EFC93DA880AA3D78298B3DC5E1663D98FC483DCECC203D7755253D2BD7FE3CA74AEB3C5C8AF03C8453EE3C5F05D73CD289B63C4F51BD3C71A3BE3C5927983C2E6B8E3C6EFE753C19A3853CADAF7E3CBD118D3CFE1A963C99776F3CCC9E7F3CB610853CFE5A593C10E36B3C7365733C5EAC503CFA39353CA4CA763CC498213C44A11A3C07F1243CAEE5473CA26A483C6C603D3CFE6A483C6A9C113C9DCD0C3C1481413C3274C63B8B6A3F3C2701E33B506B6F3C3C9DDC3B05131B3CC50E1B3CB49D723C446E023C224B713C6E0FF33BFE68FD3B63FC0E3C3E33C43B9F8B973CB3A6733A992C813C76474E3C2DA1FC3A6DA70A3CCC66103CAA0A013C14874C3C24C4913AA335383C8472993CAA53BD3BEA0CA43B0846CB3CEBAF3B3CC2F1463C1AC0963CDD26553BF2C79C3A040E983CF4C8713C16F0AC3CF198233C98AA3B3C4E6D8D3C7CFEA13C7193723C317DFF3BA24DF93B17851D3CB140BE3C76979C3C31F39A3C41D05A3B56C5873C6D537F3C1540963CACF4F13CFB52DE3C6630093D5304343D'); }}} * The magnitude value of the fft bins are stored in binary format. The first entry of the db file is shown above. So when dumping the file contents the fft bins data is shown as consecutive ASCII representation of the binary floating point numbers. The 1st is 84B7C43E <==> 0.38421, the 2nd bin is 2146863D <==> 0.065563, etc... * To quickly visualize the fft data we can download and compile the following code (it's also in the attachment). {{{ nilanjan@console.grid:~/UHD$ wget http://www.orbit-lab.org/raw-attachment/wiki/Tutorials/GNURadio/OmfExperiment1/sq3_parse.cpp nilanjan@console.grid:~/UHD$ gcc sq3_parse.cpp -o sq3_parse -lsqlite3 nilanjan@console.grid:~/UHD$ ./sq3_parse spectrum.grid.sq3 > db_dump.dat }}} * Parse the database file, load octave for a quick plot. {{{ nilanjan@console.grid:~/UHD$ ./sq3_parse spectrum.grid.sq3 > db_dump.dat nilanjan@console.grid:~/UHD$ octave octave:1> w = dlmread('db_dump.dat',','); octave:2> a = w(:,[9:136]); octave:3> imagesc([1:size(a,2)] , [1:size(a,1)] , 10*log(sqrt(a)/1000)); octave:4> colorbar() }}} || [[Image(random_tx.png, width=500px)]] ||