Showing posts with label GNU Radio. Show all posts
Showing posts with label GNU Radio. Show all posts

Saturday, October 20, 2012

UHD

Stands for "Universal Hardware Driver"

Prior to UHD, there were two distinct APIs -- one for USRP1, the other  for USRP2, and the "classic" USRP2 API used raw-ethernet frames for carrying data/control. 

In UHD, all the platforms are supported (USRP1, USRP2, N2XX, and E1XX),  and for ethernet-connected platforms, the protocol is based on VITA-49-over-UDP.

Older example applications, which would have used one or the other of the USRP1 or USRP2 "classic" API, need to be lightly worked-over to be compatible with the UHD API.  

The N2XX platforms are *only* UHD capable, and many of the newer daughtercards are only accessible using the UHD API.

The UHD API also enables some of the fancier synchronization paradigms that weren't available in the "classic" interface, and also allows things like dual-DDC on the USRP2 and N2XXX platforms.

Thursday, October 18, 2012

gr.probe_avg_mag_sqrd_cf

gr.probe_avg_mag_sqrd_cf : This function can be used to find the average power on a channel.

Details can be found at /usr/local/include/gnuradio/gr_probe_avg_mag_sqrd_cf.h

http://gnuradio.org/doc/doxygen/gr__probe__avg__mag__sqrd__cf_8h.html

http://gnuradio.org/doc/doxyge/gr__probe__avg__mag__sqrd__cf_8h_source.html

http://gnuradio.org/doc/doxygen/classgr__probe__avg__mag__sqrd__cf.html

The implementation file can be located in :

gnuradio/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc





Example :

#!/usr/bin/python2.6
#!/usr/bin/env python

from gnuradio import gr
from gnuradio import uhd
import sys, time

class rx_cfile_block1(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self)

                self.uhd_usrp_source = \
                uhd.usrp_source(device_addr="serial=1R270DU1",stream_args=uhd.stream_args('fc32'))

                self.gr_file_sink = gr.file_sink(gr.sizeof_float ,"/home/sumit/first_app_data1")

                self.uhd_usrp_source.set_subdev_spec("A:0", 0)

                self.uhd_usrp_source.set_antenna("RX2", 0)

                self.uhd_usrp_source.set_samp_rate(1000000)

                self.uhd_usrp_source.set_gain(45)

                treq = uhd.tune_request(2450000000)

                self.uhd_usrp_source.set_center_freq(treq)

                self._head = gr.head(gr.sizeof_float, int(4))
        
                self.c2mag = gr.probe_avg_mag_sqrd_cf(0.01, 0.001)

                self.connect(self.uhd_usrp_source, self.c2mag, self._head, self.gr_file_sink)

def main():
    tb = rx_cfile_block1()   

    while not tb.c2mag.unmuted():

        tb.run()

        print tb.c2mag.unmuted() #show exceed threshold or not
        print tb.c2mag.level()        #show power
        print tb.c2mag.threshold()
        time.sleep(3)
                     


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass



Monday, October 15, 2012

Something about Multichannel spectrum sensing

Interesting Discussion on Changing Parameters at Runtime

Reference : http://gnuradio.4.n7.nabble.com/how-to-achieve-change-values-of-parameters-at-runtime-tt29993.html#a29995

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tx.ofdm_tx._tx_freq is just a variable holding the frequency, but does
not set it.

You have to re-tune the usrp (tb.set_freq(new_freq)).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Something about Spectral Correlation Function

USRP and GSM


Reference : http://gnuradio.4.n7.nabble.com/Is-it-possible-to-make-a-USRP-Tx-and-Rx-at-the-same-time-tt20901.html


GSM is a half-duplex TDMA protocol.  That is, a station is only ever
transmitting or receiving, but not both at the same time. 

The channel is divided into timed frames and slots, and the base
station and mobile units are allocated specific times to transmit.  


The USRP is capable of supporting this. 


There are at least two existing open-source GSM BTS implementations;
OpenBTS is one of them:

http://gnuradio.org/trac/wiki/OpenBTS

This project uses the low-level C++ interface to the USRP1, but not
the GNU Radio framework itself.

Some thing about source and sink connection

When a source src has multiple outputs we can connect as follows


