labscript-suite / labscript-devices

A modular and extensible plugin architecture to control experiment hardware using the 𝘭𝘒𝘣𝘴𝘀𝘳π˜ͺ𝘱𝘡 𝘴𝘢π˜ͺ𝘡𝘦.
http://labscriptsuite.org
Other
5 stars 58 forks source link

Externally clocked analog inputs on NI-DAQmx #102

Closed dihm closed 1 year ago

dihm commented 1 year ago

Implement ability to specify an external sample clock timebase signal for analog inputs on an NI-DAQ.

This mitigates issues where the AI clock and the timing pseudoclock can get out of sync with each other, particularly for long shots.

Fixes #80

dihm commented 1 year ago

I've tested this in a simple experiment using a prawnblaster and an NI USB-6363. The prawnblaster is acting as pseudo-clock to the DAQ, and the DAQ ao0 is wired directly to ai0. I then command analog pulses at increasingly longer times, spanning from 100 us to 4 s. Comparing the measured output risetimes gives a handy measurement of the prawnblaster/AI sample clock drifts. Below I show each measured pulse with timing relative to the programmed time (label in top right corner).

image The measured drift between the clocks in my system happens to be ~6ppm.

By providing a Sample Clock Timebase signal, the DAQ can use an internal PLL to derive the desired sample clock. If the provided timebase is phase synchronous with the prawnblaster pseudoclock internal clock, the two timings no longer drift.

image Here there is only a small, constant clock skew due to cable lengths (> 1 us, measured resolution is limited by AI sample rate of 1MS/s).

dihm commented 1 year ago

I did look in to allowing users to do synchronization with Master Timebase and Reference Clock methods, but they ended up being more complicated. They are both more global methods of synchronization (ie they are used to generate every clock on the DAQ). While this would be nice, it necessitates configuring them before any task on the device is started, including the static, manual mode AO,DO tasks. This means that specifying an AI timing signal requires passing arguments to the analog output worker, which just didn't feel right. Moreover, these two methods are not universal to all DAQs, meaning introspection of each device would be required. Finally, it's overkill for us right now as all other tasks are timed via pseudoclocks, so they would not even benefit.

Using Sample Clock Timebase synchronization for the single AI task ends up being the most general solution that is the easiest to implement.

dihm commented 1 year ago

Seeing as this is a purely opt-in upgrade that is backwards compatible with older shots and connection tables, and there has been no comments to the contrary, I'm gong to go ahead and merge.