02-21-2006 07:20 PM
02-22-2006 01:21 PM
08-04-2006 06:27 AM
I've looked at the C manual, but it is not really helping. This is what I want to do, and it doesn't seem to work:
With the 6501, I need to put single bit signals out on the ports (about 12 lines), and read one bit in. The bit I am reading in is actually just a continuity check and should just be a readback of one of the output bits. I need to do bitwise addressing, so I wrote functions to read the ports in, do a logical and / or, then write the ports back out.
This is my setup:
char chan0[] = "Dev1/port0";
char chan1[] = "Dev1/port1";
char chan2[] = "Dev1/port2";
DAQmxBaseCreateTask("",&taskHandle);
DAQmxBaseCreateDOChan(taskHandle,chan0,"",DAQmx_Val_ChanForAllLines);
DAQmxBaseCreateDOChan(taskHandle,chan1,"",DAQmx_Val_ChanForAllLines);
DAQmxBaseCreateDIChan(taskHandle,chan2,"",DAQmx_Val_ChanForAllLines);
These are my read / write functions (they are bit funny since I use them at a higher level to do bitwise reads / writes):
int write_dio(unsigned char port0_data, unsigned char port1_data, unsigned char port2_data)
{
int32 written;
int32 return_val;
unsigned char port_data[3];
port_data[0] = port0_data;
port_data[1] = port1_data;
port_data[2] = port2_data;
return_val = DAQmxBaseWriteDigitalU8(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,port_data,&written,NULL);
return return_val;
}
int read_dio(unsigned char *port0_data,unsigned char *port1_data,unsigned char *port2_data)
{
int32 read;
int32 return_val;
unsigned char port_data[3];
return_val = DAQmxBaseReadDigitalU8(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,port_data,3,&read,NULL);
*port0_data = port_data[0];
*port1_data = port_data[1];
*port2_data = port_data[2];
return return_val;
}
I really don't understand how channels are written / read when there is no channel parameter in the read / write functions. If possible, I'd like to set each line to be a channel, and then just write each one individually, but it looks like I have to write at least 8 bits at a time since the function writes to 8 bit ports.
I have not used any LabView stuff before, and am doing this only in C (on Linux), so maybe my unfamiliarity with LabView is an issue. Also, is there a better primer for the C interface than just the API reference? It really doesn't help much with concepts, like tasks. Can't I just address the pins directly for reading and writing without setting up tasks?
Thanks,
David
08-07-2006 12:30 PM - edited 08-07-2006 12:30 PM
I have taken a look at your code below, and I have a couple
comments. First, you are creating tasks
for port0, 1 and 2 on your USB-6501.
This means that each task will have 8 lines you are writing to. When you
create a task you are given a handle to that task. When you want to perform a read or write to a
specific port you need to send the DAQmxBaseWriteDigitalU8 or the
DAQmxBaseReadDigitalU8 the taskhandle you created before. The task handle is how you reference the
channels, since you added the channels to that task.
In your case it seems that you are read and write tasks are separate,
so you might want to create two or three tasks (one for reading and one/two for
writing data).
You also mentioned that you wish to read and write to a single bit. In DAQmx and DAQmx base these bits are called lines. You can specify a single line when you create your DO or DI channel by adding some extra information to your channel string. For example below you specify char chan0[] = "Dev1/port0"; instead you could use char chan0[] = "Dev1/port0/line0"; or chan0[] = "Dev1/port0/line0:1" for lines 0 and 1.
This information is given in the manual. If you look under the DAQmxCreateDOChan help under the lines parameter you will see the following description: "The names of the digital lines used to create a virtual channel. You can specify a list or range of lines such as the following: Dev1/port0:1 or Dev1/port0,Dev1/port2 or Dev1/port0/line0:4 "
The help file, along with the examples that ship with daqmxbase are the best resource for information. The examples are typically located under /usr/local/natinst/nidaqmxbase/examples/
Regards,
Jesse O.
Applications Engineering
National Instruments
Message Edited by Jesse O on 08-07-2006 12:30 PM
08-13-2006 01:43 AM
08-14-2006 03:04 PM
Hello Sileas,
I'm sorry you have been having problems setting up your application.
Unfortunately I need to clarify something from my last post. Although you
can create a channel for Dev1/port1/line0:3 for the 6008/9 and 6501 you need to
use port operations in DAQmx Base. Therefore when you create a channel
for dev1/port1 you send an 8bit (or 32) value to the device. Each of the
least significant 8 bits corresponds to one line. Therefore to send a
value to port1/line0 you would send a 0 or 1. To send a value to
port1/line3 you would send 0 or 4. To set port1/line0, port1/line1, and
port1/line2 all to high you would send 7 to the channel.
So the easiest way to control two output ports and one input port is to create
three tasks.
For example if you had the following code:
uInt32 w_data [1];
int32 written;
w_data[0] = 0x07;
DAQmxErrChk (DAQmxBaseCreateTask ("", &taskHandle));
DAQmxErrChk
(DAQmxBaseCreateDOChan(taskHandle,"Dev1/port1","",DAQmx_Val_ChanForAllLines));
DAQmxErrChk (DAQmxBaseWriteDigitalU32(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,w_data,&written,NULL));
You would write to update all 8 lines of port1. Lines 0, 1 and 2 would be
high and the rest would be low. Unfortunately, since you are limited
to port operations when you update port0/line0 you could change
port0/line1. To get around this you will want to keep the last value you
wrote in memory and only change the bit you need to update on the device.
However if you create two tasks for your digital output, when you update task 1 it
will not change the digital lines associated with task 2.
With regards to your sample pre channel question, the samples per channel you
will specify a value of 1. The value you write will stay on the port until
you update the port.
The same logic applies for
digital input, where each line corresponds to a single bit in the returned
number.
I again apologize for any confusion you have. The documentation available
is the function reference you have already seen, shipping examples, discussion
forums, and possibly more online examples (found here). If
I did not answer your questions completely please let me know. I will try
to answer you the best I can.
Regards,
Jesse O.
Applications Engineering
National Instruments
08-14-2006 10:07 PM
Thanks for the additional help. I finally gave up this weekend and just created a task per line, 16 Out and 8 In. That seems to work, except I am having issues through NIDAQmxBase 1.5 C API configuring pins to Push-Pull (but that is on a different thread right now http://forums.ni.com/ni/board/message?board.id=70&message.id=5339)
Thanks.
08-04-2016 03:54 PM
Hi,
I'm starting writing code (in C) for the NI USB-6501 and it seems like I'm facing the same issue where writing to lines on one port will affect lines on another port. I'm probably doing something wrong...
For example, what I am trying to acheive is simple: I want to either set the 0 first bits of port0 or the 3 first bits of port1. So for example, at one point my code will set the port0 lines to 00000010, then a bit later set the port1 lines to 00000001 (but I want to keep port0 as-is).
So when I write the 3 first bits of port 0, all good, the bits are set correctly.
But then when I write the 3 first bits of port 1, the 3 first bits of port 1 are set correctly ** but the 3 first bits of port 0 are also affected and they all change to 1's?! **
Is this normal?
My code looks like this:
void set_start(uInt8 bits)
{
// Task parameters
int32 error = 0;
TaskHandle taskHandle = 0;
char errBuff[2048];
// Channel parameters
char chan[64];
// Write parameters
uInt8 w_data [1];
int32 written;
sprintf(chan, "Dev1/port%i/line0:3", 0);
printf("Channel: %s\n", chan);
// Create Digital Output (DO) Task and Channel
error = DAQmxBaseCreateTask ("", &taskHandle);
handle_DAQ_error(error, taskHandle);
printf("TaskHandle: %i\n", taskHandle);
error = DAQmxBaseCreateDOChan(taskHandle,chan,"",DAQmx_Val_ChanForAllLines);
handle_DAQ_error(error, taskHandle);
error = DAQmxBaseStartTask (taskHandle);
handle_DAQ_error(error, taskHandle);
w_data[0] = bits;
error = DAQmxBaseWriteDigitalU8(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,w_data,&written,NULL);
handle_DAQ_error(error, taskHandle);
if (taskHandle != 0)
{
DAQmxBaseStopTask (taskHandle);
DAQmxBaseClearTask (taskHandle);
}
return;
}
void set_stop(uInt8 bits)
{
// Task parameters
int32 error = 0;
TaskHandle taskHandle = 0;
char errBuff[2048];
// Channel parameters
char chan[64];
// Write parameters
uInt8 w_data [1];
int32 written;
sprintf(chan, "Dev1/port%i/line0:3", 1);
printf("Channel: %s\n", chan);
// Create Digital Output (DO) Task and Channel
error = DAQmxBaseCreateTask ("", &taskHandle);
handle_DAQ_error(error, taskHandle);
printf("TaskHandle: %i\n", taskHandle);
error = DAQmxBaseCreateDOChan(taskHandle,chan,"",DAQmx_Val_ChanForAllLines);
handle_DAQ_error(error, taskHandle);
error = DAQmxBaseStartTask (taskHandle);
handle_DAQ_error(error, taskHandle);
w_data[0] = bits;
error = DAQmxBaseWriteDigitalU8(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,w_data,&written,NULL);
handle_DAQ_error(error, taskHandle);
if (taskHandle != 0)
{
DAQmxBaseStopTask (taskHandle);
DAQmxBaseClearTask (taskHandle);
}
return;
}