Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Data reading with NI USB DAQ 6343 X series

Solved!
Go to solution

Hi

i have a couple of question regarding the code c# and using NI USB DAQ 6343

 

i have a project with couple of data acquisition. i added function generator function to my code from NI examples 

1:

// functiongenerator.cs
public static double[] GenerateSineWave( double frequency, double amplitude, double sampleClockRate, double samplesPerBuffer) { double deltaT = 1/sampleClockRate; // sec./samp int intSamplesPerBuffer = (int)samplesPerBuffer; double[] rVal = new double[intSamplesPerBuffer]; for(int i = 0; i < intSamplesPerBuffer; i++) rVal[i] = amplitude * Math.Sin( (2.0 * Math.PI) * frequency * (i*deltaT) ); return rVal; }
// mainform.cs
private void startButton_Click(object sender, System.EventArgs e)
        {
            // Change the mouse to an hourglass for the duration of this function.
            Cursor.Current = Cursors.WaitCursor;

            // Read UI selections
     /*       DigitalEdgeStartTriggerEdge triggerEdge;
            if (this.triggerEdgeComboBox.Text == "Rising")
                triggerEdge = DigitalEdgeStartTriggerEdge.Rising;
            else
                triggerEdge = DigitalEdgeStartTriggerEdge.Falling;
*/
            try
            {
                // Create the master and slave tasks
                inputTask = new Task("inputTask");
                outputTask = new Task("outputTask");

                // Configure both tasks with the values selected on the UI.
                inputTask.AIChannels.CreateVoltageChannel(inputChannelComboBox.Text,
                    "",
                    AITerminalConfiguration.Differential,
                    Convert.ToDouble(inputMinValNumeric.Value),
                    Convert.ToDouble(inputMaxValNumeric.Value),
                    AIVoltageUnits.Volts);

                outputTask.AOChannels.CreateVoltageChannel(outputChannelComboBox.Text,
                    "",
                    Convert.ToDouble(outputMinValNumeric.Value),
                    Convert.ToDouble(outputMaxValNumeric.Value),
                    AOVoltageUnits.Volts);

                // Set up the timing
                inputTask.Timing.ConfigureSampleClock("",
                    Convert.ToDouble(rateNumeric.Value),
                    SampleClockActiveEdge.Rising,
                    SampleQuantityMode.ContinuousSamples,
                    Convert.ToInt32(samplesNumeric.Value));

                outputTask.Timing.ConfigureSampleClock("",
                    Convert.ToDouble(rateNumeric.Value),
                    SampleClockActiveEdge.Rising,
                    SampleQuantityMode.ContinuousSamples,
                    Convert.ToInt32(samplesNumeric.Value));

                // Set up the start trigger
                
                string deviceName = inputChannelComboBox.Text.Split('/')[0];
                string terminalNameBase = "/" + GetDeviceName(deviceName) + "/";
        //        outputTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(terminalNameBase + "ai/StartTrigger", triggerEdge);

                // Verify the tasks
                inputTask.Control(TaskAction.Verify);
                outputTask.Control(TaskAction.Verify);

                // Write data to each output channel
                FunctionGenerator fGen = new FunctionGenerator(Convert.ToString(frequencyNumeric.Value),
                    Convert.ToString(samplesNumeric.Value),
                    Convert.ToString(frequencyNumeric.Value / (rateNumeric.Value / samplesNumeric.Value)),
                    waveformTypeComboBox.Text,
                    amplitudeNumeric.Value.ToString());

                output = fGen.Data;

                writer = new AnalogSingleChannelWriter(outputTask.Stream);
                writer.WriteMultiSample(false, output);

                // Officially start the task
                StartTask();

                outputTask.Start();
                inputTask.Start();

                // Start reading as well
                inputCallback = new AsyncCallback(InputRead);
                reader = new AnalogSingleChannelReader(inputTask.Stream);
                
                
                // Use SynchronizeCallbacks to specify that the object
                // marshals callbacks across threads appropriately.
                reader.SynchronizeCallbacks = true;
                
                reader.BeginReadMultiSample(Convert.ToInt32(samplesNumeric.Value), inputCallback, inputTask);

            }
            catch (Exception ex)
            {
                StopTask();
                MessageBox.Show(ex.Message);
            }
        }

my question is: could i generate frequencies from AO0/AO1 up to 5KHz - 10KHz,  in NI MAX with creating task , i can not generate frequencies more then 900Hz.

 

2:

 

i need to measure 2 channels in same time AI2-AI3, next loo AI3-AI4

i understand i nee to set the device  with this syntax Dev1/AI2, Dev1/AI3

but that is next how i can set all necessary data to my code and how i can read it to datatable

 

3:

how i can save data continuously to my excel file, do i need to use threads, or i can buffer all data and at the end of the test

save all data to excel file at once.

 

 

 

0 Kudos
Message 1 of 7
(3,869 Views)

Hi

the answer to 2 point

is 

two channels AI0 and AI1 will measure data and stores it to buffer

// Configure both tasks with the values selected on the UI.
                    inputTask.AIChannels.CreateVoltageChannel("Dev1/ai0:1",
                        "",
                        AITerminalConfiguration.Rse/*   Differential*/,
                        inputMinValNumeric,
                        inputMaxValNumeric,
                        AIVoltageUnits.Volts);

                    

as well it must be declared 2 size variable double [,] data:

private void InputRead(IAsyncResult ar)
        {

            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the data
                    double[,] data = reader.EndReadMultiSample(ar);

                    // Display the data
                    for (int i = 0; i < inputDataTable.Rows.Count && i < data.Length; i++)
                    {
                        inputDataTable.Rows[i][0] = data[0, i];
                        inputDataTable.Rows[i][1] = data[1, i];
                    }
                    for (int i = data.Length; i < inputDataTable.Rows.Count; i++)
                    {
                        inputDataTable.Rows[i][0] = DBNull.Value;
                        inputDataTable.Rows[i][1] = DBNull.Value;
                    }

                    // Set up next callback
                    reader.BeginReadMultiSample(Convert.ToInt32(samplesNumeric), inputCallback, inputTask);
                }
            }
            catch (Exception ex)
            {
                StopTask();
                MessageBox.Show(ex.Message);
            }
        }
