Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Triggered data acquisition python

Hello,

 

I'm currently trying to realize a data acquisition task in python. So far I have come up with two different approaches with the help of this community (big thanks!). However both solutions have still some problems. Therefore I hope that you might be able to help me again.

 

The acquisition task is the following. I have a TTL trigger pulse with a frequency of 5 kHz. At each trigger pulse I want to read from three channels several data points to integrate them later in order to improve my signal. The first solution was the usage of a trigger (see code example no. 1 below). However here I have the problem that if i read out the elapsed time for rearming the trigger it gives me roughly 10 ms, which is obviously too slow for the desired trigger. In the code the whole task is always restarted which makes it that slow so my question would be if somebody has an example for me how to accelerate this. The second solution was to use the trigger as an external sample clock (see code example no. 2 below). This is working fine in terms of speed but obviously I acquire only one data point with each trigger and not several as intended. My question here would be if somebody knows if it is possible to acquire more than just one data point which each trigger in this configuration and how to do it.

 

Cheers

Fabian

 

Code example no. 1:

import nidaqmx as n
import time
from nidaqmx.constants import (
TerminalConfiguration,
VoltageUnits,
AcquisitionType,
TriggerType,
Edge
)


s_freq = 100000
num_samples = 100


task = n.Task()


task.ai_channels.add_ai_voltage_chan("/Dev3/ai0")

task.ai_channels.add_ai_voltage_chan("/Dev3/ai1")

task.ai_channels.add_ai_voltage_chan("/Dev3/ai2")

startt = time.time()

 

task.timing.cfg_samp_clk_timing(s_freq, sample_mode=n.constants.AcquisitionType.CONTINUOUS, samps_per_chan=num_samples)
task.triggers.start_trigger.trig_type = TriggerType.DIGITAL_EDGE
task.triggers.start_trigger.cfg_dig_edge_start_trig("PFI0",trigger_edge=Edge.RISING)

 

for i in range(5):
      starttt = time.time()
      task.start()
      print(time.time() - starttt)
      data = task.read(timeout=1.0)
      print(data)
      task.stop()

print(time.time() - startt)
task.close()

 

Code example no. 2:

 

import nidaqmx as n
import numpy as np
import time
import h5py
import os
from nidaqmx.constants import (
TerminalConfiguration,
VoltageUnits,
AcquisitionType,
TriggerType,
Edge,
DigitalWidthUnits
)

 

s_freq = 10000
num_samples = 10000

task = n.Task()

 

task.ai_channels.add_ai_voltage_chan("/Dev3/ai0")

task.ai_channels.add_ai_voltage_chan("/Dev3/ai1")

task.ai_channels.add_ai_voltage_chan("/Dev3/ai2")

 

startt = time.time()

task.timing.cfg_samp_clk_timing(s_freq, "PFI0", active_edge=Edge.RISING, sample_mode=n.constants.AcquisitionType.FINITE, samps_per_chan=num_samples)

task.timing.delay_from_samp_clk_delay_units = nidaqmx.constants.DigitalWidthUnits.SECONDS

task.timing.delay_from_samp_clk_delay = 2.9e-6


data_read = task.read(num_samples)


task.stop()

task.close()

print(time.time() - startt)

0 Kudos
Message 1 of 8
(3,764 Views)

Before getting into implementation let's look at the requirements conceptually, does the below image translate your signals properly?

santo_13_0-1658765791845.png

If you just want an average of the signal between the trigger pulses, using the trigger as a sample clock and a large sampling time/integration time will do the trick (even if returns only one sample, it was integrated over a larger time which is almost the same as averaging)

 

Could you also describe your application in detail to understand the significance of these signals?

 

 

Santhosh
Soliton Technologies

New to the forum? Please read community guidelines and how to ask smart questions

Only two ways to appreciate someone who spent their free time to reply/answer your question - give them Kudos or mark their reply as the answer/solution.

Finding it hard to source NI hardware? Try NI Trading Post
0 Kudos
Message 2 of 8
(3,757 Views)

