Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Is there an equivalent for MemoryOptimizedRead for counter input?

Solved!
Go to solution
The analog reader classes have MemoryOptimizedReadWaveform methods.  I don't see anything equivalent in the CounterReader class.  Is there a way to perform that kind of read (to reduce GC churn) for counter data using the .NET API?  I know the C API has it, but I'd rather not P/Invoke if I don't have to.
0 Kudos
Message 1 of 11
(6,270 Views)

Hi Gabriel-r,

 

There isn't an equivalent optimized read for counters. You can find all of the methods of the CounterReader class in the NI DAQmx .NET  Framework Help then search for CounterReader.  You can see all of the methods that you can use.

Regards,
Jim Schwartz
0 Kudos
Message 2 of 11
(6,244 Views)

Hi Jim,

 

Thank you for your response. 

 

In case someone else comes across the same problem (lack of MemoryOptimized methods in CounterReader), I will post here my workaround, which involves building a C DLL to expose the DAQmx C API, and then calling it via platform-invoke from C#.  Note that the C# digs into the internals of the Task object, so don't be suprised if it breaks in future versions of DAQmx.  Disclaimers aside, this seems to work correctly on version 9.0.

 

 

/* C code: Compile to CWrapper.dll, depends on static library nidaqmx.lib */

#include <NIDAQmx.h>
dllexport int32 __CFUNC ReadCounterU32 (TaskHandle taskHandle,

    int32 numSampsPerChan, float64 timeout, uInt32 readArray[],

    uInt32 arraySizeInSamps, int32 *sampsPerChanRead)
{
    return DAQmxReadCounterU32(taskHandle, numSampsPerChan,

      timeout, readArray, arraySizeInSamps, sampsPerChanRead, NULL);
}



// C# code

using System;

using System.Reflection;
using System.Runtime.InteropServices;
using NationalInstruments.DAQmx;


[DllImport("CWrapper.dll")]
extern static int ReadCounterU32(IntPtr taskHandle, int numSampsPerChan,

          double timeout, uint[] readArray, int arraySizeInSamps,

          out int samplesPerChanRead);

unsafe static IntPtr GetTaskHandle(Task t)
{
    var pTaskField = typeof(Task).GetField("m_pTask",

            BindingFlags.Instance | BindingFlags.NonPublic);
    object asObj = pTaskField.GetValue(t);
    return (IntPtr)Pointer.Unbox(asObj);
}

 

// can now read from a counter Task by first getting its IntPtr taskHandle

// and then passing that into the extern ReadCounterU32

// according to the C API documentation

 

 

Best,

Gabriel

0 Kudos
Message 3 of 11
(6,241 Views)

Gabriel -

 

Thank you for posting your code showing how to do this via the C API.

We will add implementation of MemoryOptimizedRead for counter input to our list of items to add in a future version of the DAQmx .NET API.

 

Do you have a similar need for digital?

Is there any other functionality that you see as missing from the .NET API?

 

David Rohacek

National Instruments

 

 

0 Kudos
Message 4 of 11
(6,233 Views)

Hi David,

 

I don't have a similar need for digital read at the moment.  But I'd add that even the current MemoryOptimizedRead has some disadvantages compared to the C API:

 

  1. With the C API, in a continuous acquisition you can call Read(numSampesPerChan=-1, arraySize=buffer.Length, ...) to read all available samples, but not overrun the buffer. As far as I can tell, MemoryOptimizedRead doesn't provide the same functionality, since it is impossible to specify an "arraySize"-like parameter:
    • If numSamplesPerChan=-1, and if there are more samples available than space in the buffer, a larger buffer is allocated and returned in its place. 
    • If numSamplesPerChan > 0, then, like in the C API, the MemoryOptimizedRead will block until that many samples are available
  2. Actually getting at the samples returned from MemoryOptimizedRead requires an extra buffer copy, since AnalogWaveform<T> doesn't expose its internal buffer (all three overloads of AnalogWaveform.GetRawData() do a copy)

 

For these reasons, I prefer my ugly p/invoke hack to the API-provided MemoryOptimizedRead, and will use it even for Analog acquisition.

 

So for future versions of the .NET API, I'd suggest adding a set of NonAllocatingRead() methods to the AnalogReader and CounterReader classes, which just wrap the C functions:

        public void NonAllocatingRead(int samplesPerChannel, double[] readArray, out int samplesPerChannelRead);

 

If that were available, I'd gladly use it over my p/invoke hack.

 

Best,

Gabriel

 

Message Edited by Gabriel-r on 11-03-2009 02:47 PM
0 Kudos
Message 5 of 11
(6,221 Views)

Gabriel -

 

 

Thank you for your feedback. We did have #2 on our radar, but not #1. We're now tracking #1; I can't commit to when we'll implement these enhancements (fixes?) in the DAQmx .NET API, but we have given them a high prioriry.

 

Just a note of interest - the DAQmx .NET API is not a layer on top of the C API, so implementations of these functions cannot be done as simple wrappers. The C, LabVIEW, and .NET APIs are all at the same layer in the software stack. This architecture yields some performance benefit over putting the .NET API on top of the C API.

 

David Rohacek

National Instruments

Message Edited by drohacek on 11-04-2009 02:59 PM
0 Kudos
Message 6 of 11
(6,182 Views)

Good to hear--  Thanks, David.

0 Kudos
Message 7 of 11
(6,178 Views)

Hi Gabriel,

 

I just wanted to follow up with you regarding the issues you brought up. In the latest DAQmx release, NI-DAQmx 9.1, we now provide the functionality you requested in #1 for AnalogSingleChannelReader and AnalogMultiChannelReader. We have new overloads for MemoryOptimizedReads that address #1.

 

We still need to provide this same functionality for Digital and Counter Readers. We have plans to provide this functionality in a future NI-DAQmx release, but we cannot commit right now as to when we can provide this functionality. As soon as we have this functionality, I will update this thread again to let you know.

 

 

Canisius Rozario

National Instruments

0 Kudos
Message 8 of 11
(5,792 Views)
Solution
Accepted by topic author Gabriel-r

Hi Gabriel,

 

The feature that you were looking for (MemoryOptimizedRead for Counter Input) is now available with NI-DAQmx 9.4 release.

Please see http://joule.ni.com/nidu/cds/view/p/id/2604/lang/en for more details.

 

Feel free to post any questions you have.

 

Thanks

Bhavesh Shura

National Instruments

0 Kudos
Message 9 of 11
(4,726 Views)

Hi Canisius and Bhavesh,

 

Thank you for the features, and for keeping this thread updated. I really appreciate this kind of customer support.

 

Have there been any changes regarding point #2 from my post of 3-Nov-2009? David Rohacek replied saying that issue was being tracked, but I haven't seen any follow-up.

 

Thanks for your time,

Gabriel

0 Kudos
Message 10 of 11
(4,713 Views)