Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Using DIG_Block_In() to read a 32-bit (4-port) value.

I'm trying to use a PCI-DIO-32HS to read in a 32-bit value from a device that will periodically (~100 times/second) latch a new value in on the falling edge of a pulse. I've modeled my code after the example in the NI example file DIoneGroupHandshake.c. Since I am trying to read in 32 bits, I've expanded my group size to 4. This requires replacing the call to DIG_In_Grp()with a call to DIG_Block_In(), e.g.,

iStatus = DIG_Block_In(iDevice, iGroup, aiBuffer, 1);

The trouble is that this is always returning -10010 (badCountError). Why is this happening? My group has been configured for four ports, so (if I understand correctly) I should be passing in a 1 for the last parameter to DIG_Block_In().

I have
tried configuring the group for 2 ports and using DIG_In_Grp() to read in the first 16 bits of my data (as in the example code), and this seems to work fine. What is the appropriate way to adapt DIoneGroupHandshake.c to read in 32-bit values?

Thanks,
Keith Kingsley
Aeroflex Lintek
0 Kudos
Message 1 of 6
(3,642 Views)
Hello,


Hey Keith, the last parameter of DIG_Block_In is labeled �number of points�, but it is actually the size of the short array that you are passing in. So while you would assume that the input is 1, it should actually be two.

Also, I think using the DIG_Block_In will work for you in this case. However, I have not set this up and tried it. Just let us know if passing an array of size two and a count of two does not work.


Best regards,

Justin T.

Note, you should be able to get by doing the following

u32 piBuffer;

DIG_Block_In(iDevice,iGroup, (i16 *) &piBuffer, 2);
0 Kudos
Message 2 of 6
(3,642 Views)
Justin,

Thanks for your response. I've gotten DIG_Block_In to work for me, passing in 2 as the final argument.

Previously I was using DIG_Grp_Status to see if the data had been latched; for some reason this was never indicating that any data had been latched. Now I'm using DIG_Block_Check to see how many items are remaining to be transferred via my last call to DIG_Block_In. If the remaining # of items is less than 2, I know that some data has been transferred to my buffer. This approach seems to work well.

So it looks like there were two things I needed to do: 1) use 2 as the final argument of DIG_Block_In, and 2) use DIG_Grp_Status to check for progress of the transfer. I also didn't realize that DIG_Block_In is asynchronous until I look
ed at the documentation more closely.

Incidentally, it looks like the final argument to DIG_Block_In indeed represents the number of "items" to be transferred-- not necessarily the number of short ints. In other words, if I've configured my group for four ports and I call DIG_Block_In with 2 as the final argument, eventually 8 bytes will be transferred to my buffer.

One thing I'm still not clear on: if I make a call to DIG_Block_In and then wait several seconds (say, thousands of triggers from my device) and call DIG_Block_Check followed by another call to DIG_Block_In, is the second call to DIG_Block_In guaranteed to get "fresh" data? In other words, does DIG_Block_In wait for future triggers, or does the NI software buffer data up somehow? I suspect that DIG_Block_In waits for future triggers in my simple configuration, but I just wanted to confirm.

Thanks again,
Keith
0 Kudos
Message 3 of 6
(3,642 Views)
Hi Keith,

I don't quite understand what you mean by making a second DIG_Block_In call after the DIG_Block_Check call. The DIG_Block_Check won't interfere with the execution of the initial DIG_Block_In call. The DIG_Block_In will run until it reads in the specified count of items to read. DIG_Block_Check verifies how many items the DIG_Block_In has left to read, but it doesn't stop the DIG_Block_In. Calling a second DIG_Block_In before clearing the first DIG_Block_In call will most likely result in an error.

I hope that this information helps clarify your issue. If not, please elaborate on your issue, and we'll help you resolve it.

Thanks for contacting NI,
Marcus G.
Applications Engineer
National Instruments
0 Kudos
Message 4 of 6
(3,642 Views)
Hi Marcus,

Sorry for the confusion. I have a task that is triggered to run every 0.01 seconds. Its objective is to grab a recent 4-byte sample from the card and write it to a data queue. So the first time it is called, it calls DIG_Block_In. On subsequent runs it calls DIG_Block_Check until the number of items remaining is 0. Once the number of items remaining is 0, it calls DIG_Block_In again to wait for a new 4-byte sample, and the cycle repeats (actually I wait for two 4-byte samples in each call to DIG_Block_In since the minimum final argument to DIG_Block_In is 2).

Since my external device is clocking data into my PCI-DIO-32 card much more often than 100 times/second (more like 1000 times/second), I just wanted to verify t
hat the NI software isn't buffering up data internally somehow. In other words, when I call DIG_Block_In, the data that goes to my buffer will come from subsequent triggers, not from triggers that have taken place at some point in the past.

Hope this clarifies things.

Thanks for your time,
Keith Kingsley
0 Kudos
Message 5 of 6
(3,641 Views)
Hi Keith,

Thanks for the clarification. As long as you aren't doing a double buffered acquisition, the samples should not be saved internally. When you call DIG_Block_In, it will acquire fresh samples and put those into your system buffer. The only on card memory should be the FIFO which aids in preserving the samples as you acquire them and transfer them into system memory. When you call DIG_Block_In anew, the FIFO stores the fresh data values rather then sending stale values to the system buffer.

If you have any further questions concerning this issue, feel free to email us.

Best regards,
Marcus G.
Applications Engineer
National Instruments
0 Kudos
Message 6 of 6
(3,642 Views)