wiki:Other/Summer/2020/FPGAspectrum

Version 30 (modified by rgd51, 4 years ago) ( diff )

Using FPGAs for Spectrum Sensing and Modulation Recognition

Project Objective

This project seeks to use machine learning to recognize different wireless devices. The project will use software defined radios (SDR) to record various devices, such as iphones, bluetooth earbuds, and Wifi laptops. These recordings will become the training data to a set of neural networks. The second part of the project will quantify the accuracy of the neural networks in classifying various device types based on their RF signatures.

Who We Are


Ryan Davis
Class of 2021
Rutgers University
Computer Engineering and
Computer Science

Zhuohuan Li
Class of 2020
Rutgers University
Computer Engineering

Sid Mandayam
Class of 2022
Rutgers University
Computer Science and
Mathematics

Jacob Morin
Class of 2021
Pingry High School

Reading Material

Week 1 Activities

  • Get ORBIT/COSMOS account and familiarize oneself with the testbed procedures
  • Learn about FPGAs
  • Presentation 1

Week 2 Activities

Week 3 Activities

  • Rework UDP client / server to work with Go to Verilog compiler
  • Transmit and receive generated WiFi packets using the USRPs on the Grid
  • Presentation 3

Week 4 Activities

Week 5 Activities

  • Begin looking in to matched filters
  • Finish data collection on the Grid (a lot of debugging)
  • Presentation 5

Week 6 Activities

Week 7 Activities

Final Presentation

WiFi Packet Generation


% Ryan Davis

PAYLOAD = 1500;                                               % bytes
PATH = "";

for i = 0:7
   filename = "WiFi_802.11n_" + i + "MCS_int16.dat";
   ht = wlanHTConfig("MCS", i, "ChannelBandwidth", "CBW20");
   
   payload = randi([0 1], [1 PAYLOAD*8]);
   txSig = wlanWaveformGenerator(payload,ht);
   
   output_txSig = formatOutput(txSig);

   fid = fopen(PATH + filename, "w");
   fwrite(fid, output_txSig, "int16");
   fclose(fid);
end
clear;

function arr = formatOutput(txSig)
    arr = zeros(size(txSig)*2);
    j = 1;
    for i = 1:size(txSig)
        arr(j) = cast(real(txSig(i)), "int16"); 
        arr(j+1) = cast(imag(txSig(i)), "int16");
        j=j+2;
    end
end

Experiment Automation


# Ryan Davis
# Adapted from code by Ivan Seskar

Experiment.name = "Artificial_WiFi"
Experiment.project = "Artificial_WiFi"

consoleExec("omf tell -t all -a offh")
consoleExec("omf load -i usrpcal_2020-02-24.ndz -t node3-2,node3-19,node8-7,node8-14,node13-7,node13-14,node18-2,node18-19,node3-1,node3-20,node18-1,node18-20 -r 0")
consoleExec("omf tell -t node3-2,node3-19,node8-7,node8-14,node13-7,node13-14,node18-2,node18-19,node3-1,node3-20,node18-1,node18-20 -a on")

freqs = ["2412e6", "2437e6", "2462e6", "5180e6", "5240e6", "5745e6", "5825e6"]
mcss = ["0", "1", "2", "3", "4", "5", "6", "7"]

topos = {"3" => [["node18-1", "node18-2"], ["node3-1", "node3-2"], ["node18-19", "node18-20"], ["node3-19", "node3-20"]],               # format:  dist => [["txnode_A", "rxnode_A"], ["txnode_B", "rxnode_B"] ... ]
         "15" => [["node13-7", "node8-7"], ["node13-14","node8-14"]],
         "45" => [["node18-1", "node3-1"], ["node18-2", "node3-2"], ["node18-19", "node3-19"], ["node18-20", "node3-20"]],
         "72" => [["node18-20", "node3-1"], ["node18-1", "node3-20"]] }

defApplication('tx', 'tx_samples_from_file') { |a|
  a.version(1, 0, 0)
  a.shortDescription = ""
  a.description = ""
  a.path = "export LC_ALL=C;/usr/local/lib/uhd/examples/tx_samples_from_file"
  a.defProperty('freq', "center frequency in Hz", '--freq',
                {:dynamic => false, :type => :string})
  a.defProperty('ant', "antenna to be used", '--subdev',
                {:dynamic => false, :type => :string})
  a.defProperty('rate', "baseband rate in Hz", '--rate',
                {:dynamic => false, :type => :string})
  a.defProperty('gain', "receiver gain in dB", '--gain',
                {:dynamic => false, :type => :string})
  a.defProperty('file', "reveived baseband waveform file name", '--file',
                {:dynamic => false, :type => :string})
  a.defProperty('type', "sample types", '--type',
                {:dynamic => false, :type => :string})
  a.defProperty('repeat', "continuously repeat", '--repeat',
                {:dynamic => false, :type => :string})
}

