tapr / ticc Goto Github PK
View Code? Open in Web Editor NEWSub-nanosecond time interval counter
License: MIT License
Sub-nanosecond time interval counter
License: MIT License
Not urgent.
Currently, the calculation that determines the ring period has a result that is truncated to integer picosecond. Since we are multiplying the introduced error by potentially a couple of thousand, it would be good to see if we can improve the precision to 0.1 or 0.01ps.
I think this can be done by the old multiply-then-divide trick in the ringperiod calculation, and combining that into a single statement with the following ringticks * ringperiod multiplication into the same step. Final result can be integer picoseconds but want to improve the quality getting there.
Now that the basic functionality seems to be there, I'm thinking about user interface. There's not much to it, but here are ideas so far:
Hi,
i have made "copy" of the hardware to make it self contained and not Arduino based. Its based on stm32f042 mcu with frontend unchanged.
https://github.com/robots/stm32-ticc/
have fun
Without any optimizing (and using i64_t way more than is probably necessary, and Arduino that's really slow), the time inside the TICC measurement loop from "got data" to end of calculation is around 500us.
However, printing over USB takes 1 to 5ms. From some Googling I've learned that the following may be bottlenecks:
I've also found or thought of a couple of possible solutions:
Thoughts?
On upgrading from Ubuntu 14.04 to Ubuntu 16.04, the behavior of the Arduino compiler has changed. Particularly, enum usage that would not compile now does, and some ugly work-arounds are not needed. Additioally, thingsthat used to compile, no longer do.
It would be good to at least alert folks as to what compiler version they are using when they do a build. We could then identify in the documentation which version we used to create any particular code.
The following code is one possibility:
Hi
When using the TICC with both channels simultaneusly and the channels' relative phase is low enough, the TICC spits out the readings in an order different than the relative time of each event:
0.439584593247 chA
0.439582179116 chB
0.689584594560 chA <--- This row and the next are out of order, for example
0.689582177550 chB <---
0.939582176044 chB
0.939584595875 chA
1.189584597191 chA
1.189582174452 chB
1.439582172960 chB
1.439584598507 chA
1.689582171446 chB
1.689584599821 chA
1.939582169811 chB
1.939584601135 chA
2.189584602511 chA
2.189582168244 chB
2.439584603827 chA
This doesn't seem to happen when the relative phase difference between the inputs doesn't let the event times between channels get close. During this situation, the readings come out in order, as far as I can tell.
The issue causes Timelab to confuse the input readings, because of the way the channels are configured and interpreted in the software: for each reading cycle, chA is the first reading and chB goes after chA. I understand this is also an issue with Timelab, because it shouldn't expect that the reading are always in order.
I'm not sure whether this is a Timelab bug or the TICC firmware. I understand that by having two independent inputs there's no way to ensure that the channel readings will come out in order, but I'm referring to the cases where the inputs do come out of order: Is there anything that can be done in order to avoid it from happening?
Attached is a phase difference plot from Timelab, where the issue shows.
Also, the phase data files used to obtained these graphs:
phase-data-issue.txt
phase-data-ok.txt
Let me hear your comments
BR, German
I have no idea if this project is still alive or not. But i found mistake in the 64bit print function. Following code produces incorrect output for certain numbers. Eg. -1000000019516.
int64_t sec, secx, frac, frach, fracx, fracl;
char str[128];
sec = abs(x / 1000000000000); // hopefully avoid double negative sign. Thanks, Curt!
secx = sec * 1000000000000;
frac = abs(x - secx);
// break fractional part of seconds into two 6 digit numbers
frach = frac / 1000000;
fracx = frach * 1000000;
fracl = frac - fracx;
I suggest to rewrite the calculations as following:
sec = ABS(x / 1000000000000);
frac = ABS(x % 1000000000000);
// break fractional part of seconds into two 6 digit numbers
frach = frac / 1000000;
fracl = frac % 1000000;
I have tested this on both native 64bit machine and 32bit mcu.
It would be useful to have two sets of fudge values for both channels that would be compounded during measurement: fudge0 can be used as internal correction for precise calibration of the TICC + cabling / pigtails, and fudge1 can be used as the working correction for whatever the user is currently doing. Having two separate corrections would spare us some extra math and having to remember the original correction value.
The STOPB signal (from stop gate for channel B) uses Arduino I/O pin 13. I just noticed that pin 13 is attached to a resistor and LED, which provides a handy signal but might cause timing or other differences between channels.
For Rev. D board, should we change to another I/O pin, and leave 13 unused?
if you want to make the picdiv source self-contained I think you also need the library of delay functions in a file delayw.asm
FWIW I put the picdiv sources and some build notes in a repo, last time I built a picdiv board: https://github.com/aewallin/PICDIV
Tom discovered that on some (but not all) boards, the stop gate hardware can latch to a HIGH state on one or both channels. This causes the software to hang and the only way to clear is to pulse INTB low (open collector). We can't cause the TDC chip to do this.
Only fixes appear to be either changing the board to allow an Arduino I/O pin to drive a transistor to pulse the INTB lines, or to test for inactivity on a channel and disable. Tom's current code (to be committed here soon) provides that test.
For hardware Rev. D we need to consider the hardware fix.
Just pushed code that adds a rollover counter for TOF. Nothing more than an approximation of correct.
We should move as much config as possible from constants, to variables stored in eeprom so the user can change without needing to recompile. Here's my first pass at var, type length (bytes), index position:
SERIAL char[11] 0 // board serial number (10 char); can we set once then protect?
CLOCK_HZ uint32 11 // clock speed -- default 10 000 000
PICTIC_PS uint32 15 // 100 000 000 for 100us
CAL_PERIODS uint8 19 // calibration periods
TIME_DILATE_0 uint32 20 // time dilation factor channel 0
TIME_DILATE_1 uint32 24 // time dilation factor channel 1
FIXED_STOP_0 uint32 28 // do we autocal, and if so the stored value
FIXED_STOP_1 uint32 32 // do we autocal, and if so the stored value
FUDGE_0 uint32 36 // fudge factor channel 0
FUDGE_1 uint32 40 // fudge factor channel 1
MODE uint8 44 // operating mode
I thought about including firmware version, but we can compile that into the firmware itself by setting it as an array of char[]. No need to store in eeprom then.
Currently, when 10 MHz is lost and restored, the TICC does not resume measurement and stalls until it is reset, regardless of measurement mode. I have not looked into the source code yet so I appreciate that this may not be trivial to solve, but I thought I should flag this anyhow.
PICstop increment due to frequency offset doesn't seem to happen cleanly. Need to figure out why and how to address. See rollover-ex2.txt
rollover-ex2.txt
When building a bigger system out of multiple TICCs, it would be useful to be able to set an n-character ID of each board. When multiple TICCs are connected to a USB host, they may be detected in a semi-random order, and serial devices are not always detected under the same name. A board ID would allow one to scrape the output for the ID and identify which board is which.
The time2Result register reflects the time from the STOP pulse generated by the stop gate circuit until the next edge of the 10 MHz clock. This ought to be a fixed interval determined by propagation delays, and investigation seems to show that it is. Attached is a plot of the time2Result run through the normLSB (ps per tick) calculation for about 90 minutes.
Running statistics on the raw time2Result integer value, over that run we get:
Min: 1123
Max: 1127
Mean: 1124.88
STDDEV: 0.36
There is no apparent trend in the result (i.e., the dominant value is the same at both ends of the run). So the value seems to be stable over this run, and including its instantaneous value in the calculation only adds noise. What if we either: (a) do a calibration at restart that measures the first say 10 time2Result measurements and determines the integer mean, then uses that fixed value going forward, or (b) use a rolling average of time2Result instead of the instantaneous result? This could be a configurable option.
If we can remove the time2Result jitter, I think we reduce the overall jitter by half, which is a nice win.
UPDATE: The latest commit adds a "FIXED_TIME2" constant. If set to 0, calculation operates as before. If nonzero, that value substitutes for time2Result in the calculation. I set to 1125 (the integer mean from the run above) and in an initial test, it seems to reduce the 1 second ADEV (which sort of represents jitter) by about sqrt(2), which makes sense and is a worthwhile improvement if it's valid.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.