Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Need help with digital output on NI USB-6501 (why does writing bits on one port affect bits on another port?)

Hi,

I'm starting writing code (in C) for the NI USB-6501 and it seems like I'm facing a situation where writing to lines on one port will affect lines on another port.  I'm probably doing something wrong or there is some fundamental channel/port/task concept I don't understand...  I tried searching the forums for an explaination but with no success.

 

Details:

 

What I am trying to acheive is simple: I want to either set the 3 first bits of port0 or the 3 first bits of port1.  When I set the bits on one of the ports, I want the bits on the other port to stay the same.  So for example, at one point my application will get executed to set the port0 lines to 00000000, then a bit later my application is executed again but this time to 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 on port 0 are set correctly (they are all low).

 

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 (it does not return any errors so I removed the error handling code for clarity):

 

void write_to_port_0(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);
printf("TaskHandle: %i\n", taskHandle);

error = DAQmxBaseCreateDOChan(taskHandle,chan,"",DAQmx_Val_ChanForAllLines);
error = DAQmxBaseStartTask (taskHandle);
w_data[0] = bits;

error = DAQmxBaseWriteDigitalU8(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,w_data,&written,NULL);
if (taskHandle != 0)
{
DAQmxBaseStopTask (taskHandle);
DAQmxBaseClearTask (taskHandle);
}

return;
}

 

void write_to_port_1(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);
printf("TaskHandle: %i\n", taskHandle);

error = DAQmxBaseCreateDOChan(taskHandle,chan,"",DAQmx_Val_ChanForAllLines);
error = DAQmxBaseStartTask (taskHandle);
w_data[0] = bits;

error = DAQmxBaseWriteDigitalU8(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,w_data,&written,NULL);
if (taskHandle != 0)
{
DAQmxBaseStopTask (taskHandle);
DAQmxBaseClearTask (taskHandle);
}

return;
}

 

 

Anyone else had this issue before?

 

Thanks,

  Andre

0 Kudos
Message 1 of 3
(3,420 Views)

Perhaps you can try to implement procedure called "Read-Modify-Write".

What it involves is entirely in the name. You read. Then you modify. Then you write.

Read:

//Read in the value of the output register
tempVariable = [output register]

Modify:

//set all bits you want to modify to be 0.
tempVariable &= [some mask];
//or in the values of the bits with those bits you want unchanged set to 0
tempVariable |= [new value of bits];

Write:

//Write the new value back to the output register
[output register] = tempVariable;

The key is basically to end up with the values of bits you want to be unchanged to be written back to the output register along with the new values of bits you do want to change.

 

 

We can't just write to the register directly because it will affect the bits we don't want to change as well. So we need a sequence of operations that will change only the bits we want to.

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

Am I misunderstanding your code? It looks although you start a task, set the I/O lines to the state you want, then stop and clear the task.  I always assumed that the state of all and any I/O accessed through DAQmx is only defined while there is a corresponding task in the started state. Stopping and clearing the task is as good as saying that DAQmx should set the lines to their default state (input or output) and level (high or low).

 

I suggest starting the tasks at the beginning of your programme, and only stopping & clearing them at the end. Does the behaviour change?

0 Kudos
Message 3 of 3
(3,332 Views)