fg.connect((src, 0),.......blocks of fg1)
fg.connect((src, 1),.......blocks of fg2)
fg.connect((src, 3),.......blocks of fg3)

or in other case 

fg.connect((src, 0),.......blocks of fg1)
fg.connect((src, 0),.......blocks of fg2)

fg.connect((src, 0),.......blocks of fg3)


This will connect output 0 to fg1 and output 1 to fg2 and so on

But when it has single output , we connect as 

fg.connect(src, fg1)
fg.connect(src, fg2)  


 

Spectrum Sensing Code Explanation by Firas. A

Reference : http://gnuradio.4.n7.nabble.com/Some-usrp-spectrum-sense-py-code-Explanation-tc26301.html

This program can be used as a basic code for implementing wideband spectrum analyzer. 

The USRP cannot examine more than 8 MHz of RF spectrum due to USB bus limitations. 


So, to scan across a wide RF spectrum band (bigger than 8 MHz) we have to tune USRP RF front end in suitable steps so that we can examine a lot of spectrum, although not all at the same instant. 


The usrp_spectrum_sense shows the way how it can be done.It steps across the spectrum and make the RF measurements. This application can sense a large bandwidth, but not in real time, and it can do the frequency sweep over the required frequency range

Theory: 

To use N points complex FFT X(W) analysis, we have to get N time samples x(t) which are sampled at Fs. 

These N time samples must be time windowed using a known window function to reduce spectral leakage.

Performing N points complex FFT analysis. 

The output of the complex FFT will represent the frequency spectrum contents as follows: 

1. The first value of the FFT output (bin 0 == X[0]) is the passband center frequency. 
 

2. The first half of the FFT (X[1] to X[N/2-1] contains the positive baseband frequencies,which corresponds to the passband spectrum from the center frequency out to the maximum passband frequency (from center frequency to +Fs/2).     

3. The second half of the FFT (X[N/2] to X[N-1]) contains the negative baseband frequencies,which correspond to the lowest passband frequency up to the passband center frequency (from -Fs/2 to center frequency). 

Example :

Let us assume that we have 1024 (I and Q) samples gathered using a tuner centered at 20MHz. And let us assume that the sampling frequency was 8MHz.
Doing 1024 points complex FFT means: 


1. FFT Frequency resolution is : 8MHz / 1024 = 7812.5 KHz 

2. The output of the FFT X[0] represents the spectrum at 20MHz.  

3. The output of the FFT X[1] to X[511] represents the frequencies from 20.0078125 MHz to 23.9921875 MHz (about 4MHz above center frequency). 

4. The output of the FFT X[512] to X[1023] represents the frequencies from 16.0078125 MHz to 19.9921875 MHz (about 4MHz bellow center frequency).
 



RF Frequency Sweeping:

1. Let us suppose that we want to scan RF spectrum band from 10MHz to 52 MHz. 

2. Let us remember that USRP can analyze 8MHz of frequency at a time.  

3. So theoretically we have to step our RF center frequency as follows: 

First step is 14MHz (it will cover frequency band from 10MHz to 18MHz), 
 
Second step is 22MHz (it will cover frequency band from 18MHz to 26MHz), 

 
Third step is 30MHz (it will cover frequency band from 26MHz to 34MHz), 

 
Fourth step is 38MHz (it will cover frequency band from 34MHz to 42MHz), 

 
Fifth step is 46MHz (it will cover frequency band from 42MHz to 50MHz), 

 
and finally the Sixth step is 54MHz (it will cover frequency band from 50MHz to 58MHz). 


Remember that we want the frequencies up to 52MHz only, so we have to discard some FFT points from the Sixth analysis.   

Paralytically we have to use FFT overlapping to reduce the non linearity response of the Digital Down Converter (the DDC frequency response is not Flat from -Fs/2 to + Fs/2) and to fill the frequency holes that will be present at the FFT analysis edges (10MHz, 18MHz, 26MHz, 34MHz, 42MHz, 50 MHz).  


So if we choose to use an overlap of 25%, this means that our step size will be 6MHz (8MHz*(1-.25)), thus practically we have to step our RF center frequency as follows: 


First step is 13MHz (it will cover frequency band from 9MHz to 17MHz), 
 
Second step is 19MHz (it will cover frequency band from 15MHz to 23MHz), 

 
Third step is 25MHz (it will cover frequency band from 21MHz to 29MHz), 

 
Fourth step is 31MHz (it will cover frequency band from 27MHz to 35MHz), 

 
Fifth step is 37MHz (it will cover frequency band from 33MHz to 41MHz), 

 
Sixth step is 43MHz (it will cover frequency band from 39MHz to 47MHz), 

 
and Finally the Seventh step is 49MHz (it will cover frequency band from 45MHz to 53MHz),  


Changing RF center Frequency  

To change USRP RF center frequency we have to send a tunning command to the USRP every time we complete the analysis of the current frequency chunk. 

Before gnuradio revision [10165], all USRP RF daughterboards tunning were done using Python functions and classes. After that revision, tunning the USRP daughterboards from withen C++ code is possible. 

In usrp_spectrum_sense.py, the DSP C++ written code is allowed to transparently invoke Python code USRP tune function. This tunning control is done in gr_bin_statistics_f sink function. 

Tunning Delay Problem:   

When we command the usrp RF daughterboard to change its center frequency, we have to wait until (right) ADC samples arrive to our FFT engine and we have to insure that it belongs to the wanted center frequency. This represents a problem since there are many delays along the digitization path (RF synthesizer settling time, and pipeline propagation delay [FPGA FIFO filling time, USB transferring time...etc]). To overcome this problem we have to use enough tune delay time in order to  be sure that the samples entering our FFT block are belong to the requested center frequency. This is done simply by dropping the incoming received samples over a specified tunning delay time. 

usrp_spectrum_sense Implementation

1. The engine of the usrp_spectrum_sense depends mainly on bin_statistics sink function.  

2. bin_statistics function combines statistics gathering with a state machine for controlling the USRP RF tuning (frequency sweeping). It determines max values (keeps track of the maximum power in each FFT bin) of vectors (with length vlen) over a time period determined by dwell_delay (after converting it to a number of FFT vectors). This operation is performed after discarding tune_delay samples.  

3. After processing N = dwell_delay samples, bin_statistics composes a message and inserts it in a message queue. 

4. Each message from bin_statistics consists of a vector of max values, prefixed by the center frequency corresponding to the associated samples,
i.e., it is the center frequency value of the delivered input samples to bin_statistics. 


Choosing Tune and Dwell delay times  

1) We have to play with the --tune-delay and --dwell-delay command line options to determine appropriate timming values. The most important one is the tune delay time.

