T2400391-v1

Timing Analysis for Fast DuoTone Signals

Summary

2-sec non-linear fit results:

Fit @64K
960: 0.10us
1920: 0.095us
3840: 0.080us
15424: −0.18us

Fit @16K
960: 0.10us
1920: 0.095us
3840: 0.080us
15424: +2.83us (fitted with 960/961)

Fitting uncertainty typically less than 1 ns.

There is also a question of ambiguity. What happens if you fit with start conditions that are one cycle off? Looking at the normalized (χ^2) when fitting at 16K, it changes by:

(χ^2)@16K
960: 5.7 -> 680
1920: 7.2 -> 175
3840: 14 -> 56
15424: 52 -> 612 (fitted with 960/961)

At the aliased 15424 frequency there is also the ambiguity of a slip of 1 or more fast cycle.

Fit@16K
15424: -257us, (χ^2): 52 -> 85 (slip 1 fast cycle, fitted with 960/961)
15424: +2.8us (opposite amplitude), (χ^2): 52 -> 51 (slip 2 fast cycle, fitted with 960/961)
15424: +263us, (χ^2): 52 -> 88 (slip 3 fast cycle, fitted with 960/961)

I would argue 15424/15423 is unusable due to the ambiguity of the decimation. At 3840/3841 Hz, the (χ^2) difference between the good solution and the one cycle off, is somewhat marginal. Recording the DuoTone at a higher rate won’t help here. If we want 3840, we probably should test a wider frequency gap, maybe 3840/3843 Hz.

The last page shows a plot of the linear regression results as function of the number of data points that are included on each side of the zero crossing. The total number of points included is twice that plus 1. We use 6 points on each side for evaluating the 960/961 DuoTone in the IOP. This is about half way up towards maximum amplitude. For 1920/1921Hz we should probably use 3, and for 3840/3841 no more than 2.

Online duotone measurements for ADC/DAC:

960/961: 0.1 μs / 61 μs
1920/1920: 0.1 μs / 61 μs
3840/3841: 0.1 μs / 61 μs  
15424/15423: −0.2 μs / 61 μs

Init

Plot Options

$TextStyle={FontFamily->"Helvetica",FontSize->13};

plotopt=Sequence@@{GridLines->Automatic,Frame->True,FrameStyle->Thickness[0.0025],BaseStyle->{FontSize->12}};

