I'm reading 2 x 16 current channels using modules in a cDAQ and would like to timestamp the readings. I could not find any method that does that using the libraries so I am wondering what kind of configuration is preferable in order to do this? If someone can provide some quick code example or pointers it will be greatly appreciated.
If you're performing a continuous acquisition, you just need to know the first sample timestamp and the sampling rate to come up with each sample's timestamp.
Under ideal conditions, yes, however there is no overhead at all to drive this assumption out of sync.? I've tried setting up a task and reading a known number of samples, however it takes time until first valid readings are in and I would like to avoid it. Is there a possibility to run the ADC and read a known number from the NI buffer and than I can calc timestamps according to sample rate.
More description of your application with actual models involved will help comment on what you actually need to achieve your goals.
So I'm running two 9208 and I want to read 2 x 16 channels constantly. The samples are used for 2 things - First, they are logged into a text file and second I want to plot them real-time. Both of these require that the sampled are timestamped as I want to be to determine when certain events happened.
Let us assume that I sample continuously.
1. How can I get the time stamp for the first sample? Having that, I agree, calculating the times for the other samples is possible as sample freq. is known, so each one should be 1/f apart.
2. I'm running 2 analog input modules - How do I approach applying timestamping in this case?
Unfortunately, the DAQmx python library does not expose the timestamp information of the waveform. It is possible to use the current time to construct a waveform but it will not be the actual timestamp on the hardware. Reference: How to Get Timestamps with NI-DAQmx in Python?
If you don't mind learning C#, I have attached a modified example demonstrating the extraction of timestamps and plotting of the waveform. If you are not familiar with the waveform data type, see Accuracy of the Waveform Timestamp Returned by NI-DAQmx.
My exploration was unsuccessful, LabVIEW version of those APIs returns the first sample's timestamp but the Python APIs just return the samples and nothing about the timestamp of the first sample.
One more thing to note, this first sample timestamp is the timestamp added by the DAQmx driver in software and not really the timestamp from hardware, there will be a difference between the actual moment the sample was acquired vs the timestamp the DAQmx driver returns. I guess this is because the DAQmx instrument does not have any sort of actual time like an RTC other than the reference clock from PXI chassis and onboard oscillator.
@sato_13 So this can not be implemented in Python?
I understand what you are saying that this is not a real 'hardware' timestamp anyway, but perhaps the driver is smart enough to compensate for the 'pipeline' so eventually it might have a fairly consistent error? Anyway, that does not matter in my case.
So my best bet is just to read the channels, 1 sample each and generate the time samples in my code?
Is the timing configuration in the code suitable for this? When I execute the read command would that trigger the hardware to start collection and samples and place them in the numpy array? Are these 'new' samples, or samples that were in the NI's buffer before? After I'm done with the reading I can capture the current time from Python and add 1/sampling_freq to the samples for the 32 channels.
Sample timestamp = now_time + sample_index * (1 / sample_freq)
Is this the way I can implement this concept in Python?
with nidaqmx.Task() as task: task.ai_channels.add_ai_current_chan("cDAQ1Mod2/ai0:15", "", shunt_resistor_loc = CurrentShuntResistorLocation.INTERNAL ) task.ai_channels.add_ai_current_chan("cDAQ1Mod3/ai0:15", "", shunt_resistor_loc = CurrentShuntResistorLocation.INTERNAL ) # hardware timed sample triggering task.timing.cfg_samp_clk_timing(sampling_rate, "", active_edge = Edge.RISING, sample_mode = AcquisitionType.CONTINUOUS, samps_per_chan = 1 ) task.start() while True: data = task.read(samples_to_read_per_channel) now = datetime.datetime.now()
Most NI DAQ cards (with the exception of TSN-enabled cDAQ like 9185 and 9189) are not synchronized to the computer’s system clock and do not output timestamp data. The timestamp in the waveform acquired is based on the system clock. The system clock is read only once when the data is read from the buffer the first time. For more details, see Accuracy of the Waveform Timestamp Returned by NI-DAQmx.
You should stick with the idea of t0 and dt, so the resulting array should look like this:
datetime.now() + dt sample2
datetime.now() + dt*2 sample3