Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

synchronized ai-ao problem

Hi All,
I am writing a portion of code with LabWindows CVI 8.1 and NI-DAQ 8.3.0, using a PCI-6259 multifunction card.
I have slightly adjusted a synchronized ai-ao example found on the NI website. I am using an external serial dac to provide the card a voltage reference for AO0. I can correctly set the AO0 voltage but as soon as I assign the ramp array to the simultaneous ai-ao task, the AO0 output suddenly moves to a different value.
To be more exhaustive, I attach here a code snippet showing where the problem arises. Can anybody suggest a fix ?
Thanks in advance,
Marco
 
 

// code snippet showing the improper DAC setting after executing DAQmxWriteAnalogF64() below

....
 
// I preset dac on AO0 to -9.51 V
SetDacTo(-9.51);
// now I want a ramp ranging from -9.51V to 9.51V
ramp_X_voltage = 9.51;
  
// I use a proprietary serial DAC to fix the NI-dac reference voltage externally
SetVrefDacOutput(ramp_X_voltage);  
// create the simultaneous input and output task
CreateSimultaneousAIAOTasks(&AIAO_AnalogInput_Task, &AIAO_AnalogOutput_Task, AIsamplerate, 2 * rowresolution, -10.0, 10.0, -10.0, 10.0, AOsamplerate, 2 * numberoframpstep, ramp_X_voltage); 
// fill the ramp buffer
Ramp (numberoframpstep, -ramp_X_voltage, ramp_X_voltage, &rampa[0]);
Ramp (numberoframpstep, ramp_X_voltage, -ramp_X_voltage, &rampa[numberoframpstep]); 
// ...and assign it to the task  
DAQmxWriteAnalogF64(AIAO_AnalogOutput_Task, 2 * numberoframpstep, 0, 10.0, DAQmx_Val_GroupByChannel, rampa, &written, NULL);
 
// Yep, here a voltmeter connected to AO0 suddenly moves from -9.51 to about -9.2 !
 
....    
 

 
// here are the main functions invoked above:
 
void SetDacTo(double offsetx) 
{
 char dpl[40]; 
 TaskHandle FastScanDacTask = 0; 
 
 Fmt(dpl, "%s<%s%d%s", "Dev", NIDevice, "/ao0");
 CreateAO_VWriteTask(&FastScanDacTask, dpl, "FastScanDac", -10.0, 10.0);
 
 DAQmxWriteAnalogScalarF64 (FastScanDacTask, 1, 10.0, offsetx, 0); 
 
 if (FastScanDacTask != 0)  { DAQmxStopTask(FastScanDacTask); DAQmxClearTask(FastScanDacTask); } 
}
 

int32 CreateSimultaneousAIAOTasks(TaskHandle *taskHandleIn1, TaskHandle *taskHandleOut1, float64 rateIn, uInt64 sampsPerChanIn, float64 minAIVal, float64 maxAIVal, float64 minAOVal, float64 maxAOVal, float64 rateOut, uInt64 bufferSize, float64 refValue) 
{
 int chanNum, i;
 char dpl[40];
 char dpn[40];
 TaskHandle taskHandleIn;
 TaskHandle taskHandleOut;
 
 
 DAQmxCreateTask("",&taskHandleIn);
 GetNumListItems (hMainPanel, PANEL_MAINCHANNEL, &numOfChannelsInTheTask);
 for (i = 0; i < numOfChannelsInTheTask; i++)
 {
  GetValueFromIndex (hMainPanel, PANEL_MAINCHANNEL, i, &chanNum);
  Fmt(dpl, "%s<%s%d%s%d", "Dev", NIDevice, "/ai", chanNum);   
  Fmt(dpn, "%s<%s%d", "AICH", chanNum);
  DAQmxCreateAIVoltageChan(taskHandleIn, dpl, dpn, DAQmx_Val_Diff, minAIVal, maxAIVal, DAQmx_Val_Volts, "");
 }
 DAQmxCfgSampClkTiming(taskHandleIn, "", rateIn, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, sampsPerChanIn);
       
 
 DAQmxCreateTask("",&taskHandleOut);
 Fmt(dpl, "%s<%s%d%s%d", "Dev", NIDevice, "/ao", fastScanDac);
 DAQmxCreateAOVoltageChan(taskHandleOut, dpl, "", minAOVal, maxAOVal, DAQmx_Val_Volts, NULL);
 
 Fmt(dpn, "%s<%s%d%s", "/Dev", NIDevice, "/APFI0"); 
 // Specify and external reference, which connector pin to input it, and the value it will be.
 DAQmxSetChanAttribute (taskHandleOut, dpl, DAQmx_AO_DAC_Ref_Src, DAQmx_Val_External);
 DAQmxSetChanAttribute (taskHandleOut, dpl, DAQmx_AO_DAC_Ref_ExtSrc, dpn);
 DAQmxSetChanAttribute (taskHandleOut, dpl, DAQmx_AO_DAC_Ref_Val, refValue);
 if (niCardType == PCI6289) DAQmxSetChanAttribute (taskHandleOut, dpl, DAQmx_AO_DAC_Offset_Val, 0.0);
 
 DAQmxCfgSampClkTiming(taskHandleOut, "", rateOut, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, bufferSize);
 
 // The output task uses the input task's start trigger.  This causes the tasks to start at
 // exactly the same time in hardware.
 Fmt(dpl, "%s<%s%d%s", "/Dev", NIDevice, "/ai/SampleClock"); 
 DAQmxCfgDigEdgeStartTrig (taskHandleOut, dpl, DAQmx_Val_Rising);
 
 *taskHandleIn1 = taskHandleIn;
 *taskHandleOut1 = taskHandleOut;
 
 return 0;
}

 
 
