Hi Jonathon and thank you for your answer. I finally noticed the issue (a little bit late), but I think to have found a solution, albeit a temporary one.
The first step is to use two different DDCs instead of one with two ports. The second one is to configure the two data flows (or channels) in two processes running in separated threads. There are probably issues with multithreading in python, but for the moment this solution seems to work, at least for my needs. I’ll attach a script here in case someone has the same issue in the future. Arjan
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on 2021-06-01 10:09 @author: Arjan Feta """ import uhd import numpy as np from matplotlib import pyplot as plt import argparse import time from datetime import datetime import threading import asyncio def sig_pow2(s): ls = s.size res = np.divide(np.sum(np.square(np.abs(s))), ls +1) return res # 1) Create a RFNoC graph graph = uhd.rfnoc.RfnocGraph("addr=192.168.10.2") sa = uhd.usrp.StreamArgs("fc32", "sc16") sa.args = 'spp=' + str(182) rx_streamer = graph.create_rx_streamer(1, sa) rx_streamer1 = graph.create_rx_streamer(1, sa) radio_noc_block = graph.get_block("0/Radio#0") radio_block = uhd.rfnoc.RadioControl(radio_noc_block) radio_block.set_rate(200e6) radio_block.set_rx_gain(55, 0) radio_block.set_rx_gain(55, 1) radio_block.set_properties("spp="+str(182), 0) radio_block.set_properties("spp="+str(182), 1) radio_block.set_rx_frequency(1549998000, 0) radio_block.set_rx_antenna("RX1", 0) radio_block.set_rx_frequency(1.95e9, 1) radio_block.set_rx_antenna("RX2", 1) ddc_block = uhd.rfnoc.DdcBlockControl(graph.get_block("0/DDC#0")) ddc_block.set_input_rate(100e6, 0) ddc_block.set_output_rate(200e3, 0) ddc_block1 = uhd.rfnoc.DdcBlockControl(graph.get_block("0/DDC#1")) ddc_block1.set_input_rate(100e6, 0) ddc_block1.set_output_rate(200e3, 0) # Graph topology creation graph.connect("0/Radio#0", 0, "0/DDC#0", 0, False) graph.connect("0/DDC#0", 0, rx_streamer, 0) graph.connect("0/Radio#0", 1, "0/DDC#1", 0, False) graph.connect("0/DDC#1", 0, rx_streamer1, 0) graph.commit() async def rx1(): num_samps = 10000 buffer_samps = rx_streamer.get_max_num_samps() recv_buffer = np.zeros((1, buffer_samps), dtype=np.complex64) metadata = uhd.types.RXMetadata() stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont) stream_cmd.stream_now = True rx_streamer.issue_stream_cmd(stream_cmd) d = [] try: for i in range(1000): samples = np.empty((1, num_samps), dtype=np.complex64) # Receive the samples recv_samps = 0 t1 = datetime.now() while recv_samps < num_samps: samps = rx_streamer.recv(recv_buffer, metadata) if metadata.error_code != uhd.types.RXMetadataErrorCode.none: print(metadata.strerror()) if samps: real_samps = min(num_samps - recv_samps, samps) samples[:, recv_samps:recv_samps + real_samps] = recv_buffer[:, 0:real_samps] recv_samps += samps # d.append(samples[0]) p = sig_pow2(samples[0]) print("RX1: ", p) # await asyncio.sleep(0.5) # m = max(bins) # print(recv_samps, m) print("TIME LAPSED: ", datetime.now() - t1) # Get the power in each bin except KeyboardInterrupt: pass async def rx2(): num_samps = 10000 buffer_samps = rx_streamer1.get_max_num_samps() print(buffer_samps) recv_buffer = np.zeros((1, buffer_samps), dtype=np.complex64) metadata = uhd.types.RXMetadata() stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.start_cont) stream_cmd.stream_now = True rx_streamer1.issue_stream_cmd(stream_cmd) d = [] try: for i in range(1000): samples = np.empty((1, num_samps), dtype=np.complex64) # Receive the samples recv_samps = 0 t1 = datetime.now() while recv_samps < num_samps: samps = rx_streamer1.recv(recv_buffer, metadata) if metadata.error_code != uhd.types.RXMetadataErrorCode.none: print(metadata.strerror()) if samps: real_samps = min(num_samps - recv_samps, samps) samples[:, recv_samps:recv_samps + real_samps] = recv_buffer[:, 0:real_samps] recv_samps += samps # d.append(samples[0]) p = sig_pow2(samples[0]) # print("RX2: ", p) # await asyncio.sleep(0.5) # print(recv_samps, m) print("TIME LAPSED: ", datetime.now() - t1) except KeyboardInterrupt: pass def main(): rx1_thread = threading.Thread(target=asyncio.run, args=(rx1(),)) rx2_thread = threading.Thread(target=asyncio.run, args=(rx2(),)) rx1_thread.start() rx2_thread.start() exit() if __name__ == "__main__": main()
_______________________________________________ USRP-users mailing list -- usrp-users@lists.ettus.com To unsubscribe send an email to usrp-users-le...@lists.ettus.com