Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

NI-6501 unexpected DI values

Hi,

I have a rather weird problem when doing something really simple. I 'm just trying to read some values on a DI channel using the DAQmxReadDigitalU8 / DAQmxReadDigitalLines functions. However: the ReadArray always has a non-sense value in the first place of the array!

Here is some sample code i've been using to debug the issue I'm using C for my software:

---------------------------------------------
uInt8 data[8];
int32 read;
int32 result1, result2, result3;
int i;
TaskHandle taskHandlet = 0;
pFile = fopen ("c:\\myfile.txt","w");

result1 = DAQmxCreateTask ("", &taskHandlet);
fprintf(pFile, "result1 %d\n", result1);


result2 = DAQmxCreateDIChan(taskHandlet,"Device1/port0/line0,Device1/port0/line1,Device1/port0/line2,Device1/port0/line3","",DAQmx_Val_ChanForAllLines);
fprintf(pFile, "result2 %d\n", result2);

result3 = DAQmxStartTask (taskHandlet);
fprintf(pFile, "result3 %d\n", result3);

DAQmxReadDigitalU8(taskHandlet,1,10.0,DAQmx_Val_GroupByChannel,data,8,&read,NULL);
 
for (i = 0; i < 8; i++){
fprintf(pFile, "%d\n", data[i]);
}

---------------------------------------------


Here are the facts: 

- the resultcode for the three first functions (create task, create channel, start task) is 0, so that would mean that everything until then is just fine. right ?
- the resultcode for the DAQmxReadDigitalU8 is also 0, meaning that everything went fine as well... I thought.

However, in the example above, the ReadArray ('data' in my example) shows the following values when printing them to a file: {15,0,0,0,0,0,0,0}.

I've tried with a lot of different sample codes, but every time giving me the same weird first value in the first place of the ReadArray. the number varies and makes no sense to me at all.

What am i doing wrong ? Can anyone shed some light on this ?

Thanks in advance for reading this post and your help,

Sander Goossens

0 Kudos
Message 1 of 6
(4,461 Views)

Hello,

 

 

It seems normal that you only get one value in your results array.

 

the function "DAQmxReadDigitalU8(taskHandlet,1,10.0,DAQmx_Val_GroupByChannel,data,8,&read,NULL)" will only read once all lines of the port configured at "DAQmxCreateDIChan" and put that result in a decimal format at the first element of the array.

The result of "15" you get, is actually "0x0F" or in binary "11111111".  So all "1's" at the inputs.

Is this what you also expected?

 

To add a new value in the results array, you should put the  ""DAQmxReadDigitalU8" line within the for loop. That way it will add a value in the next element of the configured array each call of the read function.

To read only the lines you have configured, use the DAQmxReadDigitalLines function.

 

 

If you want to add a measured value each loop to the array, you can only use clocked measurements. That way you have to configure the clock to which the DAQmxReadDigitalLines should synchronize/trigger and you can keep that function out of the loop.
Unfortunately this is not possible with the low-cost USB-6501.

If you want to synchronize your digital measurements with an on board clock, make sure you have a measurement board which can handle the correlated I/O functionality.

 

 

 Hopes this helps to continue your project.

 

 

 

Best regards,
Joeri

National Instruments
Servicesg
0 Kudos
Message 2 of 6
(4,394 Views)

Dear Joeri,

Thanks for your very clear explanation. I see where this could be going.

However, what i don't understand... Here's a snippet of the code that's in the samples that ship with the NI-6501 board:

-------------------------------------------------------------------------------
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev1/port0/line0:7","",DAQmx_Val_ChanForAllLines));

 
DAQmxErrChk (DAQmxStartTask(taskHandle));

 
DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,100,&read,&bytesPerSamp,NULL));

 
for(i=0;i<8;++i)
printf("Data acquired, channel %d: 0x%X\n",i,data[i]);


-------------------------------------------------------------------------------

So my question is... : at the end of the code, a for-loop will show all the values that are read. but i was expecting it to be 0's and 1's ... and thus the output from the DAQmxReadDigitalLines   function that i need !

So basically: what do i need to change in my code to read in ONE time all the values of the lines configured in the DAQmxCreateDIChan function ? because the sample code that ships with the board shows that it is possible .. ? 

