Post Go back to editing

PlutoSDR ad9361 fast frequency sweep

Hi,

I am implementing a bandwidth scan of 100MHz frequency range through plutosdr. I implemented it through gnuradio flow graph to python. I get the rx data through the Probe Signal Vector module.

Now, here are a few questions that bother me:

1). Whenever I change the rx LO frequency, the iio_pluto_source function has to be re-run in the python code, which will waste a lot of my time, after the actual measurement, it is about 1.5s. So, is there a good solution?

2). Whether there is a flag for the PlutoSDR rx module can let me know that the data has been converted, so that I can read the data as soon as possible.

Apologies if I have not added enough detail, I am relatively new to this area - please ask questions to help clarify.

Kind regards,

anasss

  • 1. The best possible solution is to use fast lock profiles. See UG-570

    2. No. There is no metadata available in the data stream. You can change the LO setting from gnuradio but the data reflecting that LO setting can be several buffers after the fact. This is not deterministic. The only was to guarantee relevant data is to through away a number of buffers after the change. This should be large, like 10.

    -Travis

  • Hi Travis,

    Thanks for your prompt reply!

    My whole system is implemented through python, I'm not sure if fastlock can be implemented through python. fastlock can achieve frequency switching at a fast speed, but I don't understand how the sampled data for each frequency is obtained. Lastly, I would also like to confirm whether changing the LO frequency via the IIO Attribute Sink block can also speed up frequency switching.

    anasss

  • Since you are using purely python just using the frequency attribute should be enough (iio attribute sink). If you don't need gnuradio and just want a python interface I would look at pyadi-iio (analogdevicesinc.github.io/.../). You could sweep frequency as follows:

    import adi
    
    sdr = adi.Pluto()
    sdr._rxadc.set_kernel_buffers_count(1) # Force no elastic buffers
    
    freqs = [1e9,1.5e9,2e9]
    
    data = []
    for freq in freqs:
        sdr.rx_lo = int(freq)
        data.append({"data":sdr.rx(),"freq":freq})
        

    -Travis

  • Hi Travis,

    you really helped me!

    I found that I've been on the wrong path, thank you for pointing me in the direction!

    I tested the running time of rx and it is much faster than before. 

    Finally, I have a question about the code example you gave me, how should I understand this part of the code.

    sdr._rxadc.set_kernel_buffers_count(1) # Force no elastic buffers

  • sdr._rxadc.set_kernel_buffers_count(1) # Force no elastic buffers

    Internally libiio and the DMA driver configure a set of buffers in a ring to help add elasticity to the system. This helps real-time streaming so you can process data remotely while the hardware will collect data simultaneously. However, this will add latency to the system. So if you change a setting like gain or LO, it will not appear in the data until you process the buffers in front of it.

    When the number of buffers is set to 1 it removes this pipeline of buffers, so when you request a buffer that it will reflect the current hardware settings when the buffer was requested (there technically will be some delay but its very small). But you will miss data in-between buffer requests.

    -Travis