0 Kudos
Message 1 of 5
(3,759 Views)

Hello ElbaTech,

have you tried different values for the variable refValue? If so, the difference between the measured and the expected value remains the same?  Also, if you don't set any external reference value, the AO returns the expected value? It's better to exclude any hardware problem before working on the code, which it seems to be correct.

Best regards,

Fabio

Fabio M.
NI
Principal Engineer
0 Kudos
Message 2 of 5
(3,736 Views)
Hello Fabio,
sorry for the delayed reply due to the need to perform the required experiments. I cannot avoid using an external reference because my application needs to maximize the resolution setting the precise output range. I have done the following tests:
if RefValue = 6.66 and AO0 was -3.3 it jumps to -1.11
if RefValue = 5.00 and AO0 was -3.3 it jumps to -0.85
if RefValue = 3.33 and AO0 was -3.3 it jumps to -1.13
if RefValue = 1.66 and AO0 was -3.3 it jumps to -1.95
So a non linear behaviour, strange... Then I preset AO0 to the double = -6.6, and found similar results, where the deltaAO0 is exactly the same as in the above data:
if RefValue = 6.66 and AO0 was -6.6 it jumps to -4.38
if RefValue = 5.00 and AO0 was -6.6 it jumps to -4.17
if RefValue = 3.33 and AO0 was -6.6 it jumps to -4.45
if RefValue = 1.66 and AO0 was -6.6 it jumps to -5.28
Thanks for any advice !
Marco



0 Kudos
Message 3 of 5
(3,715 Views)
Hello, for the benefit of other NI users, here I am to explain how I fixed the problem myself.
First of all, I have demonstrated that the analog output discrepancy is real and not due to any hardware error in my circuits.
Second, I have found that it only appears if, before configuring and starting a waveform generation, the program fixes the analog output to a value by means of a separated task.
By the way, it seems reasonable that one wants to slowly preset the dac output to the first value of the future waveform, thus avoiding abrupt changes in the output voltage. For example, before outputting a ±3V amplitude waveform, one could move the dac output from the actual value to -3V in several steps, then start the waveform generation.
Well, in this case, the future use of an external reference voltage somehow conflicts with the hardware and yields to the output errors reported in the previous posts.

The fix was found to be the precise positioning of the code lines which refer to the external reference, originally interposed between the task creation and the writing of the allocated buffer. This is the wrong sequence:

1) write an analog scalar to the dac by separate task
2) create waveform output task
3) create output channel
4) define clock timing
5) set the reference source as external
6) set the reference value
7) write buffer (i.e. DAQmxWriteAnalogF64(taskHandle,bufferSize,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL); )
8) start  waveform output task

This is the correct sequence:

1) write an analog scalar to the dac by separate task
2) create waveform output task
3) create output channel
4) define clock timing
5) write buffer (i.e. DAQmxWriteAnalogF64(taskHandle,bufferSize,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL); )
6) set the reference source as external
7) set the reference value
8) start  waveform output task

In this way, the problem pointed out in my previous posts does not appear any longer.
Hope this helps other users,
good luck,
Marco




0 Kudos
Message 4 of 5
(3,686 Views)
Hello again,
things are never easy, my previous post with the auto-answer is uncorrect, sorry !
I got the help of NI people and they have found that the problem arises because the single fixed point writing occurs before setting the reference voltage. When the waveform generation is programmed, this reference is also set thus yielding to a temporary rescaling of the output.
The suggested fix is to embed in one single task both the fixed point and the waveform generation, thus fixing the reference voltage before any output change, either single point or multipoint. This way everything works fine.
Regards,
Marco


0 Kudos
Message 5 of 5
(3,614 Views)