Or what am I seeing wrong here ?

Once again thanks for your help,

Regards,

Sander

0 Kudos
Message 3 of 6
(4,347 Views)

Hello,

 

 

First I would like to correct something from my previous response.

 I wrote:

The result of "15" you get, is actually "0x0F" or in binary "11111111".  So all "1's" at the inputs.

 Actually, Hexadecimal 0X0F is still '00001111' in binary.

My excuses.

 

 

 

Secondly I would like to make sure you understand the difference between the NI_DAQmx driver calls and the application itself.

The DAQmxReadDigitalLines functions actually reads the values from the USB-6501 module and put them into the computer memory. 

Based on the array size you specify, the driver will initialize a certain memory allocation for you.

 

Till that moment you haven't read the data into your application yet.

This is done within the for loop where in the example you read the 8 first elements from that array and print the values on the screen.

 

The example by default is printing the values in hexadecimal format (that's the %X in the printf arguments).

If you would like to have it printed in decimal format just use following syntax:

 

for(i=0;i<8;++i) printf("Data acquired, channel %d: %d\n",i,data[i]);

 

 

 This will give me following results (only digital channel 2 was brought to zero when I tested it using a PCMCIA-6024 card).

 

Data acquired, channel 0: 1
Data acquired, channel 1: 1
Data acquired, channel 2: 0
Data acquired, channel 3: 1
Data acquired, channel 4: 1
Data acquired, channel 5: 1
Data acquired, channel 6: 1
Data acquired, channel 7: 1
End of program, press Enter key to quit

 

Is this the way you want to get your results?

 

When using the DAQmxReadDigitalU8 as you did earlier will give the result in one decimal number representing the whole digital port (8 channels).

Actually this method is more efficient as it uses only one byte of data memory to store a value of one digital port measurement.

Unfortunately there is no function to give the results immediately in binary format.

If you would like to convert it into binary format, you will have to add code to your application for the conversion.
Google can help you with this. Many examples and methods exist to convert a decimal value into its binary representation.

 


 

 

 

Best regards,
Joeri

National Instruments
Servicesg
0 Kudos
Message 4 of 6
(4,337 Views)

Dear Joeri,

 

It simes like i justed needed to use the DAQmxReadDigitalLines instead of the DAQmxReadDigitalU8. I seem to get more adequate values now (all 1's with no voltage connected to the Digital Inputs), and that my problem is basically solved!

 

 I've got another, non-programming-related extreme newbie-question:

 

I figured that I could test my code and see if the values (all 1) change when i hook some channels up to one of the 5 volt channels of the board. However, it doesn't affect anything. Is this a correct way of "bringing a channel to zero" as you call it ? Or should i use an external 5 volt source of some sort ? I'm sorry, my electric knowledge is non-existant, i'm writing the software for an electrician (who is currently unavailable, thats why i ask ..)

 

In your example, is channel 2 the only channel that has a voltage connected to it ? Or how should it be interpreted ?

 

Thanks again for your help, it really helped me a lot.

 

Kind regards,

 

Sander

0 Kudos
Message 5 of 6
(4,328 Views)

Hello,

 

 

It's normal that you see all "1's".

Internally the USB-6501 has weak internal pull-up resistors (see manual).
This pull-up resistors hook all channels to the internal 5V reference. 

Hook one or more channels to the DGND and it will bring these channels to "0" .

In my example, it was channel 0.2 which was connected to the DGND of my board.

 

Don't worry about this when you have an external signal.  5V will be "1", GND will be "0".

Have a look at the USB-6501 manual as this shows you the possible connection configuration.

 

 

Just another  thought.

As the decimal and hexadecimal representations of the binary "0" and "1" are just the same, you can look at this as binary representation and use following code to visualize the measured data into one line.

 

// assuming 8 channels acquired
printf ("Data acquired: ");
for(i=0;i<8;++i)
printf("%d",data[i]);

 

Message Edited by Joeri on 07-08-2009 09:02 AM
Best regards,
Joeri

National Instruments
Servicesg
0 Kudos
Message 6 of 6
(4,322 Views)