I can't seem to find much definitive information on the best way to measure the linearity of a slope waveform (triangle, sawtooth, etc.). My best attempt was to save the (heavily averaged) waveform off my DSO, then import into MATLAB, select one half-period, fit a line to that, then compute the residuals.
Just for my own curiosity, this does it on the complete half-period, then does it again after dropping 5% at the beginning and end so that the bit of rounding at the peaks isn't considered.
So... my first instinct was to convert those residuals to percentages. Linearity is always shown as a percentage. But this gives numbers that don't quite make sense - the absolute error is roughly constant over the entire period, so this just magnifies it at lower signal levels. That seems pretty useless - I don't see the point of a measurement that comes out differently if you invert the data! It's more an analysis of how you measured the signal than of the signal itself...
And what exactly is the scalar linearity measurement - average? Maximum? Something else?
Does anybody know of any good reading on this subject? Or is anybody able to quickly point out my stupid mistake?
Disclaimer: Not the best MATLAB code. It's been a while.
% Read the file!
file = csvread ('TEK00000.CSV');
t = file(:, 1);
v = file(:, 2);
plot (t, v);
title ('Waveform');
pause;
% Find the maxima and minima. We'll use the SECOND peaks, to avoid mistaking
% the start of the waveform for a peak.
[minima] = peakfinder (v, [], [], -1);
[maxima] = peakfinder (v, [], [], 1);
minimum = minima(2);
maximum = maxima(2);
span = sort ([minimum maximum]);
% Grab the section between these points
section_t = t(span(1):span(2));
section_v = v(span(1):span(2));
% A zero will cause division error, so shift the data above zero
vpp = max(section_v) - min(section_v);
section_v = section_v - min(section_v) + (0.05 * vpp);
plot (section_t, section_v);
title ('Section of Interest');
pause;
% Find the nearest line
p = polyfit (section_t, section_v, 1);
poly_v = polyval (p, section_t);
% Residuals
resid = (section_v - poly_v);
plot (section_t, resid);
title ('Absolute Nonlinearity');
pause;
% Repeat for partial wave
t_start = floor (length (section_t) * 0.05);
t_end = length (section_t) - 2 * t_start;
psection_t = section_t(t_start:t_end);
psection_v = section_v(t_start:t_end);
plot (psection_t, psection_v);
title ('Partial Section of Interest');
pause;
p = polyfit (psection_t, psection_v, 1);
ppoly_v = polyval (p, psection_t);
presid = (psection_v - ppoly_v);
plot (psection_t, presid);
title ('Partial Absolute Nonlinearity');
pause;