RawOFDM is an implementation of OFDM for GNURadio that separates modulation from channel estimation (by using pilots). The name stems from the fact that it supports "raw" payloads in form of complex (I/Q) values.




Download the latest stable release from gnuradio.org. At the time of writing the latest release was 3.3.0.

Configure, make, and install gnuradio. My preferred way is:

  ./configure --prefix $HOME \
  --enable-{gnuradio-core,usrp2} \
  --disable-{usrp,docs,mblock,vrt} \
  --disable-gr-{atsc,{gsm-fr,cvsd}-vocoder,trellis,msdd6000,radio-astronomy,pager} \
  make check && make install

If you do it this way you will need to add to your environment (.profile, .bash_profile or .bashrc) (assuming python 2.7):

export PYTHONPATH=$PYTHONPATH:~/lib/python2.7/site-packages

Unless you are willing to run gnuradio as root, it's recommended that you add setuid root to the usrp2_socket_opener:

chown root:usrp ~/bin/usrp2_socket_opener
chmod 04750 ~/bin/usrp2_socket_opener


RawOFDM leverages the gr-howto-write-a-block example from gnuradio for autotools scripts. The first step after downloading the package and unpacking is:

./makelinks.sh $(GNURADIO_SRC_HOME)/gr-howto-write-a-block
where you need to provide the path for where you placed the gnuradio source. If your gnuradio package does not come with gr-howto-write-a-block you can download it separately from ftp repo. Afterwards the process is straightforward:
./configure --prefix $HOME
make check && make install
Don't forget to ensure that PYTHONPATH in your environment reflects where you installed the packages.


The package includes a few python scripts located in examples that assemble the flowgraph. The scripts provide the -h option for usage. Below are some common scenarios:

ofdm_tx.py / ofdm_rx.py

These scripts provide raw I/Q communications. ofdm_tx.py supports three basic modes:

./ofdm_tx.py --outfile OUTPUT [--txdata INPUT]   # INPUT holds I/Q values, OUTPUT holds channel samples
./ofdm_tx.py --infile INPUT -f FREQ              # INPUT holds channel samples, which are delivered to USRP2
./ofdm_tx.py -f FREQ [--txdata INPUT]            # direct: INPUT is I/Q, samples are delivered to USRP2
If --txdata is omitted, a random packet is generated and repeated. The data in the --txdata packet as well as in the --outfile/infile is encoded as complex values (interleaved real-imag 4-byte floats). However, by using the --char CAMPL one can input values encoded in one-byte-per-dimension (i.e. fix-point instead of float).
NOTE: When providing your own packet, ensure it's exactly the right length, i.e., match it with OFDM options: --fft-length and --occupied-tones and packet size specified as -s SYMBOLS. It's recommended to add the -v verbose option to print:
Raw OFDM parameters:
FFT length:       64
Occupied Tones:   53 (with DC)
Pilot Tones:       4
Data Tones:       48
CP length:        16
Extra Preambles:   2

ofdm_rx.py supports the same three basic modes as above, where --rxdata OUTPUT is used for the I/Q values. In addition, it supports --snrdata OUTPUT which automatically computes the SNR vs. the transmitted packet as provided in --txdata (or auto-generated if omitted as above). There are three --snrmode MODE options: per-packet, per-carrier and per-symbol.

Finally, it supports output to standard output and to a graphical scope for both I/Q values and SNR. Use - or . as OUTPUT in either --rxdata or --snrdata.

qam_tx.py / qam_rx.py

These scripts provide digital communications on top of RawOFDM. The digital data is encoded using the 121-91 punctured convolutional code and modulated using QAM. The usage is analogous to ofdm_Xx.py. The new options is --bitrate BITRATE which selects one of the eight 802.11 bit-rates:
bitratecode-rateconstellationbits-per-carrier802.11 datarate [Mb/s]

test-snr.sh / test-ber.sh

These convenience wrappers allow one to test the performance of RawOFDM over simulated channel or USRP2. The usage is as follows:

$ ./test-snr.sh -h
    ./test-snr.sh [options]
    -a|--amp|--snr)    amplitude (over USRP) or snr (simulated channel) (0.01/10.0)
    -i|--interp)       interpolation rate (16)
    -f|--freq)         center frequency (2.45G)
    -u|--usrp) TX RX   send via usrp (leave empty to use simulated channel)
    -s|--size)         number of symbols per packet (14)
    -n|--num)          number of packets (10000)
    -d)                dump raw snr to (snr.dat)
    -x)                packet data to be transmitted (leave empty to use random)
    --log)             enable flowgraph logging

The output could look as follows:

.Sent 10000 packets of 14 symbols in 0.00 seconds               # In this test, the sender sends all packets in one burst, so
781894221.039                                                   # these numbers should not be taken seriously.
USRP 2.45G 16
gr_buffer::allocate_buffer: warning: tried to allocate          # ignore this warning from gr_buffer
   154 items of size 424. Due to alignment requirements
   512 were allocated.  If this isn't OK, consider padding
   your structure to a power-of-two bytes.
   On this platform, our allocation granularity is 4096 bytes.
START corr = 0.995895                                           # In this test, the frame acquisition is working in burst mode.
START corr = 0.99431                                            # It will print preamble correlation on the first 6 frames it catches.
START corr = 0.996117                                           # This is just for diagnostics.
START corr = 0.994377
START corr = 0.995338
START corr = 0.995278
10000 26.751778125 0.798497184658 14.941                        # This is the overall statistic: (count) (average) (stddev) (minimum)
0       -100.00 0                                               # A histogram:
0       -5.00   0                                               # (count) (lower-bound) (cumulative)
0       0.00    0                                               # ...
0       5.00    0
1       10.00   0
3       15.00   1
312     20.00   4
9684    25.00   316
0 30 10000

So above we see that almost 97% of the packets had SNR between 25 and 30dB. The test-ber.sh tool gives similar (per-packet) output with brackets at 10e-2, 10e-3, 10e-4, etc.

When used with the -u option. test-XXX.sh tools assume that both USRP2 are connected to the same Ethernet NIC (eth1). To override this you need to edit the scripts.

It's entirely feasible to connect multiple USRP2 to one NIC via a GigabitE switch. The one that I used quite successfully was Netgear GS105 ProSafe.

Change Log