Git Product home page Git Product logo

ticc's People

Contributors

ghbyrkit avatar mcdermj avatar n8ur avatar tom-mcdermott avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ticc's Issues

Enhancement -- ringperiod resolution

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.

UI/Config/Calibration

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:

  1. Allow user to get into setup menu by pressing any key within X seconds while in setup() -- don't waste time polling for keystrokes during loop().
  2. Store values in EEPROM and read during setup().
  3. Calibration routine for FIXED_TIME2 -- take X measurements on selected channel, get integer mean of time2Result, store in EEPROM. 0 equals calculate on each measurement.
  4. Figure out what modes we want to provide: timestampA, timestampB, timestampAB, periodA, periodB, periodAB, totalizeA, totalizeB, totalizeAB, time interval A->B, time interval B->A, time interval absolute?
  5. Investigate whether we can initiate reset from software.

Future Plans: better throughput, more measurements/second

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:

  1. The "Serial.print" function is very inefficient. Using "Serial.write" might be faster, but we have to send it the data character-by-character.
  2. USB packetizes data and sends variable length packets of up to 4K once per millisecond. So there's latency waiting for the next slot, and if the data crosses packets there's further delay.

I've also found or thought of a couple of possible solutions:

  1. Use Serial.write -- probably not a big win if you still have USB latency.
  2. Buffer the print requests so that we don't send on each measurement, but build up until we can send a burst. We do not need real-time data output; if a burst arrives every 10 seconds, I don't think that's a problem.
  3. Use one of the other UART ports on the Mega CPU for output. This would require an added TTL to RS-232 converter. It would get rid of USB latency, but may have other overhead or bottlenecks (I'm not clear whether only serial port 1 is hardware UART and the others may involve more bit banging).
  4. Use SPI to send data to another Arduino, which would buffer it to send out in large packets and could also do other cool things like drive an LCD front panel. I kind of like this idea as presumably the SPI would be able to move the data out pretty darn quickly, and we already have the SPI code in the program.

Thoughts?

Compiler Version Dependence

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:

if (defined(__ GNUC __ ) || defined( __ GNUG __))

pragma message("GCC compiler detected")

endif

pragma message("Compiler version: ")

pragma message(__ VERSION __)

Channel readings out of order

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:

timestamp (seconds)

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.
phase-difference

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

Use modulo operation instead of divide and substract

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.

Feature request for consideration: fudge1

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.

Using Arduino I/O 13 (Hardware)

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?

picdiv source

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

STOP gate glitch (Hardware)

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.

TOF rollover

Just pushed code that adds a rollover counter for TOF. Nothing more than an approximation of correct.

Values to save in eeprom

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.

No recovery from loss of 10 MHz frequency reference

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.

Feature request for consideration: Board name / ID string

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.

Is time2Result really variable

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.
time2result

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.