You lot make me feel so thick. I throw up a topic and then years later it is still being bandied about, showing yet more subtlties that can be squeezed from a Prop
If only I were more worthy.
(I never found out what it was that I said that apparently caused Heater. to go off and make Zog)
Hey we just test it, first on 3m 75 Ohm digital Belden coax, it works (in feet ;-) ).
We try with 75 Ohm termination, no change in distance ???
We try 100m we get 0 .... Time over .
I had a play with Bean's code, and have recast it as a Spin implementation.
A number of things I noticed: The low order bits of the FRQA values are critical, so I added another
bit even lower, in both of the FRQA values. Round the freqeuncies up to $10200000,$0FE00000 and bang,
it just locks rock steady...
Different COGs behave differently - with the generate COG as 1, and measurement 2, it seems to be much
less temperature sensitive. Switch them round and there is a marked temperature sensitivity (place finger on the
Prop and watch the values change). Perhaps this varies from chip to chip, could be related to PLL stability?
[note my setup has 47 ohm protection resistors on every pin so its not quite the same electrically]
I also used a lower value resistor (120 + 47 = 167ohms) to make the voltage steps larger (I think 220 ohms
is rather high to drive a 50 ohm cable.
Oh yes, the spin version, prints result in metric assuming polythene dielectric:
Different COGs behave differently - with the generate COG as 1, and measurement 2, it seems to be much
less temperature sensitive. Switch them round and there is a marked temperature sensitivity (place finger on the
Prop and watch the values change). Perhaps this varies from chip to chip, could be related to PLL stability?
Best operation needs the 'chasing PLL' to never lock, or phase-snap, to the main Sysclk.
Parasitic inductances and capacitance and crosstalk will make that aspiration vary a little from COG to COG.
Even within a COG, PLL for CTRA may be not quite the same as PLL for CTRB ?
Maybe there a Prop die photo somewhere showing Pwr/Gnd metalization and COG locations ?
That could give hints for the best COG pair to choose ?
My next experiment was to use CAT5 cable and use two pins driven differentially in PLL mode (%0_00011_000),
82 ohm resistors on each to send differential pulses along a twisted pair. Two more pins sensed the wires
(although currently I only use one of them, in theory both counters could be used to measure them simultaneously).
Seemed to work - the waveforms with 100 ohm resistors looked a bit marginal, so I reduced to 82 ohms. The nominal 100
ohm impedance of the UTP sits in the middle as a resistive divider and the symmetry should mean that both sense pins
give the same information (both are connected to symmetrically load the cable end though).
With an approx 5m length of CAT5 I could get reasonable readings for a single length, find a split halfway along,
and I connected the pairs together to send the signal back along another pair to get twice the length.
Arguably differential mode could be sensed better with a high speed comparator on the twisted pair, but I didn't have
one knocking about.
Two more pins sensed the wires
(although currently I only use one of them, in theory both counters could be used to measure them simultaneously).
.. Arguably differential mode could be sensed better with a high speed comparator on the twisted pair, but I didn't have
one knocking about.
A high speed comparator is another part, and variation, and I like the idea of two counters sensing both wires, as that will report a break in one, and could even report skew ?
Interesting thing: I was trying to increase the non-clock-locked frequency. The datasheet says to keep the NCO frequency (feeding the PLL) in the range of 4 MHz to 8 MHz (page 10). Well, at least for my test prop, I found I could get stable outputs with a NCO frequency up to 14 MHz. But the cool part was, once I requested a frequency above about 14.4 MHz, the PLL output basically stayed clamped there, and it seems the output is no longer locked to the system clock. So, simply using a PLL counter output, using FRQA := POSX gives me a nice non-clock-locked pin...I can just use a counter in Spin instead of tying up a cog! The VCO frequency is about 225 MHz, and dividing by 128 means my pin is toggling at 1.8 MHz (which is about 3x faster than the 625 kHz used in the demo). You can just change the PLL div to get higher frequencies, but this is working for me.
(I'm trying to hack this code into a really simple metal detector, instead of a wire-length measurement tool.)
Jonathan,
Excellent discovery. I'll have to try that when I get a chance.
Right now I'm working on using the Propeller for a "Continuous Time Stamping" counter. A really cool way to get upwards of 10x frequency resolution than a standard recip counter.
Let me know if I understand: as a quick first order approximation, I would probably wait for the first transition, then start acquiring a constant number of transitions, timing each one. The equation would be something like: Tcross(cross_num) = period * cross_num, where cross_num is an incrementing integer, and Tcross is referenced to the original transition. The least squares error value of period would be = sum( cross_num * Tcross ) / sum( cross_num * cross_num ). And of course, if you use a constant number of samples, that sum in the denominator would be a constant. Of course, that is the period, so inverting the equation to get frequency means the *numerator* would be a constant. Depending on the maximum frequency you were expecting to encounter, you could even do the running summation of "cross_num * Tcross" as it occurs...no need to store the samples.
Jonathan,
Yes, that is basically it. It is a little more complex because you need to use the FULL linear regression formula (at least the simple formula didn't work for me).
To be able to count a higher freq, I store the counts, then post-process them and send the value to an excel spreadsheet to do the calculations.
Attached is some test code. To get above about 1.5 MHz sampling, I had to timestamp every 2 periods. This can go up to about 2.353 MHz on my 80 MHz demo board, making a single period width 34 clocks. The value returned seems pretty accurate (within a few Hz until 2 MHz, assuming the clock speed is golden, of course).
Jonathan
P.S. Bean, you were correct, using the simplified "gain only" version of the LSE equation was less accurate.
Good point. N (sum1) and sumX are trivial to accumulate, but computing sumXX at the end would save the multiplication of X*X every time through the processing loop. Of course doing that math in Spin would probably end up being slower. Also note that I make sure my running sumYX does not go negative, so there is an early exit...not all buffered samples may end up getting used. The code can early exit for timeouts as well, so N is unfortunately not going to be a constant, otherwise a bunch of this could be pre-computed.
Sorry for continuing to hijack this thread, but here is the latest frequency counter...no floating point math needed, it does it all internally with 64-bit integers. Here's the relevant comment block:
{{
Continuous Time Stamping on the propeller
Jonathan "lonesock" Dummer
Note: I measure 2x periods at a time, because
I wanted rates above 2MHz, and could not sample
faster than at about 1.5 MHz when capturing
single periods.
Using a Least Squares Error fit:
timestamp(i) = Period * i
so, LSE gives a matrix like:
[ sum( 1 ) sum( i ) ] { offset } { sum( ts ) }
[ ] * { } = { }
[ sum( i ) sum(i*i) ] { period } { sum( ts*i ) }
I use variable names X and Y instead of i and timestamp.
Cramer's Rule for solving for the period is:
period = (sum1*sumYX - sumX*sumY) / (sum1*sumXX - sumX*sumX)
Bean pointed out that:
sumX = sum1 * (sum1 + 1) / 2
sumXX = sum1 * (sum1 + 1) * (2 * sum1 + 1) / 6
Using those substitutions, I get:
period = (12*sumYX - 6*(sum1+1)*sumY) / (sum1*(sum1+1)*(sum1-1))
Note that internally I actually do timestamps every 2 periods
to increase the max sampleable frequency. This means I would
have been solving for 2*Period, so instead I simply modified
the numerator of the above equation to use a 6 and 3 instead
of 12 and 6.
Finally, to get the actual frequency, the user would
divide clkfreq by the period. Instead of trying that,
I simply generate the inverse of the period as a 32-bit
fraction. That way, recovering the frequency in Spin is
as easy as:
freq := clkfreq ** inv_period_frac
}}
The results are displayed in picoSeconds and judging from the numbers it looks like a couple picosecond resolution.
I've not verified that this is acurrate. I just got some reasonable numbers and it looks okay to me.
MAX35101 Time-to-Digital Converter with Analog Front-End
TIME MEASUREMENT UNIT
Measurement Range tMEAS Time of flight 8-8000 μs
Time Measurement Accuracy tACC Differential time measurement 20 ps
Time Measurement Resolution tRES 3.8 ps
Price is not cheap, 50 $8.4400 Eval Board 1 $165.0000
- but it could give a means to calibrate and check a Prop design.
Right now I'm working on using the Propeller for a "Continuous Time Stamping" counter. A really cool way to get upwards of 10x frequency resolution than a standard recip counter.
Can you elaborate on how the "Continuous Time Stamping" is applied, and how many measurement cycles are needed ?
I presume this is still a variant of time-interpolation talked about above ?
What frequency range does this work over ?
You get an increase in resolution of SQRT(samples) / 2.4 so if you take 1000 samples you will get an increase in resolution of about 13.
When you take samples X is the sample counter (1,2,3,4,etc) and Y is the propeller counter (0, 1000, 2000, 3001, 4002, etc) for each cycle of the input.
For each cycle (sample) you need to calculate: SUM(X*Y),SUM(X*X), SUM(X), SUM(Y)
After all the samples are calculated then calculate the slope as SUM(X*Y) - (MEAN(X) * SUM(Y)) divided by SUM(X*X) - (MEAN(X) * SUM(X))
And the frequency is: Propeller clock / slope
To get the highest frequency input, you just need to store the Y values, them post process them to do the calculations.
You get an increase in resolution of SQRT(samples) / 2.4 so if you take 1000 samples you will get an increase in resolution of about 13.
I think you can do better than this, with Frequency counters, which are something of a special case.(unlike analog readings, where you use sample-averaging to remove random noise).
If you take care in the hardware design, so that the sample process does not lose any edges then you can now run two calculations in parallel, and because the errors are now not random, you do gain precision faster.
The fast reciprocal counter can work on the 5ms gate, and give rapid updates, with precisions as in your plots
100M*1250/(5m/(1/100M)-1) = 250000.500001000002
100M*1250/(5m/(1/100M)-0) = 250000
ie LSB is 2ppm (per 5ms)
- but a slower, background counter can work over (eg) 200 samples we can improve to
100M*1250*200/(200*5m/(1/100M)-1) = 250000.002500000025
ie LSB is 10ppb, (per second) (and a 64bit interim result is needed)
The increase in resolution is in comparison to the reciprocal counter resolution.
For example if you were 250KHz for 5mSec you would get 1250 samples (cycles).
As you say, a simple reciprocal counter will give 2ppM resolution, where the Time Stamping method will give about 0.135 ppM resolution for the same 5mSec gate time.
The increase in resolution is in comparison to the reciprocal counter resolution.
For example if you were 250KHz for 5mSec you would get 1250 samples (cycles).
As you say, a simple reciprocal counter will give 2ppM resolution, where the Time Stamping method will give about 0.135 ppM resolution for the same 5mSec gate time.
I'm a little lost - above you said if you take 1000 samples , which means you need 5 seconds worth of readings ?
Are you doing something else here ?
When using time stamping, 1 sample is 1 cycle NOT 1 gate time.
- but if you work per Fin cycle, the resolution is very poor - taking 250KHz and 100MHz each cycle is resolved to only one part in 400.
That is very coarse, or do you have some means to resolve better than 10ns in a single-shot, 1 Fin cycle measurement ?
By comparison, the nominal 5ms gate time can resolve the Fin to one part in 500000
For straight Reciprocal, 1 sample is the whole gate time (5mSec). So the result is based on that 1 sample.
For Cont. Time Stamping. 1 sample is 1 cycle, over the gate time (5mSec) you will have 1250 samples. The result is based on all 1250 samples.
That is still not clear enough for me to follow.
That 1250 samples suggests array capture and considerable post-process, which makes the time-to-result more open ended.
( are those captures done on the stable clock, or the jittered clock ?)
& why not simply use that added time, for longer gate ?
Also, what about a 5ms gate for a 1KHz frequency, or a 5MHz frequency ? (Counters need wide dynamic range.)
I can envision a system that attempts to capture the phase fraction, by using that collected edge info, but such a system has widely varying precision, and has upper edge limit problems.
It is also not easy to infer such phase fractions when the incoming signal has moderate jitter.
I can see that your very nifty swept PLL can get better precision on stable signals, but cannot yet see a general use case.
I can see niche uses, where there are only short bursts available, and some constraints are made on the signal behaviour.
Thinking some more about this, another approach is to use a 'look back' average.
Taking the same test case, here you first run for ~5ms, and collect 1250 samples, but do no maths.
Then the next ~5ms window now has enough time-reach to calculate a series of values, and each new Edge.Time pair can look-back ~5ms for a one part in 500000 result, and then that stream of look-back values can be averaged. Processing is likely to be the limit here.
(If your HW has no lost edges, you can also run a background 'ever-longer reach' figure, as a reality check)
Comments
If only I were more worthy.
(I never found out what it was that I said that apparently caused Heater. to go off and make Zog)
Alan
We try with 75 Ohm termination, no change in distance ???
We try 100m we get 0 .... Time over .
It works.
Daniel
A number of things I noticed: The low order bits of the FRQA values are critical, so I added another
bit even lower, in both of the FRQA values. Round the freqeuncies up to $10200000,$0FE00000 and bang,
it just locks rock steady...
Different COGs behave differently - with the generate COG as 1, and measurement 2, it seems to be much
less temperature sensitive. Switch them round and there is a marked temperature sensitivity (place finger on the
Prop and watch the values change). Perhaps this varies from chip to chip, could be related to PLL stability?
[note my setup has 47 ohm protection resistors on every pin so its not quite the same electrically]
I also used a lower value resistor (120 + 47 = 167ohms) to make the voltage steps larger (I think 220 ohms
is rather high to drive a 50 ohm cable.
Oh yes, the spin version, prints result in metric assuming polythene dielectric:
Best operation needs the 'chasing PLL' to never lock, or phase-snap, to the main Sysclk.
Parasitic inductances and capacitance and crosstalk will make that aspiration vary a little from COG to COG.
Even within a COG, PLL for CTRA may be not quite the same as PLL for CTRB ?
Maybe there a Prop die photo somewhere showing Pwr/Gnd metalization and COG locations ?
That could give hints for the best COG pair to choose ?
82 ohm resistors on each to send differential pulses along a twisted pair. Two more pins sensed the wires
(although currently I only use one of them, in theory both counters could be used to measure them simultaneously).
Seemed to work - the waveforms with 100 ohm resistors looked a bit marginal, so I reduced to 82 ohms. The nominal 100
ohm impedance of the UTP sits in the middle as a resistive divider and the symmetry should mean that both sense pins
give the same information (both are connected to symmetrically load the cable end though).
With an approx 5m length of CAT5 I could get reasonable readings for a single length, find a split halfway along,
and I connected the pairs together to send the signal back along another pair to get twice the length.
Arguably differential mode could be sensed better with a high speed comparator on the twisted pair, but I didn't have
one knocking about.
A high speed comparator is another part, and variation, and I like the idea of two counters sensing both wires, as that will report a break in one, and could even report skew ?
(I'm trying to hack this code into a really simple metal detector, instead of a wire-length measurement tool.)
Jonathan
Looking forward to the metal detector results.
Excellent discovery. I'll have to try that when I get a chance.
Right now I'm working on using the Propeller for a "Continuous Time Stamping" counter. A really cool way to get upwards of 10x frequency resolution than a standard recip counter.
Bean
Let me know if I understand: as a quick first order approximation, I would probably wait for the first transition, then start acquiring a constant number of transitions, timing each one. The equation would be something like: Tcross(cross_num) = period * cross_num, where cross_num is an incrementing integer, and Tcross is referenced to the original transition. The least squares error value of period would be = sum( cross_num * Tcross ) / sum( cross_num * cross_num ). And of course, if you use a constant number of samples, that sum in the denominator would be a constant. Of course, that is the period, so inverting the equation to get frequency means the *numerator* would be a constant. Depending on the maximum frequency you were expecting to encounter, you could even do the running summation of "cross_num * Tcross" as it occurs...no need to store the samples.
Jonathan
Yes, that is basically it. It is a little more complex because you need to use the FULL linear regression formula (at least the simple formula didn't work for me).
To be able to count a higher freq, I store the counts, then post-process them and send the value to an excel spreadsheet to do the calculations.
Bean
Attached is some test code. To get above about 1.5 MHz sampling, I had to timestamp every 2 periods. This can go up to about 2.353 MHz on my 80 MHz demo board, making a single period width 34 clocks. The value returned seems pretty accurate (within a few Hz until 2 MHz, assuming the clock speed is golden, of course).
Jonathan
P.S. Bean, you were correct, using the simplified "gain only" version of the LSE equation was less accurate.
The others can be computed one time at the end.
n=last X value
Sum X = n(n+1)/2
Sum XX = n(n+1)(2n+1)/6
These would need changed if you are using every-other sample.
Bean
The Frequency is usually divided down to use the CTS method. For example the CNT90 counter divides down to a maximum of 250KHz.
Jonathan
Bean
I just noticed this from Maxim
http://www.maximintegrated.com/datasheet/index.mvp/id/8347
MAX35101 Time-to-Digital Converter with Analog Front-End
TIME MEASUREMENT UNIT
Measurement Range tMEAS Time of flight 8-8000 μs
Time Measurement Accuracy tACC Differential time measurement 20 ps
Time Measurement Resolution tRES 3.8 ps
Price is not cheap, 50 $8.4400 Eval Board 1 $165.0000
- but it could give a means to calibrate and check a Prop design.
Can you elaborate on how the "Continuous Time Stamping" is applied, and how many measurement cycles are needed ?
I presume this is still a variant of time-interpolation talked about above ?
What frequency range does this work over ?
When you take samples X is the sample counter (1,2,3,4,etc) and Y is the propeller counter (0, 1000, 2000, 3001, 4002, etc) for each cycle of the input.
For each cycle (sample) you need to calculate: SUM(X*Y),SUM(X*X), SUM(X), SUM(Y)
After all the samples are calculated then calculate the slope as SUM(X*Y) - (MEAN(X) * SUM(Y)) divided by SUM(X*X) - (MEAN(X) * SUM(X))
And the frequency is: Propeller clock / slope
To get the highest frequency input, you just need to store the Y values, them post process them to do the calculations.
Bean
I think you can do better than this, with Frequency counters, which are something of a special case.(unlike analog readings, where you use sample-averaging to remove random noise).
If you take care in the hardware design, so that the sample process does not lose any edges then you can now run two calculations in parallel, and because the errors are now not random, you do gain precision faster.
The fast reciprocal counter can work on the 5ms gate, and give rapid updates, with precisions as in your plots
100M*1250/(5m/(1/100M)-1) = 250000.500001000002
100M*1250/(5m/(1/100M)-0) = 250000
ie LSB is 2ppm (per 5ms)
- but a slower, background counter can work over (eg) 200 samples we can improve to
100M*1250*200/(200*5m/(1/100M)-1) = 250000.002500000025
ie LSB is 10ppb, (per second) (and a 64bit interim result is needed)
For example if you were 250KHz for 5mSec you would get 1250 samples (cycles).
As you say, a simple reciprocal counter will give 2ppM resolution, where the Time Stamping method will give about 0.135 ppM resolution for the same 5mSec gate time.
Bean
I'm a little lost - above you said if you take 1000 samples , which means you need 5 seconds worth of readings ?
Are you doing something else here ?
Bean
- but if you work per Fin cycle, the resolution is very poor - taking 250KHz and 100MHz each cycle is resolved to only one part in 400.
That is very coarse, or do you have some means to resolve better than 10ns in a single-shot, 1 Fin cycle measurement ?
By comparison, the nominal 5ms gate time can resolve the Fin to one part in 500000
For straight Reciprocal, 1 sample is the whole gate time (5mSec). So the result is based on that 1 sample.
For Cont. Time Stamping. 1 sample is 1 cycle, over the gate time (5mSec) you will have 1250 samples. The result is based on all 1250 samples.
Bean
That is still not clear enough for me to follow.
That 1250 samples suggests array capture and considerable post-process, which makes the time-to-result more open ended.
( are those captures done on the stable clock, or the jittered clock ?)
& why not simply use that added time, for longer gate ?
Also, what about a 5ms gate for a 1KHz frequency, or a 5MHz frequency ? (Counters need wide dynamic range.)
I can envision a system that attempts to capture the phase fraction, by using that collected edge info, but such a system has widely varying precision, and has upper edge limit problems.
It is also not easy to infer such phase fractions when the incoming signal has moderate jitter.
I can see that your very nifty swept PLL can get better precision on stable signals, but cannot yet see a general use case.
I can see niche uses, where there are only short bursts available, and some constraints are made on the signal behaviour.
Thinking some more about this, another approach is to use a 'look back' average.
Taking the same test case, here you first run for ~5ms, and collect 1250 samples, but do no maths.
Then the next ~5ms window now has enough time-reach to calculate a series of values, and each new Edge.Time pair can look-back ~5ms for a one part in 500000 result, and then that stream of look-back values can be averaged. Processing is likely to be the limit here.
(If your HW has no lost edges, you can also run a background 'ever-longer reach' figure, as a reality check)