Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

cancel DAQmxExportSignal ?

Is there any way, other than DAQmxResetDevice, to "cancel" a DAQmxExportSignal?

Here's some code that demonstrates my problem:

xxxxxxxxxxxx
#include <stdio.h>
#include <NIDAQmx.h>

#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else

int main(int argc, char **argv)
{
  TaskHandle taskHandle;
  char       errBuff[2048]={'\0'};
  int32      error=0;

  DAQmxErrChk(DAQmxResetDevice("dev1"));

  printf("1 Press Enter to emit a 500ms pulse on both /dev1/pfi12 (ctr0) and /dev1/pfi1\n");
  getchar();
  DAQmxErrChk(DAQmxCreateTask("",&taskHandle));
  DAQmxErrChk(DAQmxCreateCOPulseChanTime(taskHandle, "/dev1/ctr0", "",
                                         DAQmx_Val_Seconds, DAQmx_Val_Low, 0.001, 0.001, 0.50));
  DAQmxErrChk(DAQmxExportSignal(taskHandle, DAQmx_Val_CounterOutputEvent, "/dev1/pfi1"));
  DAQmxErrChk(DAQmxStartTask(taskHandle));
  DAQmxErrChk(DAQmxWaitUntilTaskDone(taskHandle,10.0));

  /* My problem: I'd like to emit the pulse on /dev1/pfi12 and
     /dev1/pfi2 and not on /dev1/pfi1. (Actually, I'd like to emit it
     only on /dev1/pfi2, but I can live with both /dev1/pfi12 and
     /dev/pfi2).

     I know that if I invoke DAQmxResetDevice("/dev1") here I'll get the
     behaviour I want. But my ultimate application will have other tasks
     running, and resetting the device will disrupt those other tasks,
     so I'm looking for another way ... */

  printf("2 Press Enter to emit a 500ms pulse on /dev1/pfi12, /dev1/pfi1, and /dev1/pfi2\n");
  getchar();
  DAQmxErrChk(DAQmxClearTask(taskHandle));
  DAQmxErrChk(DAQmxCreateTask("",&taskHandle));
  DAQmxErrChk(DAQmxCreateCOPulseChanTime(taskHandle, "/dev1/ctr0", "",
                                         DAQmx_Val_Seconds, DAQmx_Val_Low, 0.001, 0.001, 0.50));
  DAQmxErrChk(DAQmxExportSignal(taskHandle, DAQmx_Val_CounterOutputEvent, "/dev1/pfi2"));
  DAQmxErrChk(DAQmxStartTask(taskHandle));
  DAQmxErrChk(DAQmxWaitUntilTaskDone(taskHandle,10.0));

 Error:
  if (DAQmxFailed(error)) {
    DAQmxGetExtendedErrorInfo(errBuff,2048);
    printf("Error: %s\n", errBuff);
  }
  DAQmxStopTask(taskHandle);
  DAQmxClearTask(taskHandle);
}

0 Kudos
Message 1 of 5
(3,331 Views)
Clearing the task "cancels" a signal routed with DAQmxExportSignal from the perspective that the hardware resources required to make that route are released. However, for some terminals, including PFI terminals, the tristate buffer associated with the terminal is not disabled when the task is cleared. This is done to minimize glitches. If you want, you can explicitly disable the tristate buffer by calling: DAQmxExportSignal(taskHandle, DAQmx_Val_CounterOutputEvent, "").

For more information on task-based routes, refer to "Task-Based Routing" and "Lazy Line Transitions" in the NI-DAQmx C Reference Help.

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 2 of 5
(3,322 Views)
I tried inserting the suggested
        DAQmxExportSignal(taskHandle, DAQmx_Val_CounterOutputEvent, "");
call at various places without success. Depending on where I place it I either get a run-time error, I only see the second pulse
(the one that should only appear on ctr0 or pfi1) on ctr0, or I continue to see the third pulse emitted on all three terminals.

Where, exactly, should I place this call?

I'm experimenting with DAQmxTristateOuputTerm() and it looks like this might be a solution.

I'm using an NI6224 PCI card, if that clue helps.

0 Kudos
Message 3 of 5
(3,305 Views)
I would place the call immediately before clearing the task. If that doesn't work, you may need to explicitly transition the task to the unreserved state. This can be done by invoking DAQmxTaskControl(taskHandle, DAQmx_Val_Task_Unreserve).

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 4 of 5
(3,293 Views)
I haven't had success using either DAQmxExportSignal(taskHandle, DAQmx_Val_CounterOutputEvent, "") or DAQmxTaskControl(taskHandle, DAQmx_Val_Task_Unreserve).  Perhaps a short program that demonstrates their use would be helpful.

DAQmxTristateOuputTerm() appears to solve my problem (but I'm still conducting tests). If I insert the following lines after the topmost DAQmxErrChk(DAQmxWaitUntilTaskDone(taskHandle,10.0)) in the program at the top of this thread:

     DAQmxErrChk(DAQmxStopTask(taskHandle));
     DAQmxTristateOutputTerm("/dev1/pfi1"));

then I see the second pulse on /dev1/pfi2 and not on /dev1/pfi1.

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