Quick timing question using the counter
Cncjerry
Posts: 64
Ok, so I tried an arduino first and found that their timer, unless there is an assembly mode to make it faster, was limited to 4us (microseconds) resolution.
So if I use the counter, can I time events at better than 4us?
Thanks
So if I use the counter, can I time events at better than 4us?
Thanks
Comments
[code] <- what are the code inserts agan??
Time1:=Cnt
Time2:=Cnt
pst.Dec(Time1)
pst.Chars(pst#NL, 2)
pst.Dec(Time2)
[code end] <- as above
the two values received on the terminal from the successive CNT values differ by 368 as below. Would that be 368 80mhz clock ticks? If so, if I am doing the math correctly, this would be 4.6 microseconds, correct? This was in spin. I have done some playing around with assembly, would that return faster?
13455035
13455403
What 'events' ? - Do you mean software timing, or external hardware edge timing ?
The prop has a 32 bit timer, usually clocked at 80Mhz, so that gives a LSB of 12.5ns on Read and WAITs, but there are some latency details so you cannot read down to very low count-deltas.
The Prop lacks a direct Edge Capture, but you can WAIT on a pin, and then read a counter, and resolve to 12.5ns, as the WAIT is one-clock-granular once it gets 'primed'.
So basically an optical sensor array is built into three screens spaced precisely 1ft apart. The sensor raises a pulse as the projectile enters each screen. The code saves the timer on the arduino and then does some simple calculations to get fps and averages across the three screens and if we can get enough timer resolution, then possibly the balistic coefficient which is how much the projectile slows down range.
I am using the following code to test the assembly timer and I get the same answer for each successive sample for some reason. I would expect them to be off a little, no? Even if I put some junk instructions between the mov start_time,cnt instructions, I still get the same. Any ideas?
I thnk this is going to work. I had to give-up on my last prop project as I ran out of pins. This one only uses a few, less than 10.
Thanks.
oh, and btw: there are fewer idiots on this forum than the arduino forum, by far. Except now that I am here, it went up by 1.
Jerry
Lawson
How wide is the pulse, and what sort of variance/slope do the sensors have, and will one edge be more precise than the other ?
The code in #7 is a nice starting example.
If your sensor is symmetric in rise/fall, but somewhat variable in width, you could try #7, then try a both edges capture - you may find the average of leading/trailing edges, gives a better variation tolerance, and if you can fire projectiles in both directions you can start to calibrate sensor-sensor skews.
I put a DSO on the pulse but don't remember the timing. It isn't that fast since the DSO I was using was an old Tektronix and it only is about a 20mhz. I think it only stores at 1msp. I am not measuring the pulse at all, just the timing between the three pulses coming to three different pins. I doubt the three screens will all detect the projectile at the same point if you see what I mean so the arduino with 4us resolution is probably not the weak link. As long as it is consistent I should be ok.
The circuitry seems pretty solid on the detect side and I get amazing results. I looked at using spin but the resolution was 4.6us if I read the cnt successively and since that was slightly worse than the arduino C++, I would just use that board and maybe switch to ASM but I am more familiar with the pasm.
Thanks for the help and also the timng code in 7, the long allocation in #6 and I like the calibration idea from #8 with firing in both directions. hadn't thought of that one.
Jerry
Read #7 carefully, and especially these lines :
Note they are WAIT commands, but waitpne/waitpeq act on physical pin levels, not counter based delays.
Even tho they are in Spin, they use the PASM opcodes (also called waitpne/waitpeq) and so have the same precision as PASM.
There is one difference between Spin/PASM in this use, which is Spin does have a time-per-line, so has a minimum pulse width.
requirement impact (but no edge precision impact).
If you measured 4.6us for two adjacent lines of spin, then the first line in #7 of
will wait for seconds if it needs to, before advancing to the next line
but if the Pulse width is less than 4.6us ===\___/==== then the second wait condition will be already true, and it will not time from the RISE edge, but actually be paced off the first falling edge.
The same effect occurs in PASM, but now the software imposed Pulse min is the 6+ SysClks (~ 75ns) of WAITPNE
Correct Edge resolution is 12.5ns in both cases, once you meet the Pulse Width min.
The trick to best resolution, is to avoid entirely any software pin-polling, and instead use the hardware as above.
The prop has a 32 bit counter, so there is no excuse not to edge capture to SysClk precisions.
Also the code you are quoting, does not seem to read any pins, is it just test code ?
I've unrolled the loop, and pegged it to the wait, which should make it clearer .
A CNT read straight after a waitcnt is always +waitTime SysClk snapped, but what about the CNT read BEFORE ?
It is not quite sysclk locked, as the wrlong opcodes can have variable lengths, and that is what your first capture is reading.
Note what you call stop_time, is actually start-time, (wait locked) and the start_time you write, is from the last loop
So I will be doing a waitpne(pin1_mask, pin1_mask,1) on one pin, then grabbing the cnt, waitpne(pin2_mask, pin2_mask,1) on a second pin, then calculating the delta and flagging Cog0 to do the other calcs.
I need to measure the time between the two pulses on the two pins, then calc the delta in clocks and convert to microseconds. 1 / microseconds gives me feet per second. Whole numbers are fine.
So now that the I have an understanding of the cnt timer I can move on to the other minor code.
Thanks again.
Jerry
@Jerry: Please try the test code I attached to post #7. If the pins are edited to match your hardware, it should just work. (it assumes the optical triggers are logic low between pulses)
Second, CNT is REALLY simple. it's just a 32-bit counter that increments every clock and can be read by any core.
Lawson