Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Slowdown over time calling WriteMultiSample with daqmx on a Cdaq

The answer is a little complicated.  The controller I wrote offers a lot of features (none of which are offered in any one example), so I used the example for building and testing the features as I went, but the final product is quite far from any of the examples.  For this code which I've linked I tried to find an example which allowed me to replicate this, but none of them have the full functionality that I'm looking for (in general they all create the tasks freshly each time they queue data/have a run for instance).

I am using visual studio for all of this development.

Thanks a lot

0 Kudos
Message 11 of 19
(1,266 Views)

I think the best approach it would be to test a simple code with the 2 hardware, only for a check, it seems that is controlled by software time using the timer.start and stop.

What happens if you use the hardware time?

0 Kudos
Message 12 of 19
(1,244 Views)

Thanks for the suggestion.  I assume that when you say running only with hardware you mean I set both tasks to run using their internal clocks and then call 'WriteMultiSamplePort' with the first argument true (so that they start immediately).  

I tried that and unfortunately I still see the same effect.

0 Kudos
Message 13 of 19
(1,234 Views)

Hi,

I just wanted to check back in and see if you had had a chance to look at this anymore.

Thanks a lot,

Adam

0 Kudos
Message 14 of 19
(1,189 Views)

Hi Pardon me,

Did you have any update related to the issue?

Have you changed something in the code?

I'm wondering did you check the example of Generate multiple Voltages updates internal clock or continuously generate voltage waveform internal clock?

or the examples of Digital I/O that are shipped? 

0 Kudos
Message 15 of 19
(1,170 Views)

I believe you suggested that I test a simple example with only 2 hardware.  That is what the example which I posted does and I'm not sure how to make it simpler. 