0 Kudos
Message 2 of 7
(3,803 Views)

Hi Arbo,

 

1. For two AO channels you will be able to get a maximum output of 840 kS/s per channel.  So if you calculate that out you can output a wave with (x samples) * 5kHZ  = 840kS,  then you can write a waveform with 160 samples at 5kHz, and 80 samples at 10kHz.

 

2. looks like you have that figured out

 

3.  If you are writing data continuously to an excel file I would suggest opening a separate thread.  Otherwise you may have issues with buffer overflow if you have a long test.

 

0 Kudos
Message 3 of 7
(3,784 Views)

Hi

thanks for your answers, i will be more specific i'm using only one channel AO0 and for measurements 2 channels AI.

in the program i want to use this type of loop

 

for(freq=10; freq<100; freq++) frequency loop

{

   for (i=0;i<3;i++)    some switch control

   {

          thread ( generates sinus and measurement of data)

           writing data to file (csv or excel)

   }

}

may be if all data will be finite 1000-2000 points. will it work , how i can implement this type of program.

 

i did not found any examples of using threads.

 

0 Kudos
Message 4 of 7
(3,780 Views)
Solution
Accepted by topic author Arbo

Hi Arbo,

 

From that pseudo code, i presume that you aren't going to be generating/recording continuous data.  Since that is the case, you don't need to open a new thread.  You'll just have to synchronize input and output, and then log the data to excel after the task is done.  To find examples of how to do that, look in visual studio at the menu item measurement studio->find examples.  You'll be able to find input and output examples, put them together, and loop over your frequency sweep.

 

Again, you will have to decide what frequency you want your output to be, and then calculate the max number of samples at that frequency.  If you refer to my last post you can see how I calculated out a max of 160 samples at 5kHz and 80 samples at 10kHz.

0 Kudos
Message 5 of 7
(3,760 Views)

Thanks very much the code for your solution is 

