Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Smoothly change analog output on a PXI device via C

Hello,

 

I'm trying to use the analog outputs on a PXI-4461 to drive a fast steering mirror.  I need to set each AO channel to some DC values, wait a short period of time for the mirror to settle, and then measure something.  I can use the AO channels to output the values using this code:

 

void PxiMirrorAxes::set_dc(double valX, double valY)
{
    int i;
    for (i=0;i<buffer_size/2;i++) // Write a bunch of the same value to a small buffer
    {
        buffer[i]=valX;
        buffer[i+buffer_size/2]=valY;
    }
    if (taskHandle) {  // If a task is currently running stop it
        DAQmxStopTask(taskHandle);
        DAQmxClearTask(taskHandle);
        taskHandle = 0;
    }
    int err;
    err= DAQmxCreateTask("",&taskHandle);
    err = DAQmxCreateAOVoltageChan (taskHandle, chan_char_x, "", -10.0, 10.0, DAQmx_Val_Volts , NULL);
    err = DAQmxCreateAOVoltageChan (taskHandle, chan_char_y, "", -10.0, 10.0, DAQmx_Val_Volts , NULL);
    err = DAQmxCfgSampClkTiming(taskHandle,"",sampling_rate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,buffer_size/2);

    int32 written;
    err = DAQmxWriteAnalogF64(taskHandle,buffer_size/2,0,10.0,DAQmx_Val_GroupByChannel,buffer,&written,NULL);
    err = DAQmxStartTask(taskHandle); // Task is left running
}

 This works fine to go to a specific pair of values and stay there -- however I can't call this in a loop to scan the mirror because every time I call it, the value of the outputs briefly drops to zero, presumably when I call the DAQmxStopTask.  How do I change the output values of the two channels without them going to zero at all?  (Note that when I use code like the above with a normal PCI-based DAQ where I don't have to write a buffer, it never goes to zero between calls).  Thanks,

 

Alex

0 Kudos
Message 1 of 2
(3,053 Views)

Just to follow up, I was able to do this by calling the following code once at the start of the loop:

 

void PxiMirrorAxes::prep_sweep()
{
    if (taskHandle) {  // If a task is currently running stop it
        DAQmxStopTask(taskHandle);
        DAQmxClearTask(taskHandle);
        taskHandle = 0;
    }

    int err= DAQmxCreateTask("",&taskHandle);
    err = DAQmxCreateAOVoltageChan (taskHandle, chan_char_x, "", -10.0, 10.0, DAQmx_Val_Volts , NULL);
    err = DAQmxCreateAOVoltageChan (taskHandle, chan_char_y, "", -10.0, 10.0, DAQmx_Val_Volts , NULL);
    err = DAQmxCfgSampClkTiming(taskHandle,"",sampling_rate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,buffer_size/2);

    int i;
    for (i=0;i<buffer_size/2;i++)
    {
        buffer[i]=0;
        buffer[i+buffer_size/2]=0;
    }
    int32 written;
    err = DAQmxWriteAnalogF64(taskHandle,buffer_size/2,0,10.0,DAQmx_Val_GroupByChannel,buffer,&written,NULL);
    err = DAQmxStartTask(taskHandle);
    i=1;
}

 and then calling the following every time I wanted to change the value:

 

void PxiMirrorAxes::sweep_set(double valX, double valY)
{
    int i;
    for (i=0;i<buffer_size/2;i++)
    {
        buffer[i]=valX;
        buffer[i+buffer_size/2]=valY;
    }
    int32 written;
    int err = DAQmxWriteAnalogF64(taskHandle,buffer_size/2,0,10.0,DAQmx_Val_GroupByChannel,buffer,&written,NULL);

    now_x = valX;
    now_y=valY;
}

 

Each subsequent DAQmxWriteAnalogF64 call returns the warning 200015: DAQmxWarningPotentialGlitchDuringWrite (discussed here), but since that describes what I want to happen anyways, I'm just ignoring it. 

0 Kudos
Message 2 of 2
(3,033 Views)