None of the example pieces of code provided by NI can replicate this issue because none of them (that I've found) allow creating an analog and a digital out on the same session which is necessary to creating the bug.  

Are you aware of this bug or any like it? Have you any suggestions about what I might try?  Are you able to replicate what I see using my code?

Thanks so much,

Adam

0 Kudos
Message 16 of 19
(1,143 Views)

I know there is not much documentation on Text-Based applications, I  know it could be tedious and frustrating, I dont think there's a bug, in this article it talks about synchronize analog output and digital output task but in LabVIEW.

Can you upload your code? or the snippet that you had added is all your code?

maybe we are missing something related to NI-DAQmx functions in text-based.

 

 

 

0 Kudos
Message 17 of 19
(1,130 Views)

I have uploaded my full code that I use for testing this (see below).  This is close to the simplest set of commands for replicating this issue.

 

Additionally is there a reason why you say that you don't think there's a bug?  I would be more than happy to find out that you are correct, but I am wondering if you have information.

 

Thanks for the link on synchronising analog and digital, but as you can see that is not something which I am doing in this case (and whether I do it or not does not effect this bug).

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NationalInstruments.DAQmx;
using System.Diagnostics;
using System.Threading;

// This class is a toy example intended to replicate the issue where queueing of data on the daq gets slower over time (if the timing is being changed)

namespace DaqQueueTimingIncreaseTestExample
{
    class Program
    {
        static void Main(string[] args)
        {
            
            //change these values as desired for testing on another machine
            string[] AnalogOutputChannels = new string[] { "cDAQ1Mod2/ao0" };
            string[] DigitalOutputChannels = new string[] { "cDAQ1Mod3/Port0/line0"};
            string outputFileLocation = "C:\\Users\\Q-State Admin\\Documents\\Adam\\daqTiming.txt"; //this is a file where the timing information will be saved

            //These values exist for experimenting with using them to get around the issue
            string masterClock = "";
            string analogClock = "";
            
            // Setup values:
            int signalNumber = 50;
            int numberOfRuns = 50;
            double daqRate = 7893.846153846154;
            Task analogOutputTask = new Task();
            AnalogMultiChannelWriter analogWriter = new AnalogMultiChannelWriter(analogOutputTask.Stream);
            Task digitalOutputTask = new Task();
            DigitalMultiChannelWriter digitalWriter = new DigitalMultiChannelWriter(digitalOutputTask.Stream);
            Stopwatch timer = new Stopwatch();
            long[] bigQueueTimings = new long[numberOfRuns];
            long[] smallQueueTimings = new long[numberOfRuns];
            


            // Build the daq and connections and make data
            for (int i=0; i < AnalogOutputChannels.Length; i++)
            {
                analogOutputTask.AOChannels.CreateVoltageChannel(AnalogOutputChannels[i],
                    "", -10.0, 10.0, AOVoltageUnits.Volts);
            }
            for(int i=0; i < DigitalOutputChannels.Length; i++)
            {
                digitalOutputTask.DOChannels.CreateChannel(DigitalOutputChannels[i],
                    "", ChannelLineGrouping.OneChannelForEachLine);
            }
            analogOutputTask.Control(TaskAction.Verify);
            digitalOutputTask.Control(TaskAction.Verify);

            int[,] digitalSignals = new int[DigitalOutputChannels.Length, signalNumber];
            int[,] smallerDigitalSignals = new int[DigitalOutputChannels.Length, 2];
            double[,] analogSignals = new double[AnalogOutputChannels.Length, signalNumber];
            double[,] smallerAnalogSignals = new double[AnalogOutputChannels.Length, 2];

            // Setting up initial timing
            analogOutputTask.Timing.ConfigureSampleClock(masterClock, daqRate,
                    SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, 100);
            digitalOutputTask.Timing.SampleTimingType = SampleTimingType.SampleClock;
            digitalOutputTask.Timing.ConfigureSampleClock(analogClock, daqRate,
                SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, 100);

            // performing runs
            for (int runCounter = 0; runCounter < numberOfRuns; runCounter++)
            {
                //setup first timing 
                timer.Reset();
                analogOutputTask.Timing.SamplesPerChannel = analogSignals.Length;
                digitalOutputTask.Timing.SamplesPerChannel = digitalSignals.Length;
                timer.Start();
                digitalWriter.WriteMultiSamplePort(false, digitalSignals);
                analogWriter.WriteMultiSample(false, analogSignals);
                timer.Stop();
                bigQueueTimings[runCounter] = timer.ElapsedMilliseconds;
                Console.WriteLine(bigQueueTimings[runCounter].ToString());

                // run out those signals
                digitalOutputTask.Start();
                analogOutputTask.Start();
                while(!analogOutputTask.IsDone || !digitalOutputTask.IsDone)
                {
                    System.Threading.Thread.Sleep(2);
                }
                digitalOutputTask.Stop();
                analogOutputTask.Stop();

                //setup second timing
                timer.Reset();
                analogOutputTask.Timing.SamplesPerChannel = smallerAnalogSignals.Length;
                digitalOutputTask.Timing.SamplesPerChannel = smallerDigitalSignals.Length;
                timer.Start();
                digitalWriter.WriteMultiSamplePort(false, smallerDigitalSignals);
                analogWriter.WriteMultiSample(false, smallerAnalogSignals);
                timer.Stop();
                smallQueueTimings[runCounter] = timer.ElapsedMilliseconds;
                Console.WriteLine(smallQueueTimings[runCounter].ToString());

                // run out those signals
                digitalOutputTask.Start();
                analogOutputTask.Start();
                while (!analogOutputTask.IsDone || !digitalOutputTask.IsDone)
                {
                    System.Threading.Thread.Sleep(2);
                }
                digitalOutputTask.Stop();
                analogOutputTask.Stop();
            }

            // record data
            using (System.IO.StreamWriter file =
                new System.IO.StreamWriter(@outputFileLocation))
            {
                file.WriteLine("Small Queue Timings:");
                file.Write("[");
                foreach(int time in smallQueueTimings)
                {
                    file.Write(time.ToString() + ", ");
                }
                file.WriteLine("]");
                file.WriteLine("Big Queue Timings:");
                file.Write("[");
                foreach (int time in bigQueueTimings)
                {
                    file.Write(time.ToString() + ", ");
                }
                file.Write("]");
            }

        }
    }
}
0 Kudos
Message 18 of 19
(1,127 Views)

Hi!

Unfortunately, I didn't find a cDAQ-9264 to reproduce it, I think the best approach it would be to contact directly NI-Support  866 275 6964, to replicate the system and see if there is a bug.

0 Kudos
Message 19 of 19
(1,114 Views)