From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Loop timing with NIDAQmx for Python

Solved!
Go to solution

Background: I'm trying to configure NI's new NIDAQmx library for Python to record 6 analog voltages with a USB-6210 DAQ. Here is my working baby code:

 

 

###############################################
# import libraries
import time as t
import numpy as np		
import nidaqmx
import pprint

fSampling = 1.0 #Hz
nSamples = 5 #samples
pp = pprint.PrettyPrinter(indent=4)
dtMax = 15 #sec

###############################################
# DAQ

# config
with nidaqmx.Task() as task:
	t1 = t.time()
	task.ai_channels.add_ai_voltage_chan("Dev1/ai0:5")
	task.timing.cfg_samp_clk_timing(fSampling)
	
	t2 = t.time()
	dt = t2 - t1
	while dt < dtMax:
		data = task.read(number_of_samples_per_channel=nSamples)
		t2 = t.time()
		dt = t2-t1
		print dt
		pp.pprint(data)		
		
###############################################
# output to file

 

And here is its output:

 

4.04500007629
[   [   5.450821630953765,
        4.550910274171798,
        3.375039902877309,
        2.8346332012577977,
        2.575119650469254],
    [   0.1436219369816977,
        0.1452665056820444,
        0.14444422133150514,
        0.14378639385160064,
        0.1442797644614851],
    [   0.42056734692955455,
        0.42155408844033515,
        0.421225174603295,
        0.421389631521801,
        0.4208962607663682],
    [   0.1837494141045311,
        0.1845716984899678,
        0.1842427847357057,
        0.18407832785861833,
        0.18358495722753115],
    [   0.3126836145923778,
        0.3133414421913342,
        0.313176985291552,
        0.31284807149207383,
        0.31284807149207383],
    [   -0.344814834975827,
        -0.34399255107332927,
        -0.34465037819538946,
        -0.344814834975827,
        -0.34465037819538946]]
9.05099987984
[   [   2.4391135199034384,
        2.3614897130805055,
        2.314454951111576,
        2.284359282671887,
        2.2605129885258157],
    [   0.14460867820155443,
        0.1436219369816977,
        0.145102048811878,
        0.14493759194174088,
        0.1429641095023787],
    [   0.42106071768481745,
        0.4207318038479473,
        0.42204745919610764,
        0.42155408844033515,
        0.42056734692955455],
    [   0.1837494141045311,
        0.18358495722753115,
        0.1845716984899678,
        0.1847361553671425,
        0.1837494141045311],
    [   0.3121902438934617,
        0.3121902438934617,
        0.3133414421913342,
        0.3123547007930717,
        0.31284807149207383],
    [   -0.34563711887755055,
        -0.34563711887755055,
        -0.34465037819538946,
        -0.344814834975827,
        -0.34465037819538946]]
14.0550000668
[   [   2.243573897101991,
        2.2325552649417535,
        2.2231812048235535,
        2.215616173903215,
        2.2082156002220095],
    [   0.14411530759149432,
        0.14411530759149432,
        0.14493759194174088,
        0.14559541942246498,
        0.14411530759149432],
    [   0.42007397617454656,
        0.421225174603295,
        0.42171854535889763,
        0.42188300227748843,
        0.42056734692955455],
    [   0.18309158659670616,
        0.18407832785861833,
        0.18440724161282218,
        0.1845716984899678,
        0.18342050035056034],
    [   0.3120257869938804,
        0.31284807149207383,
        0.3133414421913342,
        0.313176985291552,
        0.3120257869938804],
    [   -0.34497929175623365,
        -0.34514374853660934,
        -0.34382809429273675,
        -0.34465037819538946,
        -0.3454726620972678]]
19.0509998798
[   [   2.2034463416511727,
        2.1991704546724478,
        2.1955523964713692,
        2.1930855386131443,
        2.186836165394627],
    [   0.1442797644614851,
        0.14477313507163303,
        0.14477313507163303,
        0.14477313507163303,
        0.14378639385160064],
    [   0.42040289001119024,
        0.42188300227748843,
        0.42221191611475506,
        0.421389631521801,
        0.42007397617454656],
    [   0.18342050035056034,
        0.1850650691215794,
        0.1845716984899678,
        0.1845716984899678,
        0.18325604347361868],
    [   0.3121902438934617,
        0.313505899091145,
        0.313176985291552,
        0.31284807149207383,
        0.3121902438934617],
    [   -0.34530820531695405,
        -0.34382809429273675,
        -0.344814834975827,
        -0.3436636375121134,
        -0.34563711887755055]]

Questions:

  1. Does DAQmx make a timestamp for each channel's sample, or do I have to interpolate my own timestamp between each loop iteration?
    If DAQmx does generate a timestamp for each sampling, how can I access it?
  2. Why does it take less than 5 seconds to collect data for the first iteration? I feel like there's a simple logic error in my code, but I just can't figure it out even after a lot of dummy prints Smiley Frustrated
    T_loop = nSamplesPerChannel/fSampling (5/1 = 5)

Thanks!

 

0 Kudos
Message 1 of 10
(8,941 Views)

