05-16-2017 07:59 AM
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.
Solved! Go to Solution.
05-24-2017 04:25 AM
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); } }
05-26-2017 01:45 PM
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.
05-28-2017 01:30 AM - edited 05-28-2017 01:54 AM
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.
05-30-2017 12:35 PM
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.
06-07-2017 02:57 AM
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.
07-27-2017 02:58 AM
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