Improving ‘s21 shunt-through’ measurement of low impedances – more detail

Improving ‘s21 shunt-through' measurement of low impedances canvassed a possible improvement of the s21 series-through measurement of impedance to compensate for errors in VNA port impedances that are not corrected in simpler calibration / correction schemes.

This article provides more detail on the practical test case.

A small test inductor was measured with a ‘bare' nanoVNA SOLT calibrated, firstly using s11 reflection.

Above is the R,X,|Z| plot from the s11 reflection measurement of the unknown Zu. It shows small negative resistance, a frustration with these low end VNAs that suffer thermal drift after just a few measurements. It is less than 3min since SOLT calibration.

The shunt calibration used in this case was in fact the same one used for SOLT calibration, and as my might expect, the s11 reflection impedance is essentially 50+j0Ω with measurement noise superimposed. This might not be the case in all fixtures.

Above is the R,X plot from the s11 reflection measurement of Port 2.

Above is the R,X plot of Port 1 calculated as detailed at Improving ‘s21 shunt-through' measurement of low impedances.

Above is the test fixture with the test inductor in the series-through configuration.

Above is the R,X plot of the unknown test inductor Zu calculated as detailed at Improving ‘s21 shunt-through' measurement of low impedances.

Code

The analysis performed above was done in iPython, the following is a Python export of the script.

#!/usr/bin/env python
# coding: utf-8

# In[146]:


#Copyright: Owen Duffy 2021. All rights reserved.
import math
import cmath
import skrf as rf
import os
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
#allow to run in iPython
try:
  %matplotlib inline
except:
  pass


# In[147]:


#parameters
name='Testinductor2'


# In[148]:


#populate the networks
nws11c=rf.Network(name+'-S11c.s1p')
nws11l=rf.Network(name+'-S11l.s1p')
nws11u=rf.Network(name+'-S11u.s1p')
nws21c=rf.Network(name+'-S21c.s2p')
nws21u=rf.Network(name+'-S21u.s2p')

rf.stylely({"savefig.dpi":100,"figure.figsize":(10.24,7.68)})

#common zplot framework
def zplot(f,z):
  global fig
  global ax1
  global ax2
  plt.figure(figsize=(10.24,7.68),dpi=100)
  fig,ax1=plt.subplots()
  color='r'
  l1,=ax1.plot(f/1e6,z.real,color=color,label='R')
  ax1.set_xlabel('Frequency (MHz)')
  ax1.set_ylabel('R ($\Omega$)',color=color)
  color='b'
  ax2=ax1.twinx()  #instantiate a second axes that shares the same x-axis
  l2,=ax2.plot(f/1e6,z.imag,color=color,label='X')
  ax2.set_ylabel('X ($\Omega$)',color=color)
  lines=[l1,l2]
  ax1.legend(lines,[l.get_label() for l in lines])


# In[149]:


zc=nws11c.z[:,0,0]
#print(zc)
zplot(nws21c.f,zc)
ax1.set_ylim(48,52)
ax2.set_ylim(-1,1)
ax1.set_title('Zc - {}'.format(name))
fig.tight_layout()
filename='{}-Zc.png'.format(name)
print(filename)
plt.savefig(filename)

#zc=50 #override since part used for SOLT cal


# In[150]:


zl=nws11l.z[:,0,0] #z from s11 slice
#print(zl)
zplot(nws21c.f,zl)
ax1.set_ylim(48,52)
ax2.set_ylim(-1,1)
ax1.set_title('Zl - {}'.format(name))
fig.tight_layout()
filename='{}-Zl.png'.format(name)
print(filename)
plt.savefig(filename)


# In[151]:


#print(nws21c.s[:,1,0]) #s21 slice
zs=1/  (nws21c.s[:,1,0] / (zc*(1-nws21c.s[:,1,0])) -1/zl  )
#print(zs)

zplot(nws21c.f,zs)
ax1.set_ylim(48,52)
ax2.set_ylim(-3,0)
ax1.set_title('Zs - {}'.format(name))
fig.tight_layout()
filename='{}-Zs.png'.format(name)
print(filename)
plt.savefig(filename)


# In[152]:


#zu=(zs+zl)/s21-(zs+zl)
zu= nws21u.s[:,1,0]/(1/zs+1/zl)/ (1-nws21u.s[:,1,0])
#print(zu)
print(zu[68])
print(zu[-1])

zplot(nws21c.f,zu)
ax1.set_ylim(0,0.2)
ax2.set_ylim(0,3)
ax1.set_title('Zu - {}'.format(name))
fig.tight_layout()
filename='{}-Zu.png'.format(name)
print(filename)
plt.savefig(filename)


# In[153]:


zu2= nws21u.s[:,1,0]/(1/50+1/50)/ (1-nws21u.s[:,1,0])
#print(zu)
print(nws21u.f[21])
print(zu2[21])
print(zu2[-1])

zplot(nws21c.f,zu2)
ax1.set_ylim(0,0.2)
ax2.set_ylim(0,3)
ax1.set_title('Zu- - {}'.format(name))
fig.tight_layout()
filename='{}-Zu-.png'.format(name)
print(filename)
plt.savefig(filename)


# In[154]:


References

  • Agilent. Feb 2009. Impedance Measurement 5989-9887EN.
  • Agilent. Jul 2001. Advanced impedance measurement capability of the RF I-V method compared to the network analysis method 5988-0728EN.