DAQmx does not timestamp samples when they are taken on the DAQ device, but it does when it reads the FIFO samples onto the computer if you are reading in a waveform data type. I would check the documentation to see if that is implemented in the Python version. 

 

As for timing, if you implement the same code in LabVIEW does it take the expected time?

Chase
NI Technical Support Engineer
0 Kudos
Message 2 of 10
(8,885 Views)

The documentation for NI's NIDAQmx Python library is sparse at the moment--NI released this library less than 2 months ago--so I haven't had much luck there.

As for a LabVIEW comparison, I cannot do that because I simply don't have access to LabVIEW right now...hence Python.

0 Kudos
Message 3 of 10
(8,878 Views)

 

At any rate, my current solution to problem 1 (timestamps) is to just append the time of buffer-reading to my data array during data-acquisition. In post-processing, I will interpolate the time between the samples using the timestamps and my sampling period. Is there a more exact way, or is this how the timestamp for each sample of the dynamic datatype is created in LabVIEW?

 

data-acquisition:

T = sampling period

N = buffer size, N =  (samples/(channel*sec)) * T

 

data array

t0 ch0   ...    ch5

-   s1            s1

-   s2            s2

...

t1 sN           sN (buffer read)

-   sN+1       sN+1

-   sN+2       sN+2

...

t2 s2*N        s2*N (buffer read)

 

Post:

 

file output

t0       ch0    ...   ch5

t+T     s1            s1

T+2T  s2            s2

...

t1         sN          sN (buffer read)

t1+T     sN+1      sN+1

t1+2T   sN+2      sN+2

...

t2          s2*N       s2*N (buffer read)

0 Kudos
Message 4 of 10
(8,875 Views)

Hey aeroAggie, 

 

What you are doing is basically how we do timestamps in LabVIEW. Our DAQ cards do not have a time stamp mechanism, so we use the t0 and dt in LabVIEW to time stamp it. 

 

For this, it looks like your method is the most exact way to do it.

Chase
NI Technical Support Engineer
0 Kudos
Message 5 of 10
(8,835 Views)
Solution
Accepted by topic author aeroAggie

@aeroAggie wrote:

Background: I'm trying to configure NI's new NIDAQmx library for Python to record 6 analog voltages with a USB-6210 DAQ. Here is my working baby code:

 

 

###############################################
# import libraries
import time as t
import numpy as np		
import nidaqmx
import pprint

fSampling = 1.0 #Hz
nSamples = 5 #samples
pp = pprint.PrettyPrinter(indent=4)
dtMax = 15 #sec

###############################################
# DAQ

# config
with nidaqmx.Task() as task:
	t1 = t.time()
	task.ai_channels.add_ai_voltage_chan("Dev1/ai0:5")
	task.timing.cfg_samp_clk_timing(fSampling)
	
	t2 = t.time()
	dt = t2 - t1
	while dt < dtMax:
		data = task.read(number_of_samples_per_channel=nSamples)
		t2 = t.time()
		dt = t2-t1
		print dt
		pp.pprint(data)		
		
###############################################
# output to file

 

And here is its output:

 

4.04500007629
[   [   5.450821630953765,
        4.550910274171798,
        3.375039902877309,
        2.8346332012577977,

  

Questions:

  1. Does DAQmx make a timestamp for each channel's sample, or do I have to interpolate my own timestamp between each loop iteration?
    If DAQmx does generate a timestamp for each sampling, how can I access it?
  2. Why does it take less than 5 seconds to collect data for the first iteration? I feel like there's a simple logic error in my code, but I just can't figure it out even after a lot of dummy prints Smiley Frustrated
    T_loop = nSamplesPerChannel/fSampling (5/1 = 5)

Thanks!

 


1 Yes you have to add dt to t * Sample index

2. Because sample 0 is a T=0, 2 is at T 0+1 ,etc  So the first read returns at 4 * Sample rate + some startup for the first conversion.  On subsequent reads, the first sample in the read cannot start until a sample period has passed from the last sample so they take longer.


"Should be" isn't "Is" -Jay
Message 6 of 10
(8,828 Views)

2. Because sample 0 is a T=0, 2 is at T 0+1 ,etc  So the first read returns at 4 * Sample rate + some startup for the first conversion.  On subsequent reads, the first sample in the read cannot start until a sample period has passed from the last sample so they take longer.


OOHHHHHH, so it's like this:

sample/dt from t = 0

1/0

2/1

...

5/4 - READ

6/5

7/6

...

10/9 - READ (9-4 = 5)

That makes sense. I should have tried listing or acting out the data-acquisition. Thanks!

0 Kudos
Message 7 of 10
(8,820 Views)

With humorous intent You could have worked it out on your fingersSmiley Surprised Place your left hand on the table and start with your right index finger on your left thumb the samples are taken when your index finger moves to the next finger and the intervals are the time between fingers. The read occurs when you touch your pinky.


"Should be" isn't "Is" -Jay
0 Kudos
Message 8 of 10
(8,817 Views)

NI should start with that for its DAQ bootcamp Smiley LOL

Message 9 of 10
(8,815 Views)

Hi aeroAggie,

 

How would you include the sampling time you calculated to the logfile? Smiley Frustrated

0 Kudos
Message 10 of 10
(7,059 Views)