From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

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,528 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,508 Views)