Increasing the resolution of pulse timing
lmclaren
Posts: 104
in Propeller 1
Hi,
I am measuring the length of a pulse using the following code:
This works well but I need even finer resolution, twice would be a good start but 4 x would be better.
The processor is running at 80Mhz.
If I can't do better in code can anyone suggest hardware that could help?
thank you
I am measuring the length of a pulse using the following code:
Loopy 'Start timing the received pulse waitpeq inmask,inmask 'Normaly high, wait for input pin to be low mov vlRXCountStart,cnt 'Capture the time for the start of the pulse waitpne inmask,inmask 'Wait for rising edge (End) on input pin mov vlRXCount,cnt 'Capture system timer as event time 'tend' sub vlRXCount,vlRXCountStart 'Subtract the start time wrlong vlRXCount, vRXCount ' write result to hub ram location set in PARAMETER
This works well but I need even finer resolution, twice would be a good start but 4 x would be better.
The processor is running at 80Mhz.
If I can't do better in code can anyone suggest hardware that could help?
thank you
Comments
Bean
For a 0-1-0 pulse you would:
-- set counter to POS detect and assign pin
-- wait for low state on pin
-- clear phsx
-- wait for high
-- wait for low
-- read pulse width (system ticks) from phsx
-Phil
Only way to do better would be to use an external high frequency gated counter and oscillator. You might be able to output 128MHz on a Propeller pin to the counter but that gets less than 2 times the resolution so you will need an external oscillator for 2 or 4 times resolution. Something like the ON Semiconductor MC10E136FNG for the counter and the Analog Devices EV-ADF4360-9EB1Z for generating the clock.
This is getting into an area that will require some careful layout to get a working circuit board.
As Bean hints above, if this is repetitive, you can do multiple samples and average, and IIRC someone did some clever work with a PLL mode, to ensure a dithered sampling clock.
If it is single shot, things are tougher.
You can bump to 100MHz ok, which helps a little.
You can add a delay line, and multiple timers, so a half-sysclk delay, and a 2 gated timers, can halve the LSB.
Using 2 cogs, and a 4 tap delay line, gives 4x resolution, avoiding very fast clocks.
@jmg What you describe sounds like it may be what I need. Do you have any examples?
thank you everyone.
For averaging, there is this work by Bean
https://forums.parallax.com/discussion/135563/measure-the-speed-of-electricity
and more updated clever work here
https://forums.parallax.com/discussion/comment/1215371/#Comment_1215371
Bean says
"The hard part was getting a signal that is NOT phase locked to the propeller clock."
"I used the PLL in the counter, but normally the PLL will get phase locked to the propeller clock very quickly. So I have a tight loop that keeps moving the frequency input to the PLL.
This causes the PLL to constantly adjust and it never gets phase locked."
For delay-lines, you need some external element, and custom delay lines do exist, but sadly are niche parts.
If you need just x2 or x4 improve, you can probably roll your own delay line, using a string of inverter gates.
If you vary their Vcc, you can adjust the delay (That's how the PLL works in P1 & P2)
A larger part like 74ALVCH16646, could do interesting things with a typ delay given of 2.6ns, but that's in a larger package.
Addit: The '646 series looks to be fading, so maybe more mainstream would be cheap & widespread HEX inverters and registers, x04/x14 and x597 to capture fractional info
3 inverters and 2 registers can capture 16b of delay info.
One in NEG detector mode and the other one in NEGEDGE mode.
Wait for a rising edge and clear both counters.
Wait for a while (a couple seconds ?)
Wait for a rising edge and read both counters.
This will give a count of the pulses and the total time spent in the low state.
Average time is simply total/count.
Bean
I have a question very similar to this so I figured it belongs here too:
I'm using the following code to measure pulse width:
My goal is to get 12.5ns resolution but for some reason the pulse width I'm getting is always a multiple of 16. For example the output may fluctuate between 384 and 400. I have verified that the propeller is running at 80MHz and the pulse width it measures is correct but only at 1/16 of the resolution I want. I thought CNT should increment by one after each clock cycle, but that does not seem to be the case?
-Phil
That's a quite small difference. Did you try larger pulse widths, to check first, and then see how narrow a pulse you can capture ?
Any HLL code is going to take finite time, which imposes some limit on the correct wait operation.
-Phil
Mike R...
I used LMM, -O2 and "no fcache" option was disabled so I suppose I already have it enabled, is that correct?
(Opcodes are 4 sysclks, but will re-align/shift on a WAIT opcode)
Did you try PASM code ? or other code ?
eg this resolves to 1 SysCLK
https://forums.parallax.com/discussion/123170/propbasic-reciprocal-frequency-counter-0-5hz-to-40mhz-40mhz-now
-Phil
The first command after the WAITXXX for reading the CNT value always gets synchronized to the Hub when it is executed, so a 16 clock resolution is forced.
A short C function with: __attribute__((fcache)) may also work.
Andy
-Phil
Perhaps you should try a PASM program running in a cog that does the timing and puts the result(s) in one or more hub locations that your code can then access.
Mike