05-02-2016 12:46 PM
I'm trying to get an NI 4065 to grab 1500 samples in 1 second with 4.5 digits of accuracy. First attempt was to use the waveform acquisition class and methods exposed by the NIDmm class in the NI-Dmm .NET library, but that is not available on the NI 4065. Can't make things easy, can we?
Anyways, there is multipoint reading, which looks like what I want, but something isn't right. Here's the code.
public Task<List<double>> MeasureCurrentAsync() { return Task.Run<List<double>>(() => { const int pointsToFecth = 1500; List<double> samples = new List<double>();
multimeter = new NIDmm(dmmSlot, true, true);
multimeter.ConfigureMeasurementDigits(DmmMeasurementFunction.DCCurrent, 1.0, 4.5); multimeter.Trigger.MultiPoint.SampleTrigger = DmmSampleTrigger.Interval; multimeter.Trigger.MultiPoint.SampleCount = pointsToFecth; double sampleInterval = 1.0 / (double)(pointsToFecth); multimeter.Trigger.MultiPoint.SampleInterval = new NationalInstruments.PrecisionTimeSpan(sampleInterval); AutoResetEvent waitForEnd = new AutoResetEvent(false);
//Setup an anonymous callback to read the points and let the Task continue on. multimeter.Measurement.ReadMultiPointCompleted += (o, e) => {
Tracing.TraceEvent(TraceEventType.Information, 0, "Total samples actually read: {0}", e.ActualNumberOfPoints); samples.AddRange(e.Reading); waitForEnd.Set(); }; Stopwatch sw = new Stopwatch(); sw.Start(); multimeter.Measurement.ReadMultiPointAsync(pointsToFecth, null);
//Wait unitl the above anonymous callback is called. waitForEnd.WaitOne(); sw.Stop(); Tracing.TraceEvent(TraceEventType.Information, 0, "Collected {0} samples in {1}ms", multimeter.Trigger.MultiPoint.SampleCount, sw.ElapsedMilliseconds); return samples; }); }
The above code sets up the NIDmm (called "multimeter") to read 1500 samples in 1 second, with the dmm configured to measure DC current. I would expect the Stopwatch to report that is took about 1000ms to collect those 1500 samples, but the logs (outputted by Tracing.TraceEvent) are saying it took 1525ms.
But here's the weird part: If I drop the number of samples to 1000, then the total sample collection time drops to 350ms. According to the manual, the NI 4065 should be able to collect up to 3000 samples per second when configured to 4.5 digit resolution.
How can I get the NI 4065 to collect a specified number of samples in a specified time frame, provided I don't exceed its specifications?
05-02-2016 01:10 PM
A little more info:
Here's some pointsToFetch vs collection time:
Points Collection Time
1 41ms
2 520ms
4 771ms
8 897ms
16 963ms
32 999ms
64 1025ms
128 1055ms
256 1102ms
512 1189ms
1024 1362ms
2048 1716ms
I was expecting all of those to be close to 1000ms (1 second). I am completely bamboozeled by this.
05-03-2016 07:53 AM
Hi CurtisHX,
I have a couple questions that might help:
1) For your ReadMultiPointAsync() call (shown below), is there a reason you passed pointsToFecth as a parameter? The function definition shows that the first parameter is expecting a PrecisionTimeStamp maximumTime where the maximumTime is the allowed time in ms for this method to complete.
multimeter.Measurement.ReadMultiPointAsync(pointsToFecth, null);
2) Have you checked if the method was timing out or returning some other error? From the API Reference "You will get a Ivi.Driver.IOTimeoutException if the function does not complete within the specified time interval. This exception happens if an external trigger has not been received or if the specified timeout is not long enough for the acquisition to complete." As well, does the data returned look reasonable?
3) Is your Stopwatch measuring true acquisition time? Wouldn't it be measuring the time from start, time to complete ReadMultiPointAsync method (which has overhead and processing time beyond the actual acquisition time) and then also the time it takes for your callback to execute?
05-03-2016 08:11 AM
Hi Jon,
To answer your questions,
1) There are 3 overloaded ReadMultipointAsync methods, one of which takes a "pointsToFetch" parameter. I have not tried the others yet.
public void ReadMultiPointAsync(PrecisionTimeSpan maximumTime, object userState); public void ReadMultiPointAsync(int pointsToFetch, object userState); public void ReadMultiPointAsync(PrecisionTimeSpan maximumTime, int pointsToFetch, object userState);
2) No exceptions or errors, and the data looks good.
3) The stopwatch is measuring the time it takes to call ReadMultiPointAsync and read the points in. The overhead of calling ReadMultiPointAsync is significantly less than my target acquisition. I think I measured it at something like 0.5ms. Callback execution time is also too short to have an impact.
I did get a few more ideas to try out, though. Thanks.
05-04-2016 01:38 PM
The plot thickens.....
I tried doing multi point read, passing in a PrecisionTimeSpan of 1.2 seconds to the first parameter of NIDmm.Measurement.ReadMultiPointAsync. NIDmm.Measurement.MultiPoint.SampleCount was still set to 1000.
It timed out after 2000ms, not 1200ms.
05-04-2016 01:59 PM
List<double> rVal = new List<double>(); multimeter.ConfigureMeasurementDigits(DmmMeasurementFunction.DCCurrent, 1.0, 4.5); const int samples = 1000; multimeter.Trigger.MultiPoint.SampleCount = samples; multimeter.Trigger.MultiPoint.SampleInterval = new NationalInstruments.PrecisionTimeSpan(1.0 / samples); Stopwatch sw = new Stopwatch(); sw.Start(); rVal.AddRange(multimeter.Measurement.ReadMultiPoint(samples)); sw.Stop(); Tracing.TraceEvent(TraceEventType.Information, 0, "Took {0} ms to measure {1} samples", sw.ElapsedMilliseconds, samples); return rVal;
This is a simplified version of the above code, but I still get the same results. Why does the Trigger.MultiPoint.SampleInterval have no effect on the time needed to take multiple samples?