2) The choose of tune-delay should include time for the front end PLL to settle, plus time for the new samples to propagate through the pipeline.  The default value is 1ms, which is probably in the ballpark on the RFX** boards.  The TV RX board is much slower.  The tuner data sheets says it could take 100ms to settle.

3) The tune delay timing parameter passed to bin_statistics is calculated in FFT frames which depends on USRP rate and FFT length as in :

tune_delay_passed_to_bin_statistics = int(round(required_tune_delay_in_sec*usrp_rate/fft_size))

if this calculated value is less than "1", then we should make it at least "1" FFT frame.

For example:

If the :

required_tune_delay_in_sec = 10e-3
and usrp_rate = 8000000 (decimation =8)
and FFT size is 1024


Then :

tune_delay_passed_to_bin_stats = 78   (FFT Frames)

This means we have to skip 78 incoming vectors (FFT frames) before we actually use the acquired samples in our spectrum statistics. 


Beside tunning time depends on the hardware (RF synthesizer speed),one should remember that the time needed to collect 1024 samples
with decimation rate=8 (minimum USRP decimation) is 128 usec, while the time needed to collect 1024 samples with decimation rate=256 (maximum USRP decimation) is 4.096 msec.

This means that the tune delay in the case of decimation rate =256 should be larger than that used for decimation = 8. 

A working tune delay value (which gives accurate results) can be known by experiments (for given decimation rate and FFT length).

Interrupting Output Spectrum  


The actual mapping from the levels at the daughterboard antenna input port to the output analysis values depends on a lot of factors including the used daughterboard RF gain and decimation specific gain in the digital down converter. You'll need to calibrate the system if you need something that maps to dBm.


