Skip to content

Instantly share code, notes, and snippets.

@dk2ro
Last active December 13, 2018 21:37
Show Gist options
  • Save dk2ro/8636a14646d0d128168d097fd357b5c8 to your computer and use it in GitHub Desktop.
Save dk2ro/8636a14646d0d128168d097fd357b5c8 to your computer and use it in GitHub Desktop.
Frequency response measurement of a two-port with the ADALM-PLUTO
import iio
import time
import struct
import matplotlib.pyplot as plt
import numpy.fft as fft
import numpy as np
import math
def set_rx_freq(freq):
d.channels[0].attrs["frequency"].value = str(int(freq))
def set_tx_freq(freq):
d.channels[1].attrs["frequency"].value = str(int(freq))
def setup_dds(freq, scale):
dds.channels[0].attrs["frequency"].value = str(int(freq))
dds.channels[2].attrs["frequency"].value = str(int(freq))
dds.channels[0].attrs["scale"].value = str(scale)
dds.channels[2].attrs["scale"].value = str(scale)
def set_tx_gain(gain):
d.find_channel("voltage0", True).attrs["hardwaregain"].value = str(gain)
def set_rx_gain(gain):
d.find_channel("voltage0").attrs["hardwaregain"].value = str(gain)
def sweep(startf, stopf, step):
BUFFLEN = 2 ** 6
rx_gain = 0
set_rx_gain(rx_gain)
tx_gain = -20
start_gain = tx_gain
set_tx_gain(tx_gain)
rxbuff = iio.Buffer(rx, BUFFLEN)
iq_samples = [None] * BUFFLEN
steps = int((stopf - startf) / step) + 1
print("Number of points: " + str(steps))
valsx = np.zeros(steps)
valsy = np.zeros(steps)
set_rx_freq(startf)
set_tx_freq(startf)
freq = startf
for j in range(0, 10):
rxbuff.refill()
b = rxbuff.read()
k = 0
while freq <= stopf:
set_rx_freq(freq)
set_tx_freq(freq)
freq += step
rxbuff.refill()
b = rxbuff.read()
for i in range(0, BUFFLEN):
iq_samples[i] = complex(struct.unpack("h", b[i * 4:i * 4 + 2])[0],
struct.unpack("h", b[i * 4 + 2:i * 4 + 4])[0])
mfft = abs(fft.fft(iq_samples))
s = 8
s21 = 20 * math.log10(abs(mfft[s]) / float(BUFFLEN))
#plt.plot(mfft)
#plt.show()
valsy[k] = s21 - tx_gain - rx_gain
valsx[k] = freq
k += 1
#o=raw_input()
newgain = False
if s21 < 0:
if tx_gain <= -10:
tx_gain += 10
set_tx_gain(tx_gain)
newgain = True
elif rx_gain <= 60:
rx_gain += 10
set_rx_gain(rx_gain)
newgain = True
if s21 > 30:
if rx_gain >= 30:
rx_gain -= 10
set_rx_gain(rx_gain)
newgain = True
else:
tx_gain -= 10
set_tx_gain(tx_gain)
newgain = True
if newgain:
print("new gain tx " + str(tx_gain) + " rx " + str(rx_gain) + " " + str(freq))
for j in range(0, 10):
rxbuff.refill()
b = rxbuff.read()
return valsx, valsy
def smooth(y, box_pts):
"""stolen from https://stackoverflow.com/a/26337730"""
box = np.ones(box_pts) / box_pts
y_smooth = np.convolve(y, box, mode='same')
return y_smooth
ctx = iio.NetworkContext("pluto.local")
d = ctx.find_device("ad9361-phy")
rx = ctx.find_device("cf-ad9361-lpc")
dds = ctx.find_device("cf-ad9361-dds-core-lpc")
def init():
rxI = rx.find_channel("voltage0")
rxQ = rx.find_channel("voltage1")
rxI.enabled = True
rxQ.enabled = True
txI = dds.find_channel("altvoltage0",True)
txQ = dds.find_channel("altvoltage2",True)
txI.enabled = True
txQ.enabled = True
txI.attrs["scale"].value = "1"
txQ.attrs["scale"].value = "1"
d.find_channel("TX_LO", True).attrs["powerdown"].value = "0"
d.find_channel("voltage0").attrs["sampling_frequency"].value = "2084000"
d.find_channel("voltage0").attrs["rf_bandwidth"].value = "1000000"
d.find_channel("voltage3",1).attrs["rf_bandwidth"].value = "1000000"
d.find_channel("voltage0").attrs["gain_control_mode"].value = "manual"
init()
setup_dds(250000, 0.3)
time.sleep(0.5)
setup_dds(250000, 0.3)
start = 70e6
stop = 6000e6
step = 1000e3
slen = 500
slen1 = slen/2
slen2 = -slen1
print(d.find_channel("voltage0").attrs["sampling_frequency"].value)
raw_input("Calibration, please connect through and press enter.")
cvalsx,cvalsy = sweep(start,stop,step)
raw_input("Now please connect dut and press enter.")
valsx, valsy = sweep(start, stop, step)
scvalsy = smooth(cvalsy, slen)[slen1:slen2]
svalsy = smooth(valsy, slen)[slen1:slen2]
svalsx = valsx[slen1:slen2]
plt.figure()
plt.subplot(222)
plt.plot(valsx, valsy-cvalsy)
plt.subplot(224)
plt.plot(svalsx, svalsy-scvalsy)
#plt.plot(valsx, valsy-cvalsy)
plt.subplot(221)
plt.plot(valsx, valsy, label="val")
plt.plot(valsx, cvalsy, label="cval")
plt.legend()
plt.subplot(223)
plt.plot(valsx[slen1:slen2], svalsy, label="sval")
plt.plot(valsx[slen1:slen2], scvalsy, label="scval")
plt.legend()
#plt.plot(valsx[50:-50], smooth(valsy, 100)[50:-50])
#
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment