ScanImage 5 allows hardware timestamps to be recorded and be appended to each acquired frame. The available timestamps are
- frame timestamp (relative to the start of the acqMode)
- acq trigger timestamp
- next file marker timestamp
additionally, a stop trigger is evaluated, but no timestamp is recorded.
In SI5 Resonant, the FPGA records these timestamps with high precision. In SI5 Galvo/Galvo, these timestamps are generated by acquiring a continuous digital waveform at a known frequency and then searching this waveform for rising edges.
When an acquisition is started in SI5 Galvo/Galvo, a continuous buffered digital input task (3 channels for start/stop/next triggering) is started on the auxiliary device. For alignment with the actual start of the acquisition, this task is triggered by the first edge of the frame clock and then runs freely (but synchronized to the sample clock) until the acquisition is aborted or the end of the acqMode is reached.
At the end of each acquired frame the function LinScan2DClocks.updateTriggerTimes is called. This function reads the data from the running DI task, and searches the waveform for triggers. If a start/stop/next trigger is found, the timestamp is reported back to LinScan2D and the information is appended to the frame (after invalid triggers were rejected), and the acquisition state is changed accordingly (e.g. stopped, when a stop trigger occurred).
The digital input task has a limited buffer size. Since the task is running even when there is no active acquisition (e.g. between two triggered acquisitions), the buffer can overflow if it is not read periodically. To avoid this problem, the 'everyNSamples' callback is configured for the DI task. However, he option everyNSamplesReadDataEnable is disabled, so that only the callback is executed, but no data is read by the event. the everyNSamples callback function then calls LinScan2DClocks.updateTriggerTimes which retrieves the data from the DI task, analyzes the triggers and stores the results until it is called again at the end of a frame.
One limitation applies for Next Triggering: When a DAQmx finite task is started, the number of samples to be acquired/generated by that task cannot be updated while the task is running. However, the length of an acquisition cannot be determined in case of next triggering. If a next trigger occurs, the task needs to continue running beyond its predefined duration.
For this reason, the AI/AO tasks are configured to be continuous when LinScan2D.trigNextEnable = true. After the end of an acquisition, the task keeps running and the data produced by the task is discarded. Only after the next start trigger is received, the acquired data is used again and the stripeAcquiredCallback is executed.