Author Topic: Open source VNA calibration, conversion, touchstone read-write from python or C!  (Read 260 times)

0 Members and 2 Guests are viewing this topic.

Offline scott_guthridgeTopic starter

  • Newbie
  • Posts: 2
  • Country: us
Hi everyone.  For folks working on open hardware vector network analyzers, I'd like to put in a plug for my open source VNA software library, libvna, available in python or C.  It supports Linux, Windows and MacOS.  The library contains extensive VNA calibration including SOLT, TRL, TXYZ (a.k.a "unknown through"), as well as all the others: LRL, TRM, LRM, LXYZ, LRRM, etc. If it doesn't have a specific solver for the calibration, it uses a general solver -- all that's necessary is that there are a sufficient number of calibration conditions.  It supports 8, 12 and 16 error term models.  It can also model measurement and connection non-repeatability errors.  The library also has full conversion routines between S, Y, Z, H, G, A (ABCD), B (inverse ABCD), T (scattering transfer) and U (inverse scattering transfer) parameters.  It loads and saves Touchstone v1 and v2 file formats as well as a more general space-separated value .npd (network parameter data) format.

From python3:
pip install libvna

Python documentation is here: https://libvna.readthedocs.io/latest/   There are extensive examples in the docs.
Python/Cython source is here: https://github.com/scott-guthridge/pylibvna
C source is here: https://github.com/scott-guthridge/libvna

There is definitely some overlap with scikit-rf, but we've taken fairly different approaches and I believe that this library is complementary to that one.  Please try it out and let me know what you think.
 

Offline shabaz

  • Frequent Contributor
  • **
  • Posts: 263
Hi Scott,

This is great, thanks for sharing!

I gave it a shot, but wanted to run it by you, in case I’m doing something wrong. I’m not a calibration expert, so I apologize if I’m making basic mistakes here. On the other hand, if I can use it, then almost anyone probably can! : )

I have an OSL kit called SDR-Kits Female Calibration Kit of Rosenberger parts (PDF datasheet) and it comes with offset delay (or electrical length) values. Ordinarily, I would plug those values into the VNA, but I recently got a Nano-VNA (the H4 variant), and I’m completely new to these Nano instruments. I don’t think I can configure those values into the instrument.

The NanoVNA appears to be applying some default calibration, I left that calibration enabled (with hindsight I would have switched the default calibration off, I can do that if you think it’s needed). I left the NanoVNA at all the default settings for now, and it is set to a span of 50 kHz – 900 MHz.

Next, I connected a short length of cable (~ 90 mm) to the NanoVNA, and then attached the open/short/load, and obtained the .s1p files for the Open/Short/Load standards in that kit.
I named the files open_meas.s1p, short_meas.s1p and load_meas.s1p (attached in the zip file).

Next, I ran the program cal_create.py, and it generated a file called 1x1.vnacal

Then, I attached a DIY 100-ohm load (two 200-ohm resistors in parallel across the back of a SMA female connector) and saved the measurement as dut_meas.s1p

I ran the program cal_apply.py, and it converted to a file called dut_meas_corrected.s1p

It certainly looks spot-on (Smith chart output attached). Have I done it right? It feels odd not having typed the calibration standard offset delay (or electrical length) values anywhere, so I was wondering if I've done something wrong.

Many thanks.
 

Offline scott_guthridgeTopic starter

  • Newbie
  • Posts: 2
  • Country: us
One problem I see is that the frequencies were linearly spaced in your measurements, but given as log spaced to the libvna.cal.Solver object.  It's better to grab the actual frequency vector from one of the input files than to use linspace or logspace to compute it.  It's interesting that you used by scipy.rf and libvna together -- nothing wrong with that -- but you can write it with fewer lines if you use libvna.data.NPData to read the files.  I'm attaching a modified version of cal_create.py that fixes the frequency vector mismatch and loads using libvna.data.NPData instead of scikit.rf.

As for the offset delay values of your standards, those suggest that the standards may have differing lengths relative to the reference plane.  It's possible to compensate for those offsets by altering the -1, 1, and 0 s11 values given to the add_single_reflect calls using:

    s11_measured = exp(-4 pi j x) s11_actual

Where x is the electrical length (in wavelengths) in one direction.  You'd pass the s11_measured value to the add_single_reflect methods, where s11_actual is -1, 1 or 0.  For the match (assuming it's perfect), the offset shouldn't matter.  A negative value of x would indicate that the standard lies in front of the reference plane.  You might want to understand how the maker of the standards defines the location of the reference plane because you want your DUT to lie exactly in the same place.

I should add a method to add length offsets to the ports of any arbitrary standard.

Otherwise, your code looks good.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf