Hello again,
I left gnuradio for the moment and try to concentrate to the python API, since
it seems to have
a finer level of granularity in controlling the RFNoC blocks. In the attached
script I can manage to
set up the block properties i.e., the two channels with one antenna and a
tuning frequency each.
The problem now comes when the flow graph is committed.
```
RuntimeError: RfnocError: ResolveError: Attempting to overwrite property
`mtu@INPUT_EDGE:1' with a new value after it was locked!
```
Has anybody tried something like this before?
Regards,
Arjan
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
import uhd
import numpy as np
from matplotlib import pyplot as plt
import time
# 1) Create a RFNoC graph
graph = uhd.rfnoc.RfnocGraph("addr=192.168.10.2")
# 1.1) Get the list of available RFNoC blocks loaded on the USRP device
def listStaticConnections():
for edge in graph.enumerate_static_connections():
print(edge.to_string())
listStaticConnections()
# =============================================================================
# 0/SEP#0:0==>0/DUC#0:0
# 0/DUC#0:0==>0/Radio#0:0
# 0/Radio#0:0==>0/DDC#0:0
# 0/DDC#0:0==>0/SEP#0:0
# 0/Radio#0:1==>0/DDC#0:1
# 0/DDC#0:1==>0/SEP#1:0
# 0/SEP#2:0==>0/DUC#1:0
# 0/DUC#1:0==>0/Radio#1:0
# 0/Radio#1:0==>0/DDC#1:0
# 0/DDC#1:0==>0/SEP#2:0
# 0/Radio#1:1==>0/DDC#1:1
# 0/DDC#1:1==>0/SEP#3:0
# 0/SEP#4:0==>0/Replay#0:0
# 0/Replay#0:0==>0/SEP#4:0
# 0/SEP#5:0==>0/Replay#0:1
# 0/Replay#0:1==>0/SEP#5:0
# =============================================================================
# 2) Construct a Radio RFNoC block
# get rfnoc block of interest as a graph node, to connect with other blocks
radio_noc_block = graph.get_block("0/Radio#0")
# construct radio block
radio_block = uhd.rfnoc.RadioControl(radio_noc_block)
# We now want to pass the data acquired from the radio to the host;
# stream end point (SEP) and from then to the DDC.
# Radio -> DDC -> SEP -> HOST (file or another sink type)
# Connect the rx streamer to a Digital Down Converter (Radio -> DDC)
graph.connect("0/Radio#1", 0, "0/DDC#1", 0, False)
graph.connect("0/Radio#1", 1, "0/DDC#1", 1, False)
# Construct a rx streamer block
# graph.create_rx_streamer(numOfChannels, StreamAttributes)
# fc32: cpu 32 bits float type;
# sc16: OTW - Over The Wire type (rfnoc deals in 16 bit fixed point complex values)
# OTW indicates the data type that will be interchanged from the UHD driver on the
# HOST and the RFNoC graph. UHD does the convertion automatically back and forth
rx_streamer = graph.create_rx_streamer(1, uhd.usrp.StreamArgs("fc32", "sc16"))
rx_streamer1 = graph.create_rx_streamer(1, uhd.usrp.StreamArgs("fc32", "sc16"))
# Now connect the output of the DDC to the SEP
graph.connect("0/DDC#1", 0, rx_streamer, 0)
graph.connect("0/DDC#1", 1, rx_streamer1, 0)
graph.commit()
# WE STILL NEED TO CONFIGURE THE DDC AND THE RADIO FOR OUR APPLICATION, i.e., tune the
# radio to a part of the spectrum of interest and return some amount of bandwidth to
# capture all the trarffic within tha portion of the spectrum.
# set the radio rx freq (e.g. to 853 MHz)
radio_block.set_rx_frequency(1.5e9, 0)
# gain in dB
radio_block.set_rx_gain(20, 0)
# Set the number of samples per packet spp equal to the fftt length
radio_block.set_properties('spp:0=4096')
# receive form the receiver RX2 at a rate of 125 MHz
radio_block.set_rx_antenna("RX1", 0)
radio_block.set_rate(200e6)
# Configure the DDC radio attributes
ddc_block = uhd.rfnoc.DdcBlockControl(graph.get_block("0/DDC#0"))
ddc_block.set_input_rate(200e6, 0)
ddc_block.set_output_rate(10e3, 0)
# dspRate/sampRate = 125e6/5e6 = 5
# warning: odd decimation -> possible passband CIC roll-off
# Select an even decimation to ensure that a halfband filter is enabled ->
# -> can be done using propertie
# ddc_block.get_property_ids()
# ddc_block.set_properties("decim:0=24")
print(ddc_block.get_output_rate(0))
# Allocate space to store the received samples from the radio
num_samples = int(ddc_block.get_output_rate(0) * 5)
# num_samples = 4096 # 2048
# create some empty storage with the data type we told the streamer to return
# the samples to us, which is complex float values
radio_data = np.zeros((1, num_samples), dtype="complex64")
# To get the smples we need to send a stream commad to indicate how the device
# should send samples to us.
# create an instance of the stream command object and pass it the mode that one
# wants; which in this case is `num_done` -> get a certain number of samples and
# then be done, no more samples after that point
stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.num_done)
stream_cmd.num_samps = num_samples
# If this script is executed interactively (row by row), there is an issue.
# When one sends the stream command there is not enough time to type in the
# receive command into the interpreter.
# stream_cmd.stream_now = False
# then one sets a future time event on the stream command to tell it to start
# to send me samples 10 seconds from now. So one gets a reference to the
# motherboard controller from which one can get the timekeeper and get the
# current time on the radio and add 10 to it
# stream_cmd.time_spec = graph.get_mb_controller(0).get_timekeeper(0).get_time_now() +1
# time.sleep(0.9999)
rx_streamer.issue_stream_cmd(stream_cmd)
num_samples_received = rx_streamer.recv(radio_data, uhd.types.RXMetadata())
print(num_samples_received)
# plt.semilogy(range(np.size(radio_data[0])), np.real(radio_data[0]), "g",
# range(np.size(radio_data[0])), np.imag(radio_data[0]), "r")
# plt.show()
## For all blocks of fft_length find maximum and its index
# for i in range(5):
# bb = radio_data[0][i:2048*(i+1)]
# fft = np.fft.fft(radio_data[0][0:2048])
# fft = np.fft.fftshift(fft)
# idx = np.argmax(fft)
# amax = fft[idx]
# print(idx, amax)
# fft = np.fft.fft(radio_data[0])
# fft = np.fft.fftshift(fft)
# plt.semilogy(np.abs(fft))
# plt.scatter(np.arange(0,len(fft)), np.abs(fft), s=3, c='r')
# plt.yscale('log')
# plt.show()
while True:
radio_data = np.zeros((1, num_samples), dtype="complex64")
num_samples_received = rx_streamer.recv(radio_data, uhd.types.RXMetadata(), 1.0)
maxa = np.argmax(radio_data[0])
print(maxa, np.log10(np.abs((radio_data[0][maxa]))))
time.sleep(1)
graph.release()
_______________________________________________
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-le...@lists.ettus.com