% Measure Cable Length

% WARNING does not work with long lengths of cable
% I've tested 2m which works, but 20m doesn't.

% Configuration Section  -------------------------------------------------

% the serial port that the nanoVNA is connected to
nanoVNAport = '/dev/tty.usbmodem4001';

% End  of Configuration  
% Do not edit below here -------------------------------------------------

% Method based on alex_m original
% see nanovna.m in https://github.com/qrp73/NanoVNA-MATLAB

hCom = nanoOpen(nanoVNAport);

netwk = nanoGetData(hCom);

disp('Measuring cable connected to ch0 ...')
vf = input('Velocity factor of cable? ');

% get TDR step response
    
% fit to a rational function object
tdrfit = rationalfit(netwk.Frequencies, rfparam(netwk, 1,1), 'NPoles', 101);

% Parameters for a step signal
Ts = 3e-12;
N = 32768;
Trise = 1e-10;

% Calculate the step response for TDR
[tdr,t1] = stepresp(tdrfit,Ts,N,Trise);
tdrz = arrayfun(@(x) 50 * (1+x)/(1-x), tdr);

% search for last dip

% invert the values to turn dips into peaks
invtdrz = max(tdrz) - tdrz;

% find the dips
[pk,indx] = findpeaks(invtdrz, 'NPeaks', 100);

% find the big dip at the end
diffs = abs(diff(pk));
[dummy, x] = max(diffs);

% calculate the return trip time in seconds
tRet = (indx(x) * 100)/N;

% calculate the cable length from the return trip time
l = (tRet / 1e9) * (physconst('lightspeed') * vf)/2;

disp(['The calculated cable length is ' num2str(l) ' metres.'])

% optionally plot the TDR Response  
continueAns = input('Show TDR Response plot (Y/n)', 's');
if isempty(continueAns)
    continueAns = 'Y';
end
if strcmpi(continueAns, 'Y')
    fig = figure('Name','TDR Step Response', 'NumberTitle','off');
    plot(t1*1e9, tdrz, 'LineWidth',2);
    ylabel('TDR Step Response [Ohm]');
    xlabel('Delay [ns]');
    xlim([0 Ts*N*1e9])
    ylim([10 60])
    grid on;
    grid minor;
end

nanoClose(hCom);