plotoptn[n_Integer?(#>0∧#<6&)]:=Sequence@@{GridLines->Automatic,Frame->True,FrameStyle->Thickness[0.0025],PlotStyle->Take[{Purple,Brown,Darker[Green],Blue,Red},-n],BaseStyle->{FontSize->12}};
plotoptn[n_Integer?(#≤0∨#≥6&)]:=plotopt

plotoptnthin[n_Integer?(#>0∧#<6&)]:=Sequence@@{GridLines->Automatic,Frame->True,FrameStyle->Thickness[0.0025],PlotStyle->Take[{#,Thickness[0.0025]}&/@{Purple,Brown,Darker[Green],Blue,Red},-n],BaseStyle->{FontSize->12}};

mylegend[labels_List,pos_:Right]:={Placed[LineLegend[labels,LabelStyle->{FontSize->11},LegendMargins->2,LegendFunction->(Framed[#,Background->White]&)],pos]}

Functions

retime[dat_,n_:14]:=Prepend[Drop[dat\[Transpose],1],N[((Range[0,Length[dat]-1])/(2^n))-1]]\[Transpose]

sel1[dat_,sample_,n_:14]:=retime[dat,n][[(2^n)+1-sample;;(2^n)+1+sample]]

Import

duotone_960Hz_2sec.txt (64K):
duotone_1920Hz_2sec.txt (64K):
duotone_3840Hz_2sec.txt (64K):
duotone_15424Hz_2sec.txt (64K):
Really stupid data format!

Filter Delay:
Std 4x (64K -> 16K) : 43.5 us
Mod 32x(64K -> 16K) : 40.0 us
Old 8x (512K->64K) :  19.7 us
New 8x (512K->64K) :  14.5 us
Old 8x (512K->64K) + Std 4x (64K -> 16K) : 63.2 us
New 8x + Mod 32x (512K -> 16K) : 54.4 us

4 cycle delay: 7.6 us
3 cycle delay: 5.7 us

onedrive=Environment["OneDriveConsumer"];
path=onedrive<>"\\Documents\\Mathematica\\Timing\\";

dat1=Flatten[Drop[#,1]& /@ Drop[Drop[Import[path<>"duotone_960Hz_2sec.txt","Table"],4],{8193,8196}]]
dat2=Flatten[Drop[#,1]& /@ Drop[Drop[Import[path<>"duotone_1920Hz_2sec.txt","Table"],4],{8193,8196}]]
dat3=Flatten[Drop[#,1]& /@ Drop[Drop[Import[path<>"duotone_3840Hz_2sec.txt","Table"],4],{8193,8196}]]
dat4=Flatten[Drop[#,1]& /@ Drop[Drop[Import[path<>"duotone_15424Hz_2sec.txt","Table"],4],{8193,8196}]]
dat0=Range[0,Length[dat1]-1]/(2.^16);
dat=Transpose[{dat0,dat1,dat2,dat3,dat4}]
dat1//Length
dat2//Length
dat3//Length
dat4//Length

Re-time

data=retime[dat,16]

Check

sel1[data,6,16]//TableForm

Full Fit Analysis

Plots

ListPlot[{Take[#[[{1,2}]]&/@retime[data,16],{1,70,1}],Take[#[[{1,3}]]&/@retime[data,16],{1,70,1}],Take[#[[{1,4}]]&/@retime[data,16],{1,70,1}],Take[#[[{1,5}]]&/@retime[data,16],{1,70,1}]},Frame->True,GridLines->Automatic,Joined->True]

ListPlot[{Take[#[[{1,2}]]&/@retime[data,16],{1,70,4}],Take[#[[{1,3}]]&/@retime[data,16],{1,70,4}],Take[#[[{1,4}]]&/@retime[data,16],{1,70,4}],Take[#[[{1,5}]]&/@retime[data,16],{1,70,4}]},Frame->True,GridLines->Automatic,Joined->True]

960/961 Hz

Fit 960/961 Hz

ListPlot[Take[#[[{1,2}]]&/@retime[data,16],{1,-1,4}]]

res1=NonlinearModelFit[#[[{1,2}]]&/@retime[data,16],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res1["BestFitParameters"]
res1["ParameterErrors"]
res1["EstimatedVariance"]

ListPlot[Take[res1["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

960/961 Hz Decimated

ListPlot[Take[#[[{1,2}]]&/@retime[data,16],{1,-1,4}]]

res6=NonlinearModelFit[Take[#[[{1,2}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res6["BestFitParameters"]
res6["ParameterErrors"]
res6["EstimatedVariance"]

ListPlot[Take[res6["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,2}]]&/@retime[data,16],{(2^16)-31,(2^16)+32,4}]],Plot[res6[x],{x,((-31-1)/(2^16)),((32-1)/(2^16))}],Frame->True,PlotRange->All]

960/961 Hz Decimated: One cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,2}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c, ((1.*^6)/961)},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

1920/1921 Hz

Fit 1920/1921 Hz

ListPlot[Take[#[[{1,3}]]&/@retime[data,16],{1,-1,4}]]

res2=NonlinearModelFit[#[[{1,3}]]&/@retime[data,16],a Sin[2π 1920(t-1*^-6c)]+a Sin[2π 1921( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res2["BestFitParameters"]
res2["ParameterErrors"]
res2["EstimatedVariance"]

ListPlot[Take[res2["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,3}]]&/@retime[data,16],{(2^16)-20,(2^16)+20}]],Plot[res2[x],{x,((-20-1)/(2^16)),((20-1)/(2^16))}],Frame->True,PlotRange->All]

1920/1921 Hz Decimated

res7=NonlinearModelFit[Take[#[[{1,3}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 1920(t-1*^-6c)]+a Sin[2π 1921( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res7["BestFitParameters"]
res7["ParameterErrors"]
res7["EstimatedVariance"]

ListPlot[Take[res7["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

1920/1921 Hz Decimated: One cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,3}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 1920(t-1*^-6c)]+a Sin[2π 1921( t-1*^-6c)]+e,{{a,8000},{c, ((1.*^6)/1920)},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

3840/3841 Hz

Fit 3840/3841 Hz

ListPlot[Take[#[[{1,4}]]&/@retime[data,16],{1,-1,4}]]

res3=NonlinearModelFit[#[[{1,4}]]&/@retime[data,16],a Sin[2π 3840(t-1*^-6c)]+a Sin[2π 3841( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res3["BestFitParameters"]
res3["ParameterErrors"]
res3["EstimatedVariance"]

ListPlot[Take[res3["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,4}]]&/@retime[data,16],{(2^16)-1817,(2^16)-1797}]],Plot[res3[x],{x,((-1817-1)/(2^16)),((-1797-1)/(2^16))}],Frame->True,PlotRange->All]

3840/3841 Hz: One cycle mismatch

rr=NonlinearModelFit[#[[{1,4}]]&/@retime[data,16],a Sin[2π 3840(t-1*^-6c)]+a Sin[2π 3841( t-1*^-6c)]+e,{{a,8000},{c, ((1.*^6)/3840)},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

3840/3841 Hz Decimated

res8=NonlinearModelFit[Take[#[[{1,4}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 3840(t-1*^-6c)]+a Sin[2π 3841( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res8["BestFitParameters"]
res8["ParameterErrors"]
res8["EstimatedVariance"]

ListPlot[Take[res8["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

3840/3841 Hz Decimated: One cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,4}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 3840(t-1*^-6c)]+a Sin[2π 3841( t-1*^-6c)]+e,{{a,8000},{c, ((1.*^6)/3840)},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

15424/15423 Hz

15424/15423 Hz

ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{1,-1,4}]]

res4=NonlinearModelFit[#[[{1,5}]]&/@retime[data,16],a Sin[2π 15424(t-1*^-6c)]+a Sin[2π 15423( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res4["BestFitParameters"]
res4["ParameterErrors"]
res4["EstimatedVariance"]

ListPlot[Take[res4["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Ordering[res4["FitResiduals"],-10]

(2^16)-63729

Show[ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{(2^16)-5,(2^16)+5}]],Plot[res4[x],{x,((-5-1)/(2^16)),((5-1)/(2^16))}],Frame->True,PlotRange->All]

15424/15423 Hz Decimated

ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{1,-1,4}]]

res5=NonlinearModelFit[Take[#[[{1,5}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c,0},{e,0},{d,0}},t]
res5["BestFitParameters"]
res5["ParameterErrors"]
res5["EstimatedVariance"]

ListPlot[Take[res5["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{(2^16)-31,(2^16)+32,4}]],Plot[res5[x],{x,((-31-1)/(2^16)),((32-1)/(2^16))}],Frame->True,PlotRange->All]

15424/15423 Hz Decimated: One cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,5}]]&/@retime[data,16],{1,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c, ((1.*^6)/960)},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

15424/15423 Hz Decimated: One fast cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,5}]]&/@retime[data,16],{2,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c, 0},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{(2^16)-31+1,(2^16)+32+1,4}]],Plot[rr[x],{x,((-31-1)/(2^16)),((32-1)/(2^16))}],Frame->True,PlotRange->All]

15424/15423 Hz Decimated: Two fast cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,5}]]&/@retime[data,16],{3,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c, 0},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{(2^16)-31+2,(2^16)+32+2,4}]],Plot[rr[x],{x,((-31-1)/(2^16)),((32-1)/(2^16))}],Frame->True,PlotRange->All]

15424/15423 Hz Decimated: Three fast cycle mismatch

rr=NonlinearModelFit[Take[#[[{1,5}]]&/@retime[data,16],{4,-1,4}],a Sin[2π 960(t-1*^-6c)]+a Sin[2π 961( t-1*^-6c)]+e,{{a,8000},{c, 0},{e,0},{d,0}},t]
rr["BestFitParameters"]
rr["ParameterErrors"]
rr["EstimatedVariance"]

ListPlot[Take[rr["FitResiduals"],{1,-1,1}],Frame->True,PlotRange->All]

Show[ListPlot[Take[#[[{1,5}]]&/@retime[data,16],{(2^16)-31+3,(2^16)+32+3,4}]],Plot[rr[x],{x,((-31-1)/(2^16)),((32-1)/(2^16))}],Frame->True,PlotRange->All]

Online Analysis

Equations

takeColumn[data_,col_]:={#[[1]],#[[1+col]]}&/@data

xAtOne[x_?NumberQ]:=(x>0.999999) && (x<1.000001)

rescale[y_,slope_,f_:960.5]:=y (1+((2 (f^2) (π^2) (y^2))/(3 (slope^2))))

N[1*^6 (2^(-16)), 15]
N[(2/3)(π^2) ((((9605/10000000)))^2),15]

zeroCrossing[l_,stepofs_:5,stepnum_:11,f_:960.5]:=Module[{x,y,mean,n,ix0,lsel,estD,sumx,sumy, sumxx,sumxy,den,offset,slope,step,zerocross},
mean=N[Mean[Last/@l]];
(*Print["mean = ",mean];*)
(*Print["ix0 = ",ix0];
Print["stepofs = ",stepofs];*)
ix0=Length[l]/2+1;
lsel={1*^6#[[1]],#[[2]]-mean}&/@Take[l,{ix0-stepofs,ix0-stepofs+stepnum-1}];
(*Print["y0 = ",lsel];*)
If[First[lsel][[2]]Last[lsel][[2]]>0,Return[1000]];
(*Print["lsel = ",lsel];*)
estD=((Last[lsel][[2]]-First[lsel][[2]])/(Last[lsel][[1]]-First[lsel][[1]]));(*Print[estD];*)
x=First/@lsel;
y=rescale[#,estD,f 1*^-6]&/@Last/@lsel;
(*Print["yold = ",Last/@lsel];*)
(*Print["y1 = ",Transpose[{x,y}]];*)
n=Length[x];
step=l[[2,1]]-l[[1,1]];
(*Print["x = ",x];
Print["y = ",y];
Print["n = ",n];
Print["step = ",step];*)
sumx=Plus@@x;
sumy =Plus@@y;
sumxx=Plus@@((x^2));
sumxy=Plus@@(x y);
den=n sumxx-(sumx^2);
offset=((-sumx sumxy+sumxx sumy)/den);
slope=((-sumx sumy+n sumxy)/den);
zerocross=-(offset/slope);
zerocross]

Evaluation

r3=zeroCrossing[retime[takeColumn[data,3],16],#,2 #+1,3840.5]&/@Range[1,8]

Check

sel1[data,16,16]//TableForm

960/961 Hz

r1=zeroCrossing[retime[takeColumn[data,1],16],#,2 #+1,960.5]&/@Range[1,16]

1920/1921 Hz

r2=zeroCrossing[retime[takeColumn[data,2],16],#,2 #+1,1920.5]&/@Range[1,16]

3840/3841 Hz

r3=zeroCrossing[retime[takeColumn[data,3],16],#,2 #+1,3840.5]&/@Range[1,8]

Show[Plot[{0.08015,0.09518,0.1005},{x,0.8,16.2},FrameLabel->{"Points on each side", "Zero crossing (μs)"},PlotRange->{{0,17},{-0,0.12}},Evaluate[plotoptnthin[3]],ImageSize->450],ListPlot[{r3,r2,r1},plotoptn[3],PlotLegends->mylegend[{"3840/3841","1920/1921","960/961"}]]]