Currently, the output of usrp_spectrum_sense is the magnitude squared of the FFT output.

That is, for each FFT bin[i], the output is Y[i] = re[X[i]]*re[X[i]] + im[X[i]]*im[X[i]] which  is nothing but power


If we square root the output, and divide it with the fft size, then we will get the voltage magnitude.

Calculating 20 Log10 this value will give us the power.

 
 
    

Sunday, October 14, 2012

Rate at which CPU gets the data

USRP ADC sampling rate = 64MSPS

Decimation Rate = x

Actual rate at which CPU gets data = 64/x MSPS

16bit for I and 16bit for Q

64/x MSPS = 64/x I samples + 64/x Q samples

So total bytes per sec = (64/x*16 + 64/x*16)/8

For x = 200

total bytes per sec =(64/200 + 64/200)*16*10^6 = 1.28 MBPS

For x = 100

total bytes per sec = 2.56 MBPS

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If the CIC starts linearly from 4 to 128, and followed by decimate by 2 Half Band Filter (HBF) Then [CIC+HBF]  should give us the following range [8,10,12,14,...........,256], and not the range [2,4,6,8,......,256] 


Reference :  http://gnuradio.4.n7.nabble.com/USRP-RX-Decimation Rate-tt11784.html

But Matt said something different

The CIC decimator does 4 through 128, but this is followed by a halfband
decimator which multiplies this by a factor of 2.  Thus, it only does
multiples of 2.  4, 6, 8, 10, 12, 14, 16, 18. 20, etc.   Up to 256 total.

Matt 






Reason of Frequency Spurs in FFT

Reference : http://gnuradio.4.n7.nabble.com/Artefacts-in-usrp-fft-py-tc11359.html

Sometimes we see several unknown frequency components visible in our FFT plot.

These are called "receiver spurs" or "rf spurs" or "a/d spurs"

You can check whether it is because of internal hardware imperfections or some external source. Following is a very simple test to verify it :

Note down the frequency of the spur, now tune the receiver again say by 1KHz and see the frequency of the spur again

If it doesn't move or if it moves in the opposite direction or it moves with an amount other than 1KHz , then it is an internal artifact not external.

** Histogram of a noisy input will be of Gaussian in shape

You can also check the proper functioning of the ADC by observing the  histogram.

Spikes in the histogram may indicate the bits which are stuck

A/D's also have quantization effects that are periodic and show up as spurs


Adding dithering noise helps to break up the periodicity and reduce the spurs.

** Dithering is a process that adds broadband noise to a digital signal. You may wonder why adding noise would make a signal sound better? It is really a trade off. The introduction of noise lessens the audibility of the digital distortion that comes from the quantization errors discussed above. In essence, low-level hiss-like noise is traded for a reduction of digital distortion.Dithering adds amplitude to all the signals in a digital sample. It forces the lower level amplitude values up to the next threshold level.

Reference http://www.pcrecording.com/dither.htm

Can we detect Bluetooth and 802.11 with USRP-1

A Nice Discussion : 

The answer is no.

The bandwidth is too large for the system to currently  handle.

If you tune the GNU Radio to the center frequency of an 802.11  channel, you'll see what looks like a rise in the noise floor (and, under  these conditions, it really is a rise in the noise) when there is a  transmission. 


Bluetooth signals hop from 2.402 - 2.480 MHz

79 1 MHz channels at a rate of  1600 hops per second. 


The GNU Radio cannot look a the entire band all at  once

If you look at a particular slice (~4 MHz) of spectrum, you might  catch a glimpse of a signal every now and then, unless you can plug in the  right frequency hopping sequence

If you have some 1 or 2 Mbps 802.11 devices to use, the BBN guys have done
work on receiving those. Here is the link.

Reference : http://gnuradio.4.n7.nabble.com/802-11-and-Bluetooth tc8615.html#a8618

usrp_spectrum_sense.py application can  sense a large bandwidth, but not in real time! It can do a sweep over  a very large frequency range, but it will very likely not be able to  detect bluetooth (since it is frequency hopping) nor 802.11b/g since this will most likely just look like noise.

Anyway, it is difficult to just detect wi-fi without trying to decode it, since it is not a continuous signal, i.e., packet oriented. Therefore, you won't have a
nice peak in your fft, compared to a radio broadcast channel.

