11-03-2011 12:38 AM
I have a setup that uses:
USB-6009
NI-DAQmx Base on Mac OS
Is it possible to *query* the current states of the digital outputs? Whenever I try to read back the DIO states, it seems to reset the outputs.
- Am I doing something wrong?
- Or is this a limitation in NI-DAQmx Base and/or the USB-6009?
Alternatively, is there a way (again using the same hardware setup) to set up a DO task to connect to a single DIO line and update that single DIO line without perturbing the others? I've tried this too without success, it seems like I can only talk to the 8-bit DIO port as a whole.
11-03-2011 04:02 PM
Hi pwr,
When you create the DO task, you should be able to create a control for the input that specifies which lines that task uses. When you create your task, are you able to select the individual lines? Or, do you only have the option of selecting them all?
Best regards,
11-03-2011 04:32 PM
> When you create the DO task, you should be able to create a control for the input that specifies which lines that task uses.
I'm currently using all of the 8 DIO lines as outputs, like this:
DAQmxBaseCreateDOChan(task, "Dev1/port0", "", DAQmx_Val_ChanForAllLines)
> When you create your task, are you able to select the individual lines? Or, do you only have the option of selecting them all?
You tell me... All I know how to do from the NI-DAQmx Base example code is to use all lines at once as shown in the code above.
What's the syntax (if there is one) for connecting a DO task to a subset of the lines? It would also solve my problem to be able to create a DO task that connects only to a single line within the port (leaving the other lines within the port alone).
11-04-2011 12:04 PM
Hi pwr,
The syntax to use a single digital line would be something like:
DAQmxBaseCreateDOChan(task_name, "Dev0/port0/line0", "name_here", DAQmx_Val_ChanPerLine);
Then, to create a task using a subset of lines, you would repeat this code while changing the line number and "name_here" field.
Best regards,
11-04-2011 01:29 PM
I'll try that.
FYI "DAQmx_Val_ChanPerLine" is not mentioned in the DAQmxBaseCreateDOChan() page in the documentation that was installed along with DAQmx Base 3.4.5:
lineGrouping int32 Always pass DAQmx_Val_ChanForAllLines
Value Description
DAQmx_Val_ChanForAllLines One channel for all lines
11-04-2011 04:15 PM
No success in using "port0/line0" to access a single line on the port. I've attached a testcase that illustrates the problem.
test_0() cycles through some patterns on 2 DO bits, writing the entire port at a time. This behaves as expected.
test_1() attempts to do the same thing, using 2 tasks to control 2 individual lines of the port. I don't get the expected behavior (see code for details).
FWIW my setup is:
MacOSX SnowLeopard, 32-bit
DAQmxBase 3.4.5
USB-6009
What am I doing wrong?
Here's the code. I'd attach the file separately but the forum software won't let me; I get the error "The attachment's content type (application/octet-stream) does not match its file extension)."
// dio-test.c
//
// Testcase trying to debug issues with DIO
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "NIDAQmxBase.h"
#define DAQ_CHECK(s) daq_check(s,__FILE__,__LINE__)
void daq_check(int32 status, const char *file_name, int line_num)
{
if (DAQmxFailed(status)) {
char err_buf[1024];
DAQmxBaseGetExtendedErrorInfo(err_buf, sizeof(err_buf));
fprintf(stderr,"error: %s\n",err_buf);
exit(1);
}
}
void do_set(TaskHandle t, int value)
{
DAQ_CHECK(DAQmxBaseWriteDigitalScalarU32(t, FALSE, 10, (uInt32) value, NULL));
}
void test_0()
{
TaskHandle task_a;
printf("begin test_0\n");
// Create a task to talk to entire DIO port
DAQ_CHECK(DAQmxBaseCreateTask("",&task_a));
DAQ_CHECK(DAQmxBaseCreateDOChan(task_a, "Dev1/port0", "", DAQmx_Val_ChanForAllLines));
// Start task
DAQ_CHECK(DAQmxBaseStartTask(task_a));
// Try setting DO states
printf("line[0] -> 1\n");
do_set(task_a,1);
sleep(10);
printf("line[2] -> 1\n");
do_set(task_a,5);
sleep(10);
printf("line[0] -> 0\n");
do_set(task_a,4);
sleep(10);
printf("line[2] -> 0\n");
do_set(task_a,0);
sleep(10);
printf("line[0] -> 1\n");
do_set(task_a,1);
sleep(10);
printf("line[2] -> 1\n");
do_set(task_a,5);
sleep(10);
printf("line[0] -> 0\n");
do_set(task_a,4);
sleep(10);
printf("line[2] -> 0\n");
do_set(task_a,0);
sleep(10);
// Done, stop and clear tasks
DAQ_CHECK(DAQmxBaseStopTask(task_a));
DAQ_CHECK(DAQmxBaseClearTask(task_a));
printf("end test_0\n");
}
void test_1()
{
TaskHandle task_a, task_b;
printf("begin test_1\n");
// Create a task to talk to one DO line
DAQ_CHECK(DAQmxBaseCreateTask("",&task_a));
DAQ_CHECK(DAQmxBaseCreateDOChan(task_a, "Dev1/port0/line0", "", DAQmx_Val_ChanPerLine));
// Create a second task to talk to a second DO line
DAQ_CHECK(DAQmxBaseCreateTask("",&task_b));
DAQ_CHECK(DAQmxBaseCreateDOChan(task_b, "Dev1/port0/line2", "", DAQmx_Val_ChanPerLine));
// Start tasks
DAQ_CHECK(DAQmxBaseStartTask(task_a));
DAQ_CHECK(DAQmxBaseStartTask(task_b));
// Try setting DO states
printf("line[0] -> 1\n");
do_set(task_a,1);
sleep(10);
printf("line[2] -> 1\n");
do_set(task_b,1);
sleep(10);
printf("line[0] -> 0\n");
do_set(task_a,0);
sleep(10);
printf("line[2] -> 0\n");
do_set(task_b,0);
sleep(10);
printf("line[0] -> 1\n");
do_set(task_a,1);
sleep(10);
printf("line[2] -> 1\n");
do_set(task_b,1);
sleep(10);
printf("line[0] -> 0\n");
do_set(task_a,0);
sleep(10);
printf("line[2] -> 0\n");
do_set(task_b,0);
sleep(10);
// Done, stop and clear tasks
DAQ_CHECK(DAQmxBaseStopTask(task_a));
DAQ_CHECK(DAQmxBaseStopTask(task_b));
DAQ_CHECK(DAQmxBaseClearTask(task_a));
DAQ_CHECK(DAQmxBaseClearTask(task_b));
printf("end test_1\n");
}
int main()
{
// Things work as expected when a single task controls
// the entire USB-6009 DIO port.
// Get expected pattern on {line[2], line[0]}:
// 01 -> 11 -> 10 -> 00 -> 01 -> 11 -> 10 -> 00
test_0();
// Expect this to do the same thing, using 2 tasks to
// control 2 individual lines in the port.
// !!! Doesn't work. !!!
// Get the following pattern on {line[2], line[0]}
// 01 -> 00 -> 00 -> 00 -> 01 -> 00 -> 00 -> 00
test_1();
return 0;
}