defApplication('rx', 'rx_samples_to_file') { |a|
  a.version(1, 0, 0)
  a.shortDescription = ""
  a.description = ""
  a.path = "export LC_ALL=C;/usr/local/lib/uhd/examples/rx_samples_to_file"
  a.defProperty('freq', "center frequency in Hz", '--freq',
                {:dynamic => false, :type => :string})
  a.defProperty('rate', "baseband rate in Hz", '--rate',
                {:dynamic => false, :type => :string})
  a.defProperty('gain', "receiver gain in dB", '--gain',
                {:dynamic => false, :type => :string})
  a.defProperty('nsamps', "number of samples", '--nsamps',
                {:dynamic => false, :type => :string})
  a.defProperty('file', "reveived baseband waveform file name", '--file',
                {:dynamic => false, :type => :string})
  a.defProperty('type', "sample types", '--type',
                {:dynamic => false, :type => :string})
  a.defProperty('discardtime', "time at which storing samples starts", '--discardtime',
                {:dynamic => false, :type => :string})
}

topos.each { |dist, topo|
    topo.each { |node_pair|
        freqs.each { |freq|
            mcss.each { |mcs|
                infilename = "WiFi_802.11n_"+mcs+"_int16.dat"
                exptag = dist+"ft_"+freq+"Hz_"+mcs+"MCS_"+node_pair[0]+","+node_pair[1]
                outfilename = "/root/rx_"+exptag+"_int16.dat"
                info("Setting up group for experiment: " + exptag)
                
                rxGroup = node_pair[1]+"@"+exptag
                txGroup = node_pair[0]+"@"+exptag
                
                defGroup(txGroup, node_pair[0]) { |n|
                    n.addApplication('tx') { |app|
                        app.setProperty('freq', freq)
                        app.setProperty('ant',  "A:0")
                        app.setProperty('gain', "30")
                        app.setProperty('type', "short")
                        app.setProperty('file', infilename)
                        app.setProperty('rate', "20e6")
                        app.setProperty('repeat'," ")
                    }
                }
                
                defGroup(rxGroup, node_pair[1]) { |n|
                    n.addApplication('rx') { |app|
                        app.setProperty('freq',freq)
                        app.setProperty('gain', "30")
                        app.setProperty('type',"short")
                        app.setProperty('nsamps',"40000000")
                        app.setProperty('file',outfilename)
                        app.setProperty('rate',"40e6")
                    }
                }
            }
        }
    }
}
trap("INT") {
  allGroups.stopApplications
  allGroups.exec("/usr/bin/pkill -9 -f rx_samples")
  allGroups.exec("/usr/bin/pkill -9 -f tx_samples")
  exit!
}

onEvent(:ALL_UP_AND_INSTALLED) { |event|
    # Wait for nodes to associate and give it an extra 5 sec just in case...
    sleep 5
    
    # scp IQ binary file to transmitters
    txfiles = "txfiles/WiFi*"
    topos.each { |dist, topo|
        topo.each { |node_pair|
            consoleExec("ssh root@" + node_pair[0] + " rm -f /root/*.dat")
            consoleExec("ssh root@" + node_pair[1] + " rm -f /root/*.dat")
        
            consoleExec("scp -o StrictHostKeyChecking=no " + txfiles + " root@"+node_pair[0]+":");
            consoleExec("scp -o StrictHostKeyChecking=no test.sh root@"+node_pair[0]+":");  # TODO temp for debugging
        }
    }
    
    topos.each { |dist, topo|
        topo.each { |node_pair|
            freqs.each { |freq|
                mcss.each { |mcs|
                    exptag = dist+"ft_"+freq+"Hz_"+mcs+"MCS_"+node_pair[0]+","+node_pair[1]
                    info ("\nStarting experiment:  " + exptag)
                    rxGroup = node_pair[1]+"@"+exptag
                    txGroup = node_pair[0]+"@"+exptag
                    
                    group(rxGroup).startApplications    # start receiver  (captures for 1 sec)
                    sleep 1                             # make sure we do not start transmitting before receiving
                    group(txGroup).startApplications    # start transmitter
                    
                    sleep 5 # wait for applications to hopefully finish
                    
                    group(txGroup).stopApplications
                    group(rxGroup).stopApplications
                    
                    outfilename = "/root/rx_"+exptag+"_int16.dat"
                    consoleExec("scp -o StrictHostKeyChecking=no root@" + node_pair[1] + ":" + outfilename + " /spare/spectrum/Artificial_WiFi/")  #copy recved data to archive
                    consoleExec("ssh root@" + node_pair[1] + " rm -f " +outfilename)
                }
            }
        }
    }
  
  allGroups.stopApplications
  Experiment.done
}

Attachments (15)

Note: See TracWiki for help on using the wiki.