Skip to main content
Skip table of contents

3.2.1 Stream Timing [T-Series Datasheet]


Channel-to-Channel (Interchannel) Timing

Channels in a scan list are input or output as quickly as possible after the start of a scan, in the order of the scan list.

For descriptions of typical interchannel delays, see Appendix A-1 Data Rates.

Timing pulses are generated on SPC so that the channel-to-channel timing can be measured. Pulses on SPC are as follows:

  • Falling edge at the start of a scan.

  • Rising edge at the start of a sample.

  • Falling edge at the end of a sample.

  • Rising edge at the end of a scan.

Device Clock Scan Time

To calculate the time a scan was collected relative to the device clock, multiply the scan's offset from the first scan with the interval length. The interval length is the inverse of the scan rate:

TimeSinceFirstScan = Offset * (1 / ScanRate)

For example, with a 500 Hz scan rate, the 1000th scan collected is 2 seconds after the first scan, according to the device clock.

You can use STREAM_START_TIME_STAMP to relate the start of stream with other events:

System Clock Scan Time

With writing custom code, you can assign timestamps to each stream scan. These timestamps can be the host computer's system time (calendar time) or the steady clock (absolute) time. These timestamps are based on the computer's real-time clock rather than the device's clock.

Assigning a timestamp to each scan can be beneficial for logging and for multi-device synchronization. It can also help to correct clock drift between your system clock and the device clock.

Using this technique it is realistic that the time accuracy of every scan's timestamp is within 1 ms of your system's clock, unless suboptimal conditions apply, such as asymmetric network routes or network congestion.

Example Technique

First, start stream. Then read the following registers using normal command-response.

Once stream is started, use STREAM_START_TIME_STAMP to determine when stream started,hen read CORE_TIMER in order to correlate scan times with system host clock times:

  1. Read the CORE_TIMER and your system time quickly in a loop for e.g. five times. You can assume the CORE_TIMER value is, on average, halfway between when you begin the CORE_TIMER read and when you receive the CORE_TIMER value. Throw out any measurements that take an abnormal amount of time. (If most round-trip reads of CORE_TIMER take 1 ms and one CORE_TIMER read takes 3 ms, it's likely that either the outbound or inbound communication had an unusual delay—but unlikely that both had an equal delay.)

  2. Next, calculate the CORE_TIMER value for each scan. Use the actual scan rate to calculate the CORE_TIMER value for each scan starting from STREAM_START_TIME_STAMP. If you're using LJM, LJM_eStreamStart returns the actual scan rate in the ScanRate parameter, which can be slightly different from the specified scan rate. If you're not using LJM, see Low-Level Stream.

  3. Once you have your current system clock correlated with CORE_TIMER and each scan is assigned a CORE_TIMER value, you can convert each CORE_TIMER value into a system clock time.

Additional considerations

  • There is a more detailed example in the following Host Timestamp Synchronization section.

  • Make sure your code handles when the CORE_TIMER rolls over.

  • If you're assigning wall-clock timestamps, consider what should happen when the clock skips forward or backward due to an NTP update.

  • To prevent clock drift, you must continually re-synchronize the system clock to CORE_TIMER. The T-series clock error at room temperature is 20 ppm. This is 2 ms per 100 seconds, so a re-sync of core-clock to host-clock must be done at least every 50 seconds to maintain 1 ms accuracy.

  • Check your own computer's clock specs for a source of additional clock error.

Stream Timing Complications

Most stream complications are due to the device acquisition outpacing the rate that data is consumed with your host device/computer/LJM. When using LJM, there are three common causes for this sort of issue:

  1. Sample rate is too high

  2. Device buffer overflow

  3. LJM buffer overflow

Sample rate is too high

When the sample rate is too high, it causes a STREAM_SCAN_OVERLAP error and stream is terminated.

Scans are triggered by hardware interrupts. If a scan begins and the previous scan has not finished, the device stops streaming and returns a STREAM_SCAN_OVERLAP error (errorcode 2942), which LJM returns immediately upon the next call to LJM_eStreamRead.

Stream Data Buffer

As samples are collected, they are placed in a FIFO ring buffer on the device until retrieved by the host. The size of the buffer is variable and can be set to a maximum of 32768 bytes for T4 and T7, and 262144 bytes for T8. The buffer size can be set by writing the desired number of Bytes to STREAM_BUFFER_SIZE_BYTES. The stream buffer will be allocated within shared memory. Values are stored in 16-bit words. A buffer of 8192 Bytes will be able to store 4096 results.

Once samples have been transferred to a host computer, they are stored in a second buffer until an application retrieves them.

Device buffer overflow

When the device buffer overflows, LJM inserts a dummy sample (with the value -9999.0) in place of each skipped sample, or it causes a STREAM_AUTO_RECOVER_END_OVERFLOW error and stream is terminated.

If the device buffer overflows, the device will continue streaming but will discard data until the buffer is emptied, after which data will be stored in the buffer again. The device keeps track of how many scans are discarded and reports that value. Based on the number of scans discarded, the LJM library adds the proper number of dummy samples (with the value -9999.0) such that the correct timing is maintained. This will only work if the first channel in the scan cannot return 0xFFFF.

If the device buffer overflows for too much time, a STREAM_AUTO_RECOVER_END_OVERFLOW error occurs and stream is terminated.

If the device buffer is overflowing, see the LJM stream help page for some mitigation strategies.

LJM buffer overflow

When the LJM buffer overflows, it causes a LJME_LJM_BUFFER_FULL error and stream is terminated.

LJM reads samples from the device buffer and buffers them internally. LJM reads these samples in an internal thread, regardless of what your code does. LJM's buffer can run out of space if it is not read often enough using LJM_eStreamRead, so make sure the LJMScanBacklog parameter does not continually increase.

LJM_eStreamRead blocks until enough data is read from the device, so your code does not need to perform waits.

If the LJM buffer is overflowing, see the LJM stream help page for some mitigation strategies.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.