Normally an AP will send beacons at 1 Mbps even if it is a b/g AP. 

Here Eric says :

Actually, I think you should be able to detect Bluetooth without too
much trouble.  If you just stare at a single point in the spectrum you
should be able to reliably detect 7 1 MHz channel's worth of data.

IIRC the hopping sequence is known, and thus you should be able to
determine if what you are seeing is bluetooth or not, even though you
are seeing only 7 out of 79 channels.

Eric 


Bandpass sampling says :

Bluetooth is only about 1 Mb/s data rate, so you should be able to decode it with only a few MSPS of sampling. 

 

Very Important Basics on usrp_oscope.py

usrp_oscope.py -f 103.3M -d 256

The command above, after executed, will plot the received signal in a 250KHz window centred at 103.3MHz

250KHz because the USRP samples at the rate of 64MSPS and decimation is 256, thus 64M/256 = 250e3 = 250KHz

Similarily if the decimation was 512, then we would have observed the received signal in a 125KHz window

This can be more clear if you see the fft of the signal with the same decimation rate.

You can observe that the length of the fft window will go from 0 to fs/2 and 0 to -fs/2 giving a total observable window of length fs Hz

** The Y axis of usrp_oscope does not show the voltage level, its not calibrated for that. The levels depend on gain settings too.

** usrp_oscope shows real and imaginary part of the complex baseband signal coming from the output of Digital down converter of the USRP

** So the usrp_oscope is actually showing the downconverted frequency, not the actual frequency










Something Important about usrp_spectrum_sense.py

gr_bin_statistics_f just keeps track of the maximum power in each FFT bin

--tune-delay  :  should include time for the front end PLL to settle, plus time for the  new samples to propagate through the pipeline.  The default is 1ms,  which is probably in the ballpark on the RFX-* boards.  The TVRX  board is much slower.  The tuner data sheets says it could take 100ms to  settle.

--dwell-delay :  says how long you want to "stare" at any particular window.

m.center_freq is the current tunning/tunned freq

m.data is the mag-squared of the FFT.

http://gnuradio.4.n7.nabble.com/attachment/13587/0/graph.JPG
Output from m.data is from the center frequency to the maximum frequency and half way it flips to the minimum frequency and increases back to the center frequency.

In other words : 

The first half of the array contains the positive baseband frequencies,  which corresponds to the passband center frequency out to the maximum  passband frequency.

The second half of the array contains the negative baseband frequencies,
which correspond to the lowest passband frequency up to the passband
center frequency.

This format is due to the output format of the underlying fftw library we use to calculate FFTs.

You can rotate the values by swapping the first and second halves of the array and end up with it going from lowest passband frequency to highest passband frequency.

If you have taken 512 point FFT then , for each 512 bins, (m.data[0]) to (m.data[255]) are mag_squared values for (m.center[0]) to (m.center[0] +freq_step/2), and (m.data[256]) to (m.data[511]) are mag_squared values for (m.center[0]-freq_step/2) to (m.center[0]).

USRP is capable to monitor 32MHz theoritically but because of USB it can send only 8MHz of bandwidth to the CPU.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is a line in the usrp_spectrum_sense.py

self.msgq = gr.msg_queue(16) ,

Here 16 means the number of messages in the queue

If you set it to 0 , that means no limit

If the queue is full, an attempt to add a message will block until there's room.

gr_message_sink also has an option that will have it drop messages if the message queue is full

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

log = gr.nlog10_ff(10, self.fft_size, -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)). 

** This formula is used to convert the FFT output value to dB. This is relative conversion and the values does not mean actual power because the actuall power value  depends on other factors such as RF gain used. 


** What is meant by relative, is that if the input signal power is (for example) -20dBm and we measured it in this formula as (say) 50dB, then when we change the signal power to -30dBm, we get 40dB from the output of this formula. So, lowering signal power level by 10dBm result a 10dB value reduction from the formula output. 

** So, what is the factors that effect dB conversion?. The first value is the FFT size, so that when we change the FFT size, the formula should compensate for this. Second we should compensate for the taps of the window used for FFT (Hanning, Hamming,...etc).