private void cmd_start_Click(object sender, EventArgs e)
        {
            // Change the mouse to an hourglass for the duration of this function.
            Cursor.Current = Cursors.WaitCursor;

            // Read UI selections
                   DigitalEdgeStartTriggerEdge triggerEdge;
                  // if (this.triggerEdgeComboBox.Text == "Rising")
                       triggerEdge = DigitalEdgeStartTriggerEdge.Rising;
                  // else
                   //    triggerEdge = DigitalEdgeStartTriggerEdge.Falling;

            try
            {
                //list of frequencies from the file
                for (int freqcount = 0; freqcount < matrix_data.Count; freqcount++)
                {
                    //group count A, B, C = 3
                    for (group_index = 0; group_index < 3; group_index++)
                    {
                        writing_DO("Dev1/port0", "", Group_Array[group_index]);

                        // Create the master and slave tasks
                        inputTask = new Task("inputTask");
                        outputTask = new Task("outputTask");

                        // Configure both tasks with the values selected on the UI.
                        inputTask.AIChannels.CreateVoltageChannel(Group_Channel_AI[group_index], "", AITerminalConfiguration.Rse, Convert.ToDouble(inputMinValue), Convert.ToDouble(inputMaxValue), AIVoltageUnits.Volts);

                        outputTask.AOChannels.CreateVoltageChannel(Generator_AO, "", Convert.ToDouble(inputMinValue), Convert.ToDouble(inputMaxValue), AOVoltageUnits.Volts);

                        // Set up the timing
                        //inputTask.Timing.ConfigureSampleClock("", Convert.ToDouble(rateNumeric), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(samplesNumeric));
                        inputTask.Timing.ConfigureSampleClock("", Convert.ToDouble(rateNumeric), SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, Convert.ToInt32(samplesNumeric));

                        //outputTask.Timing.ConfigureSampleClock("", Convert.ToDouble(rateNumeric), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(samplesNumeric));
                        outputTask.Timing.ConfigureSampleClock("", Convert.ToDouble(rateNumeric), SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(samplesNumeric));

                        // Set up the start trigger

                        string deviceName = "Dev1";
                        string terminalNameBase = "/" + GetDeviceName(deviceName) + "/";

                        outputTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(terminalNameBase + "ai/StartTrigger", triggerEdge);

                        // Verify the tasks
                        inputTask.Control(TaskAction.Verify);
                        outputTask.Control(TaskAction.Verify);
                        double result = frequencyNumeric / (rateNumeric / samplesNumeric);

                        // Write data to each output channel
                        //FunctionGenerator fGen = new FunctionGenerator(matrix_data[group_index].freq/*Convert.ToString(frequencyNumeric)*/, Convert.ToString(samplesNumeric), Convert.ToString(frequencyNumeric / (rateNumeric / samplesNumeric)), "Sine", /*amplitudeNumeric*/ matrix_data[group_index].Voltage_Gen.ToString());
                        FunctionGenerator fGen = new FunctionGenerator(outputTask.Timing, matrix_data[group_index].freq, Convert.ToString(samplesNumeric), Convert.ToString(frequencyNumeric / (rateNumeric / samplesNumeric)), "Sine", matrix_data[group_index].Voltage_Gen.ToString());

                        output = fGen.Data;

                        writer = new AnalogSingleChannelWriter(outputTask.Stream);
                        writer.WriteMultiSample(false, output);

                        // Officially start the task
                        StartTask();

                        outputTask.Start();
                        inputTask.Start();

                        // Start reading as well
                        inputCallback = new AsyncCallback(InputRead);
                        
                        reader = new AnalogMultiChannelReader(inputTask.Stream);


                        

                        // Use SynchronizeCallbacks to specify that the object marshals callbacks across threads appropriately.
                        reader.SynchronizeCallbacks = true;

                        
                        //reader.BeginReadMultiSample(samplesNumeric, inputCallback, inputTask);

                        data = reader.ReadWaveform(samplesNumeric);

                        dataToDataTable(data, ref inputDataTable);

                       
                        //outputTask.WaitUntilDone();
                        inputTask.WaitUntilDone();
                        StopTask();
                        file_save(inputDataTable, freqcount, group_index);
                    }
                }
            }
            catch (Exception ex)
            {
                StopTask();
                MessageBox.Show(ex.Message);
            }

        }

it works and saving the data to csv file

 

 

here is another problem , that the accuracy of the measurement drops 5-10% , using the FINITE measurement.

 

when i was testing with continuous sampling the accuracy of the measurement much better.

i will check again the thread and continuous sampling approach  and separate threads for sampling and saving to the file.

0 Kudos
Message 6 of 7
(3,722 Views)

HI

as u said  icheck for one AO 90kS/s and maximum frequency 3kHz is 300 samples

 

and at the same time i measure the signal at the output of electronic circuit with two channels of AI2-AI3

 

wich sampling rate i need to set  tech spec giving the value of 500kS/s

 

 

0 Kudos
Message 7 of 7
(3,492 Views)