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.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Finite-sample async AI with concurrent background data retrieval

Can anyone clarify the timing for AI asynchronous input via AnalogMultiChannelReader (I'm using VB.Net 2005 with NiDaqmx 8.6) and have reviewed the examples.  I'm confused about the timing issues.

I want to aquire 1000 samples/channel for 4 channels over 60 seconds and I need to know/calculate the time of each sample relative to the start time.  I also want to display a dynamic graph of the data vs time during aquisition as a background operation.  The data I need is basically 4 waveforms (one from each AI channel) versus time.

The question is how to retrieve samples in the background of a single 1000 sample/channel acquisition.  If I use the asynchronous start method specifying 1000 samples, I won't get a callback until all 1000 samples are complete but I will be assured a very very regular time between samples.  If use BeginReadSingleSample for continuous acquisition (SamplesPerChannel = -1) I can use a callback to collect data in the background and quit when I reach at least 1000 samples.  The problem/question is if I use a series of Begin/End operations will I loose all control of the timing between samples (which should be very close to 0.060 seconds between each sample)?

Am I missing a way to simply read/retrieve data during aquisition without interrupting the 1000 sample acquision process?

I'd really appreciate it if someone could clear up my fuzzy thinking on this issue!!!
0 Kudos
Message 1 of 8
(4,207 Views)
Hello mjcatt,

I would recommend that you use the ReadMultiSample method to read your data in a call back that occurs asynchronously. As stated in the documentation for this method in the NI-DAQmx .NET Framework 2.0 Help (Start>>All Programs>>National Instruments>>NI-DAQ😞

"If you set samplesPerChannel (parameter) to -1 for a finite acquisition, the read behavior is set by the ReadAllAvailableSamples property of the DaqStream you are reading from."

By setting the ReadAllAvailableSamples property to true, you can read all the available samples during your finite acquisition and plot the data dynamically as you are acquiring. An example of this use can be found in the example called ContAcqVoltageSamples_IntClk. This example performs a continuous acquisition, so you would need to change the ConfigureSampleClock method to set the SampleQuantityMode to FiniteSamples and set the ReadAllAvailableSamples property as described above. This would allow you to read 1000 samples on your channels at whatever rate you wanted (approximately 17 Hz should give you just over 1000 samples in 60 seconds). This document describes where to find .NET examples for NI-DAQmx, NI-VISA and NI-488.2.

Matt Anderson

Hardware Services Marketing Manager
National Instruments
0 Kudos
Message 2 of 8
(4,167 Views)

Matt,

Thanks for your comments. I had reviewed the examples, which are somewhat misleading.  The NI example asynchronous code is as follows:

    Public Sub New(ByVal t As Task)
        'Create the reader
        reader = New AnalogSingleChannelReader(t.Stream)
        'Acquire 100 samples
        Dim handle As IAsyncResult
        handle = reader.BeginReadMultiSample(100,AddressOf OnDataReady,Nothing)
    End Sub

    Public Sub OnDataReady(i As IAsyncResult)
        'Retrieve the data that was read.
        'At this point, any exceptions that occurred during the asynchronous read are thrown
        Dim data As Double()
        data = reader.EndReadMultiSample(i)

        'You can call the BeginReadMultiSample method here again
    End Sub

This lead me to believe that a call to BeginReadMultiSample initiates a measurement sequence (which apparently it does) - it was unclear if every call to BeginReadMultiSample would want to initiate a new measurement sequence in addition to reading samples.

In fact the code I needed was (this is just a very simplified example), which now seems obvious:

mytask.Timing.ConfigureSampleClock("", SampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, NSamp)
Reader = New AnalogMultiChannelReader(mytask.Stream)
mytask.Start
DO WHILE NOT mytask.IsDone
  data = Reader.ReadWaveform(-1)
  DIM  Count AS INTEGER = data(0).Samples.Count
  IF Count > 0 THEN
    FOR i AS INTEGER = 0 TO Count - 1
      ' process data and update real-time display
    NEXT
  END IF
LOOP

Thanks again.  Regards,

Mark

0 Kudos
Message 3 of 8
(4,146 Views)
 Hello Mark,

It sounds like you've got some code working that accomplishes what you need, but I wanted to post back to expand on the topic a little. Specifically, I wanted to clarify the difference between starting and stopping a task and beginning and ending a reader. Starting and stopping a task actually tells the hardware to begin and end a data acquisition session. As described in the NI-DAQmx .NET 2.0 Framework Help (Start>>All Programs>>National Instruments>>NI-DAQ), the Task.Start method "Transitions the task to the running state, which begins the measurement or generation." You can find more details about the NI-DAQmx state model in the NI-DAQmx Help (Start>>All Programs>>National Instruments>>NI-DAQ). The transition to the running state performs the following:

"When the task begins to perform the specified operation, the task transitions from the Committed state to the Running state. You can explicitly perform this transition by invoking the Start Task function/VI. Notice that starting a task does not necessarily start acquiring samples or generating a waveform. You might have specified the timing and triggering attributes/properties such that a sample is not acquired until you call the Read function/VI or a waveform is not generated until a trigger is detected. In general, the start transition does not fail. If it does, it is an exceptional condition, and the task remains in the Committed state. If the task begins to perform the specified operation, the task is successfully started and transitions to the Running state."

In contrast, the reader class is used to configure how data will be read in the .NET ADE. For example, the AnalogMultiChannelReader class "Contains methods for reading samples from one or more analog input channels in a task." It does not change the state in hardware or affect how the hardware acquires data. Rather, it allows you to configure how you will read the data into your program. You can configure your reader class to invoke events and callbacks through the Invoke method of the implementation or invoke have events and callbacks directly. This allows you to configure your program to read data asynchronously from the task. If you examine your code, you are not reading the data asynchronously. You are using the while loop and the for loop to execute your code line by line and perform your operations in order. In contrast, you could use a reader class to asynchronously enter a callback on the occurence of an event. This means that you could be executing completely separate code and then handle the data acquisition whenever a certain event occurred (like a set number of data points having been read).

I hope this clarifies the difference between starting a task and beginning a reader.

Matt Anderson

Hardware Services Marketing Manager
National Instruments
0 Kudos
Message 4 of 8
(4,136 Views)
I am having a similar problem here. And every time I try to read the samples from my DIO I get a message saying that the task was stopped and that I am trying to read beyond the final sample acquired. Interestingly I write the number of samples to a text box control (I am using VB.NET)  and the number there is 127.
 
Some parts of my code:

TaskAB.Stream.ReadRelativeTo = ReadRelativeTo.FirstSample

'New: configure clock to acquire finite number of samples

TaskAB.Timing.ConfigureSampleClock(ClockOutSrcAB, Convert.ToDouble(TRANSFER_HZ), SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples,

CType(CMB_NUMPOINTS.Text, Integer))

'Configure task to be Burst Handshake Timing protocol:

TaskAB.Timing.ConfigureHandshakingBurstExportClock(ClockOutSrcAB, Convert.ToDouble(TRANSFER_HZ), DigitalLevelPauseTriggerCondition.Low, ReadyForTransferEventLevelActiveLevel.ActiveHigh, SampleClockPulsePolarity.ActiveHigh, SampleQuantityMode.FiniteSamples,

CType(CMB_NUMPOINTS.Text, Integer))

.

.

.

ReaderAB.BeginReadMultiSamplePortInt32(DataMult *

CType(CMB_NUMPOINTS.Text, Integer), asyncDigitalCallbackAB, TaskAB)

.

.

.

M_Buffer = ReaderAB.EndReadMultiSamplePortInt32(async_req)  <== this is where it sends the exception -200278

 

Do you have any ideas why this is happening? I need to collect, say, 128 samples from my DIO at 20 MHz. Then get this data to a vector of long integers. Thank you for any suggestions.



Message Edited by leosgb on 12-18-2007 04:35 PM
0 Kudos
Message 5 of 8
(3,985 Views)

Hello,

Two things can be happening here … either way the error code related to trying to get samples that are not available.  One you are trying to pull samples that are not there, since the number you are trying to read in the callback is larger than the amount currently acquired / available. As Matt stated above in post 2, you can read all the available samples using the ReadAllAvailableSamples and setting it to true.  Try enabling the ReadAllAvailableSamples property. 

In addition, the error could also be accruing if all the samples specified in the finite acquisition have already been acquire and now the callback task cannot link to an acquisition in process.  This is more likely the case given the 20 MHz rate and only 128 samples needed.  You might want to consider using continuous mode, increasing the 128 number, or using post processing instead of using a callback.   

Samantha
National Instruments
Applications Engineer
0 Kudos
Message 6 of 8
(3,967 Views)
Hi samantham,
 
How do I use a post processing? Let me briefly explain what I have here: I have a working program that used the Traditional DAQ library with a DIO 6533. With that library/DIO I was capable of acquiring 128 samples at 20 MHz and bring them to a MSChart (in VB 5). Now I am trying to use a DIO 6537 with the DAQmx library. I want to do the same.
 
I already configured the card to operate in continuous mode using a callback. Now I would like to do something similar but acquire just a limited number of samples.
 
Could you direct me to an example for the post processing? I think that what is happening is that somehow my task is completed and then when I try to read the data from the buffer it is not there anymore.
 
Thank you for any suggestions.
0 Kudos
Message 7 of 8
(3,964 Views)

Hello,

For post processing, I would suggest writing the data to a file and reading from it at a later point in time.  I do however think that running in continuous mode would be a better option, if possible.  Or I also see from your description of the application that I can recommend some examples.  The DAQmx .Net examples download to two different locations mattering what version of Drivers you have downloaded.  Please refer to the Knowledge Base linked below for the path locations.  The examples on my computer are located at C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\DotNET2.0 and I have DAQmx 8.6.  I opened up the example titled ContReadDigitalChan_ExtClk.2005.  I modified the example to take an internal clock by referencing the ReadDigChan_IntClk_PatternMatchStart and changed it from continuous to finite.  I hope this helps.  Please note that when you posted that you were using VB 5, I assumed you were using 2005 since this was initially a .NET post and you stated you have a similar issue.

NI-DAQmx, NI-VISA and NI-488.2 .NET Example Locations

 

Samantha
National Instruments
Applications Engineer
0 Kudos
Message 8 of 8
(3,947 Views)