Friday, October 12, 2012

Quick & Dirty: Part-1 : Getting data from USRP

So Lets start the quick and dirty guide on "How to get data from usrp"


Step -1 Make a file named "foo.py" with your favourite text editor

Step-2 Insert following two lines in the beginning.

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

Please change the version number of python as per your system
These two lines are necessary to make this foo.py file executable.

Step-3 Import necessary ingredients by insert the following lines

from gnuradio import gr
from gnuradio import uhd

We are importing gr to get our canvas i.e. top_block.py and importing uhd to access the usrp

 Step-4 Making a class by inserting the following lines

class rx_cfile_block1(gr.top_block):

This makes a class named "rx_cfile_block1" which is a derived class of gr.top_block (don't worry about this .. just do it)

Step-5 Defining a function of the class by inserting the follwing line

def __init__(self):

Every python class has a member function named __init__ which is passed a parameter  "self"(don't worry about this .. just do it)

Step-6 Constructor for the derived class by inserting the following line

gr.top_block.__init__(self)

(don't worry about this .. just do it)

Step-7 Instantiating a uhd source by inserting following line

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

# If you want to record complex data then leave the line above as it is. If you want to record short data, put sc16 instead of fc32

# Instead of serial number you can put type=usrp1 or type=usrp2 (according to availability), inside the quotes

Step-8 Instantiating a file sink by inserting following line

self.gr_file_sink = gr.file_sink(gr.sizeof_gr_complex,"/home/username/first_app_data1")

** Replace username with your username


#  If you want to record complex data then leave the line above as it is. If you want to record short data, gr.sizeof_short*2 instead of gr.sizeof_gr_complex.

# For collecting short type data perform the above step after modification mentioned in step-7  

Step-9 Specify the subdevice by inserting following line

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

# For details on subdevices and antenna see my tutorial on subdevices here
http://www.youtube.com/watch?v=BERxSmWlRZM&feature=BFa&list=PLE8D7641BBF6E849B

Step-10 Specify antenna by inserting following line

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

# For details on subdevices and antenna see my tutorial on subdevices here
http://www.youtube.com/watch?v=BERxSmWlRZM&feature=BFa&list=PLE8D7641BBF6E849B

Step-11 Set the sampling rate by inserting following line

self.uhd_usrp_source.set_samp_rate(1000000)

#This sets the sampling rate to 1000000 i.e. 1MSPS

 Step-12 Set the gain by inserting following lines

self.uhd_usrp_source.set_gain(45)

 #This sets the gain to 45dB

Step-13 Set the center frequency by inserting following lines

treq = uhd.tune_request(2450000000)

self.uhd_usrp_source.set_center_freq(treq)

#This sets the center frequency to 2450000000 i.e. 2.45GHz

Step-14 Set the number of samples to be collected by inserting following line

self._head = gr.head(gr.sizeof_gr_complex, int(1000000))

#This sets the number of samples to be recorded equals 1000000

Step-15 Connect everything by inserting following lines

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

# It connects the uhd source, the head and the sink

Step-16 Finishing touch by inserting following lines of code

if __name__ == '__main__':
      tb = rx_cfile_block1()
      tb.run()

Now go to the terminal and type chmod +x foo.py

Now the python you just created has become executable so run it  by typing

./foo.py at the terminal

Now check the destination directory for the collected data.

Now you can plot the data by typing


gr_plot_psd_c /home/username/first_app_data1 # for PSD

gr_plot_fft_c /home/username/first_app_data1 # for FFT

Program :

http://www.2shared.com/file/hSrMaEKF/pgm_1.html
                     


22 comments:

  1. Hi Sumit,
    Your blog is very helpful for absolute beginners like me. Just had a doubt, should the Left hand side of the expressions conform to self.uhd_usrp_source or it can be any other variable u can use. Because what is important is the R.H.S. which indicates what you are declaring?

    ReplyDelete
  2. hi just wondering what range it captures from? so if the center frequency is 100, what would be the lower / upper x limits when graphed in the fft?

    ReplyDelete
  3. Hi Christopher, If the center frequency is 100MHz then the upper limit is 104MHz while lower limit is 96 MHz knowing that USRP-1 can process upto 8MHz.

    ReplyDelete
  4. Hi,
    Is it possible to send a character/string from one usrp to another? to generate a signal source and send it through USRPs can be done. But to send & receive a 'real' message (like 'Hello world'), how that can be done using GRC or Python environment?
    Greatly appreciate your sharing. Thanks

    ReplyDelete
  5. You can see the section where the packets are made. Its very easy. Start trying with single characters, then you can send strings. Although I have not tried strings, but I am sure it is possible.

    ReplyDelete
  6. Easy, humm maybe!
    You can see the code below. Currently I can send out 1 character but receiving different character. Sorry for the lengthy lines. I hope somebody will read it and guide me. Summary: send and receive character between 1 or 2 usrp.

    Eva

    Is there a way I can send you the code? I am limited to 4096 characters. so I couldn't paste the whole code

    ReplyDelete
  7. Just paste the part where you are packing the bits... i.e. payload generation part

    ReplyDelete
  8. ##There is a main function that I couldn't paste bcause lack of space. Also, please paid attention to Mod./deMod & Encod/deCod ##

    #Modulation/Demodulation initialization
    self.digital_gmsk_mod_0 = digital.gmsk_mod(
    samples_per_symbol=2,
    bt=0.35,
    verbose=False,
    log=False,
    )
    self.digital_gmsk_demod_0 = digital.gmsk_demod(
    samples_per_symbol=2,
    gain_mu=0.175,
    mu=0.5,
    omega_relative_limit=0.005,
    freq_error=0.0,
    verbose=False,
    log=False,
    )

    #Encoders/Decoders initialization
    self.blks2_packet_encoder_0 = grc_blks2.packet_mod_b(grc_blks2.packet_encoder(
    samples_per_symbol=2,
    bits_per_symbol=1,
    access_code="",
    pad_for_usrp=True,
    ),
    payload_length=0,
    )
    self.blks2_packet_decoder_0 = grc_blks2.packet_demod_b(grc_blks2.packet_decoder(
    access_code="",
    threshold=-1,
    callback=lambda ok, payload: self.blks2_packet_decoder_0.recv_pkt(ok, payload),
    ),
    )

    # initialize queues
    self.sink_queue = gr.msg_queue()
    self.source_queue = gr.msg_queue()

    # initialize the blocks
    self.msg_source = gr.message_source(gr.sizeof_char, self.source_queue)
    self.msg_sink = gr.message_sink(gr.sizeof_char, self.sink_queue, False)

    #Connect everything:
    self.connect((self.msg_source, 0), (self.blks2_packet_encoder_0,0), (self.digital_gmsk_mod_0,0), (self.uhd_usrp_sink_1))
    self.connect((self.uhd_usrp_source_1), (self.uhd_usrp_sink_2))
    self.connect((self.uhd_usrp_source_2), (self.digital_gmsk_demod_0,0), (self.blks2_packet_decoder_0,0), (self.msg_sink, 0))


    def send_pkt(self, payload):
    self.source_queue.insert_tail(gr.message_from_string(payload))

    def recv_pkt(self):
    pkt = ""

    if self.sink_queue.count():
    pkt = self.sink_queue.delete_head().to_string()

    return pkt

    # THANKS #

    ReplyDelete
  9. No .. not this part .. you need to play with struct.pack and struct.unpack in the benchmark>tx and benchmark_rx files respectively. If you see the documentation of struct.pack and struct.unpack in python .. you will get easily how to send integers, characters, and strings ...

    ReplyDelete
  10. Right! when test it in Python envir, they work perfectly. But adding USRPs, another mismatch error showed up. hope i didn't miss some parameters. msg error: ValueError: itemsize mismatch: message_source(23):0 using 1, gr uhd usrp sink(2):0 using 8
    Here is the major change:
    #Connect everything:
    self.connect(self.msg_source, self.uhd_usrp_sink_1,)
    self.connect(self.uhd_usrp_source_1, self.uhd_usrp_sink_2)
    self.connect(self.uhd_usrp_source_2, self.msg_sink)

    def send_pkt(self, payload):
    # (!c): '!' to make a packed network-byte order binary, that has type unsigned character (c)
    self.source_queue.insert_tail(pack('!c', (gr.message_from_string(payload))))

    def recv_pkt(self):
    pkt = ""
    if self.sink_queue.count():
    pkt = unpack('!c', self.msg_sink.delete_head().to_string())
    return pkt

    # Greatly appreciate your suggestion! #

    ReplyDelete
  11. !c will support only a character not the entire string... does this make sense :)

    ReplyDelete
  12. I am wondering that inside PC how you are able to send strings ! .. I shall also give it a try ...
    Why don't you try sending a single character over usrp ... to begin with

    ReplyDelete
    Replies
    1. yeah, for now the try is for one single character. "!": is to make a packed network-byte binary.

      Delete
  13. Hi all,
    Just checking if somebody got ideas on how to send/receive character via usrp using Python coding. I'm stuck :)

    Thanks!

    Eva

    ReplyDelete
  14. If you are not in hurry I can help ...:) I am badly busy in some assignments :(

    ReplyDelete
    Replies
    1. Yeah, no worry.
      I had set a goal to get it before going back to school, but I realized that I have lots to learn on embedded-wireless-python.
      I'll keep working on that until WE get it done for the sake of all fans :)

      Delete
  15. Brand new user. Installed Bashkar11's s/w set for Windows XP, 8 in Wiindows 7 machine and am attempting to run Quick and Dirty part 1.Exercised uhd_find_devices from command line and recieved both addr and serial. However received "...no devices found..." error using either addr or serial in the script. Any suggestions? Regards DS

    ReplyDelete
    Replies
    1. Hey ... can u send me a screen shot of the error ?

      Delete
    2. Yes. Never done so. Will attempt

      Delete
    3. Could not attach image. Here is the traceback

      Traceback (most recent call last):
      File "C:\Graduate School Materials\USRP drivers and code\pgm_1.py", line 35, in
      tb = rx_cfile_block1()
      File "C:\Graduate School Materials\USRP drivers and code\pgm_1.py", line 12, in __init__
      uhd.usrp_source(device_addr="addr=192.168.10.2",stream_args=uhd.stream_args('fc32'))
      File "C:\Program Files (x86)\gnuradio\lib\site-packages\gnuradio\uhd\__init__.py", line 116, in constructor_interceptor
      return old_constructor(*args)
      File "C:\Program Files (x86)\gnuradio\lib\site-packages\gnuradio\uhd\uhd_swig.py", line 3010, in usrp_source
      return _uhd_swig.usrp_source(*args)
      RuntimeError: LookupError: KeyError: No devices found for ----->
      Device Address:
      addr: 192.168.10.2

      The same when "serial= " is used instead of addr

      Thank you. DSego

      Delete
  16. Was able to get everything working. Thanks

    ReplyDelete