Post Go back to editing

Issues regarding storing RX-buffer of Pluto SDR.

Category: Software
Product Number: ADLAM-Pluto
Software Version: Firmware version 0.38

Hi,

I am trying to continuously transmit known number of IQ samples and then receive them, the transmission works fine I've checked that on a oscilloscope as well as a spectrum analyzer, the reception seems to be working fine when we continuously plot the received data, but when we try to store the buffers into a array and then plot it, we get to see a very interesting behaviour that is the first 4 buffers that we store are stored correctly without any issue, but from the fifth buffer the signals start to overlap may be because of overflow of buffers so I reduced the sampling rate from 60MSPS to 30 MSPS and the bandwidth from 30MHz to 10MHz, but still experiencing the same issue I tried plotting single buffers too but in that too from the 5th buffer the signal being plotted changes.

Is this related to the stock setting that the pluto uses 4 buffers?

And even after generating a wave from -1 to +1 and using a loop back to receive the signals, teh amplitude of the received signals is reduced, I hev not changed teh filter setting or anything, and even tried changing the firmware.

For some reason I was not able to insert the code in the field for it.

Below is the code to store the buffers,

import time
import adi
import numpy as np
import matplotlib.pyplot as plt

file_path = 'pylfm.iq'
bin_data = np.fromfile(file_path, dtype=np.complex64)
bin_data *= 2**14

# Create radio
sdr = adi.Pluto(uri="ip:192.168.2.1")

# Define waveform properties
sample_rate = int(60e6)
bandwidth = int(30e6)

# Configure properties
sdr.sample_rate = sample_rate
sdr.tx_rf_bandwidth = bandwidth
sdr.tx_lo = int(435e6)
sdr._tx_buffer_size = int(len(bin_data))
sdr.gain_control_mode_chan0 = "manual"
sdr.tx_hardwaregain_chan0 = 0.0  # The range is -90 to 0 dB

# Configure RX properties
sdr.gain_control_mode_chan0 = 'manual'
sdr.rx_hardwaregain_chan0 = 0.0  # dB, allowable range is 0 to 74.5 dB
sdr.rx_lo = int(435e6)
sdr.rx_rf_bandwidth = bandwidth  # Filter width, set to the same as sample rate for now
sdr.rx_buffer_size = int(len(bin_data))
print('len of  a single buffer',int(len(bin_data)))

# Configuration data channels
sdr.tx_enabled_channels = [0]
sdr.rx_enabled_channels = [0]

sdr.tx_cyclic_buffer = True  # Enable cyclic buffers
sdr.tx(bin_data)

# Array to store buffers
buffers = np.array([], dtype=np.complex64)
count = 0
# Collect buffers
for i in range(10):
    rx_samples = sdr.rx()
    buffers  = np.concatenate((buffers, rx_samples))
    print(len(rx_samples))
    count = count  + 1
    plt.figure()
    plt.plot(np.real(rx_samples), label='Real part')
    # plt.plot(np.imag(rx_samples), label='Imaginary part')
    plt.xlabel('Sample')
    plt.ylabel('Amplitude')
    plt.title(f'Time Domain Plot - Buffer {i+1}')
    plt.legend()
    plt.grid(True)
    plt.show()

print(buffers)

print(type(buffers))
plt.figure()
plt.plot(buffers)
plt.title("Time Domain Signal")
plt.xlabel("Sample")
plt.ylabel("Amplitude")
plt.show()

Below is the result of storing 10 buffers together

Below is the result for storing 4 buffers together



Removed code for generation of bin file
[edited by: Rajpatil at 9:46 AM (GMT -4) on 5 Aug 2024]
  • Yes this is because the PLUTO uses 4 kernel buffers by default. You can change the number of kernel buffers up to 64(I think) but on the 65th buffer you will run into the same problem.

    The problem is that throughput is limited by the USB2.0 connection. You are generating a lot more data than you can transport so you overflow. 

    2 channels @ 30 MSPS and 2 bytes per sample = 2 * 2 * 30 * 8  = 960 Mb/s

    USB2.0 throughput is theoretically 480Mb/s, but realistically is probably lower than this.

    In my experience I could reach stable streaming at about 5MSPS although this can vary.

  • I also have access to a ADRV9361 board is there any way that I can run the above code on that board without running into the same problem?

  • Yes, it should be pretty straight-forward ..

    Change this line, the rest of the code should be more or less the same .. 

    sdr = adi.Pluto(uri="ip:192.168.2.1")  to adi.AD9361(uri="ip:192.168.2.1")

    Make sure you check the new IP address of the board

    -Adrian

  • I just tried that it I get the same results the, first 4 buffers are seen properly but after that samples are lost.

    Is there a way to resolve this issue, if not form the existing libraries then from HDL changes or something like that, if I go into HDL changes where are should I make the changes? as I need contiguous data reception, with minimum number of lost samples.

  • With the pluto it is not possible to get such a high streaming throughput. 

    What is your configuration with ADRV9361 board ? 

  • If you asking bout my host pc to which I connect the ADRV to? intel i7 processor 12th, 32 GB ram, nvidia rtx 3050. And I am using the ADRV1CRR-FMC carrier board.

  • ADRV1CRR-FMC has a gigabit ethernet connection, however 960MB/s can be pretty close to the limit. Python may also introduce a delay when processing data. Are you using the correct IP address for the ADRV9361 configuration ?

    You can run iio_readdev -u ip:192.168.... cf-ad9361-lpc -b 16384 -B 

    This will benchmark the connection and give you a throughput in MiB (1000000 bytes / second)

    Also try setting a slower sample rate and once you get stable streaming, go higher to see where it breaks. 

  • Are you using the correct IP address for the ADRV9361 configuration ?

    I had assigned the IP to the board as 192.168.5.213 so I am using that IP, If I was not using the correct IP the code would not have run in the first place right?

    This will benchmark the connection and give you a throughput in MiB (1000000 bytes / second)

    Tried running it by reducing the sample rate as well as the bandwidth the same issue is seen the first 4 pulses are recorded clearly but the samples of the next pulses are dropped. Before I was running the code at BW of 30e6 and Fs of 60e6, now I tried at BW of 10e6 and Fs of 20e6.

    Also while checking the through put I get the following error when I run the command into a terminal
    iio_readdev -u ip:192.168.5.213 cf-ad9361-lpc -b 16384 -B
    >>iio_readdev: invalid option -- 'B'
    >>Unknown argument '?'


    Is there a sample code for continuous transmission and reception in C or Cpp

  • In the pluto I am using one channel to transmit and one to receive and I was using a sample rate of 60MSPS but I've reduced it down to 5MSPS but still it drops samples  after the 4th buffer.

  • It is possible you have an older version of libiio. That's why you are getting the error. You should install the latest release ..

    This is an example of continous stream with libiio - https://github.com/analogdevicesinc/libiio/blob/libiio-v0/examples/ad9361-iiostream.c