Hi Santhosh,

 

thanks for your reply. It's almost like that I don't want to integrate the complete time between the trigger pulses only maybe something like 5 to 10 µs. Below you can see how my signals look like. The idea behind taking several data points and averaging them later is originated from the fact, that the signals are not of equal length. Because on the first two channels there are two different photodiodes connected with different rising and fall times. On the third channel there is a refernce signal connected, which is close to a sinusodial with a frequency of 12 Hz, therefore it should be almost constant on the timescale of a few microseconds.

 

Ideally I would like to take several data points after the trigger for roughly 50 µs and average them in the postprocessing to account for the different duration times of the signals. However your idea with this distinct integration time sounds very nice how could I implemet this to test if it works and can one set an arbitrary integration time like for example 5 to 10 µs?

 

Cheers

Fabian

fabi21_0-1658818923523.png

 

0 Kudos
Message 3 of 8
(3,723 Views)

These additional details help understand the requirements better, now on the hardware capabilities - what DAQ device do you use?

 

In general, I am looking at the re-triggerable acquisition concept as per the below articles,

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019MXxSAM&l=en-US

https://www.ni.com/en-us/support/documentation/supplemental/21/retriggerable-tasks-in-ni-daqmx.html

 

 

Santhosh
Soliton Technologies

New to the forum? Please read community guidelines and how to ask smart questions

Only two ways to appreciate someone who spent their free time to reply/answer your question - give them Kudos or mark their reply as the answer/solution.

Finding it hard to source NI hardware? Try NI Trading Post
0 Kudos
Message 4 of 8
(3,707 Views)

Hi Santhosh,

 

I'm using a NI BNC-2110 as an interface conntected to a NI USB-6212 card (16 Inputs, 16 bits, 400 kSa/s, Multifunction I/O) which is connected to my computer.

 

Cheers

Fabian

0 Kudos
Message 5 of 8
(3,704 Views)

Your M-series device doesn't natively support retriggered AI.  But there's an indirect way to accomplish it with a counter task set up as a retriggerable finite pulse train, and an AI task set up to use the counter output as its sample clock.

 

Sorry, I don't know the Python syntax to make it happen , but that's the basic idea.  The links Santhosh provided also describe it.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 6 of 8
(3,662 Views)

Hi Kevin,

 

thanks for your reply. I also noticed with the provided documents, that I have to use this kind of work around with the counters. However I have a question to this procedure. In the document they state one has to use both onboard counters. I am now a bit confused this means for me that one should not use the external trigger directly as sample clock. Does that mean I have to set up basically two sample clocks, one from the external trigger and one to the desired speed of acquisition, and then use the first one to enable the second one? Since I am not getting the described procedure in the documents could you maybe try to explain it to me how to do it then I might be able to translate it to python code. Also if you might explain it in simple labview blocks / or in a block diagram this might help me to translate it.

 

Thanks,

Fabian

0 Kudos
Message 7 of 8
(3,654 Views)

2 counters get *used* but you only explicitly program 1 of them.  On M-series devices such as your USB-6212, finite pulse trains use up both counters.

 

The USB-621x devices have some special limitations however, so I'm not 100% sure if the following will be supported.  Here's what to try:

 

Program one of the counters for Finite Sampling, Implicit Timing, 50 samples, 1 MHz frequency.  Also configure it to use the external pulse as a Start Trigger.   And then further (this is the part I'm not sure is supported), configure it to be retriggerable.  It's possible this is an optional parameter when configuring the Start Trigger?

 

If supported, then for each incoming external pulse, you'll trigger a series of 50 counter pulses at 1 MHz -- a total of 50 microsec worth.  It will then internally rearm itself and be ready for the next external pulse.  And so on.

 

Then you'll configure your AI task to use your counter pulses as its sample clock.  In the function call to set up sample timing, it may look something like: source="\Dev1\Ctr0InternalOutput"

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 8 of 8
(3,635 Views)