Cable impedance profile with NanoVNA and TDR script

NanoVNA TDR impedance
Help us grow. Share with your friends!

We have gone over NanoVNA so many times in the past. I did a complete review of the inexpensive NanoVNA last month. Furthermore, I compared it with the super-expensive Keysight N9952A Vector Network Analyzer. Finally, I wrote a small script to compute the TDR response from the S-parameter data that NanoVNA gave us. Today, I wrote a small extension to the TDR script to plot the impedance profile of a cable. In this article, we will go over the basic mathematics involved to compute the impedance profile and finally, you all get the script to try it out.

Understanding the concept

Computing TDR (time domain reflectometry) from frequency domain data results in what we call as the “impulse response”. In other words, it’s the response of the DUT (device under test) when we inject an impulse. In our previous test case where we used a segment of a cable as the DUT, the impulse went through the cable and reflected back from the open end. Remember that in our case, this impulse is imaginary because we are never sending it in the first place, instead synthesising it using the Inverse Fourier transform.

According to a Keysight Application note, we can derive the impedance profile of the cable if we obtain a step response instead of an impulse response. Now, what is a step response? The step response is when we apply a sudden step signal at the input of the DUT. A step looks like the sharp square wave except that the voltage transitions from 0V to 1V (or whatever volts) and stays there forever.

Unit step function

For those of you who don’t know, you can obtain a step response of the DUT if you already have the impulse response.

Finding impulse response and step response involve slightly advanced knowledge of signal processing. You can skip the following section.

In order to find the step response of any system, we need to convolve the impulse response with the step input.

\(y(n) = \sum_{k=-\infty}^\infty h(k)u(n-k)\)

Since, TDR response is \(0\) for \(n < 0\), the lower limit of the summation changes. Additionally, we are only interested in convolving up to \(N\) where \(N\) is the number of \(FFT\) points.  Thus, the equation changes to the following

\(y(n) = \sum_{k=0}^\infty h(k)\)

Once we obtain the step response, we are very close to plotting the impedance profile. Remember, that the \(S_{11}\) is return loss. We need to convert return loss into impedance \(Z\).

To do so, we follow a simple derivation below.

\(S_{11} = \frac{ Z_{in} – Z_o }{Z_{in} + Z_o}\)

Therefore, rearranging the terms gives us an equation to compute \(Z_{in}\) from the \(S_{11}\).

\(Z_{in} = Z_o \biggr(\frac{1 + S_{11}}{1 – S_{11}}\biggl)\)

Now, let us try to implement this in Python.

Python implementation

As mentioned earlier, the TDR script gives us the impulse response of the DUT. We now compute the step response by adding a few lines in the script.

The steps:

  1. Create a step waveform (Basically all ones in an array)
  2. Convolve it with the impulse response
  3. Transform \(S_{11}\) to \(Z\)
  4. Truncate the step response to \(NFFT\) points

The results

While testing this script, I created two test scenarios. One, with the short-circuited-ended cable. In another scenario, there are multiple cables with difference impedances and a \(50\Omega \) termination. The first cable is a \(50\Omega\) RG316, then a \(75\Omega\) RG6U and finally another \(50\Omega\) RG58. Finally, a \(50\Omega\) resistor terminates everything.

nanovna review

Short circuit cable. TDR shows a inverted peak indicating a 180 degree phase reversal. Impedance profile shows a short circuit after the given cable length.

Here, there are 3 cables. First cable is 50 Ohms, the second is a short section of 75 Ohms and the third section is 50 Ohms. Finally, it is terminated with a 50 Ohms resistor.

There are two things to observe above. The impulse response peak and the sudden spike in impedance align quite perfectly. The second thing to note here is that the open-ended cable shows a good \(50\Omega\) impedance until the point of short circuit. After the short circuit, the impedance settles down to \(0\Omega\).

In the second image, we are looking at the second scenario, where there are cables having multiple impedances. To repeat, we have \(50\Omega,\thinspace 75\Omega \thinspace and \thinspace 50\Omega\) respectively. The graph starts at \(50\Omega\), jumps to \(60\Omega\) and finally returns back to slightly higher than \(50\Omega\). Eventually, it settles at \(50\Omega\) corresponding to the resistor value.

In another experiment, I terminated the cable end with \(100\Omega\) like shown below.

The cable terminated with a 100 Ohm resistance

Impedance profile of cable terminated with 100E resistor

The full script is below.

Let me know what you think about this script in the comments below.

If you haven’t purchased a NanoVNA yet, go ahead and get one. It’s worth it!

BUY nanoVNA – Amazon 

Incoming search terms:


Salil is an electronics enthusiast working on various RF and Microwave systems. In his free time he writes on the blog, talks over ham radio or builds circuits. He has Yaesu FT2900R VHF transceiver, FT450D HF transceiver and a TYT UV8000E Handheld transceiver.

You may also like...

8 Responses

  1. Neha says:

    Very nicely done …good job Salil

  2. Anna says:

    Awesome post, thanks for sharing.

  3. Ricardo Escobar says:

    Saludos desde Ecuador…
    Felicitaciones por excelentes aportes…
    Puede guiarme o indicarme como corro los script

  4. Very informative tidbit of code. Thank you for sharing.
    if you change line 42 and 43 to:
    ax1.set_ylabel(“Reflection Magnitude”).set_color(‘green’)
    ax2.set_ylabel(“Impedance (Ohms)”).set_color(‘red’)
    then the labels will match the plotted curve colors to make the connections a little more obvious

  5. Velat says:

    Hi Salil,

    Thak you for sharing your works with us.

    When i run the script with the open ended coax cable, the measurement and the plot coming correct, but when i run the script with the shorted cable’s s1p parameter, the plot shows the inverse peak at the right length,but the outcome of the script gives wrong measurement. Can you help me to deal with it?

    • nuclearrambo says:

      I believe the inverse peak indicates 180 degree phase shift from the shorted point which is correct. I think the plot is showing “real+imag” instead of “abs(real, imag)”.

      • Velat says:

        Thanks for the reply. I figure out that script includes a line to get max peak point at open ended cable. When shorted, the inverse peak occurs and script line should be corrected to get min peak point. And here is another question; Why did you take NFFT as 16384? What does that NFFT mean in our script? It’s 2^n, and n=14 but where did we get that 14 from?

  6. Julien says:


    Note that scikit-rf also provides methods to make time domain calculations:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.