06-23-2011 01:36 PM
Greetings,
I'm new to writing code to control the PCI-6534 and I'm trying to update to using NIDAQmx. We previously had a DLL built for us using the legacy dll which worked great but the guy that wrote it no longer works here and we're looking into upgrading to a faster Digital I/O card. But before I spend the money, I want to know I can figure out how to control the 6534 card using Matlab and the calls to the NIDAQmx.
I use the 6534 in 2 modes (using legacy): Port0 continuous pattern I/O with external clocking and Port1 configured as static I/O using software clocking. I believe I know how to do the static I/O, but the continuous pattern I/O is giving me problems. Ultimately I want to write an 8xN bit array (which I'll refer to as the default "frame") to Port0 which the card will continously output (the pattern MUST repeat after the Nth byte is outputted, no extra bytes should be sent). The next part is that a new frame is sent once and then the default frame is sent again (repeating the default frame until a new single frame is required).
Now the legacy DLL written performs all of this flawlessly so I would think the NIDAQmx should be able to handle this as well. The problem I'm having is 2-fold. First I can't seem to get the 6534 to repeat after the Nth bit is sent, I always get extra 0's sent. The next issue is I don't know how to change the frame without stopping the task, rewrite the output and then restart the task which doesn't allow for continuous operation.
I'm using Windows 7 64-bit, Matlab 2011a 64-bit, and I have the latest NIDAQmx (as of 6/23/2011).
Below is the test code I've been trying. One thing to note is I'm using internal timing instead of external for this test case.
%% Start by loading the NI dll: Lib = 'NIDAQmx'; if ~libisloaded(Lib) funclist = loadlibrary('nicaiu.dll','NIDAQmx.h','alias',Lib); libfunctionsview(Lib) end % Reset NI6534 clearvars -except Lib DAQmxCheckError(Lib,calllib(Lib,'DAQmxResetDevice','Dev1')) % Create Channels LineGrouping = 'DAQmx_Val_ChanForAllLines'; Device = 'Dev1/port0'; Taskh.DO_00 = DAQmxCreateDOChan(Lib,Device,LineGrouping); % Configure Sample Clock Timing Source = 'OnboardClock'; Rate = double(1e6); DATA = uint32([1,2,4,8,16,32,64,128]); SmpsPerChanToGen = uint64(numel(DATA)); Err = calllib(Lib,'DAQmxCfgSampClkTiming',Taskh.DO_00, Source,Rate,'DAQmx_Val_Rising','DAQmx_Val_ContSamps',SmpsPerChanToGen); DAQmxCheckError(Lib,Err); Err = calllib(Lib,'DAQmxSetDOUseOnlyOnBrdMem',Taskh.DO_00,'',uint32(0)); DAQmxCheckError(Lib,Err); BufferSize = SmpsPerChanToGen; Err = calllib(Lib,'DAQmxCfgOutputBuffer',Taskh.DO_00,uint32(BufferSize)); DAQmxCheckError(Lib,Err); Err = calllib(Lib,'DAQmxSetWriteRegenMode',Taskh.DO_00,'DAQmx_Val_AllowRegen'); % Write Data to Channel DataLayout = 'DAQmx_Val_GroupByChannel'; SPerChan = int32(SmpsPerChanToGen); AutoStart = uint32(0); Timeout = double(10); Array = libpointer('uint8Ptr',DATA); [Err,SampsPerChanWritten,~,~] = calllib(Lib,'DAQmxWriteDigitalU8', Taskh.DO_00,SPerChan,AutoStart,Timeout,'DAQmx_Val_GroupByChannel', Array,libpointer('int32Ptr',0),libpointer('uint32Ptr',[])); DAQmxCheckError(Lib,Err); % Start Task Err = calllib(Lib,'DAQmxStartTask',Taskh.DO_00); DAQmxCheckError(Lib,Err);
Now this seems to work for sending out a single 8xN frame, but I can't figure out how to update the data without stopping the task.
Any help is appreciated.
Thanks,
Jason
06-23-2011 01:37 PM
Oops...
BufferSize = SmpsPerChanToGen;
should be
BufferSize = SmpsPerChanToGen*4;
otherwise I get an error saying the buffer is too small.
Thanks,
Jason
06-24-2011 10:53 AM
Jason,
Thank you for using the National Instruments forums. If I understand your question correctly you want to continuously generate a pattern and then generate another updatable pattern after your base pattern. In order to continuosly generate your base pattern continuously, there is an example c program that will generate continous digital output that can be found \National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Digital\Generate Values\Cont Write Dig Port-Ext Clk\ContWriteDigPort-ExtClk.c. You can port this over with new syntax or use a MEX file. As for the second patten how did you trigger this second pattern in your traditional daq program? Are you going to use a button to update that data or is it the same data everytime, or just a list that it pulls from after every regeneration?
Regards,
Brian P.
06-27-2011 06:30 AM
Hi Brian,
Thanks for the assistance. Thanks for the link to the ansi c example. I already found that and that's what I started with when I started my project. The problem I have with this portion of code is the buffer size. The problem is this: When I entered the equivalent Matlab code to run the ContWriteDigPort-ExtClk.c code I received a "DAQmx error - Generation cannot be started, because the selected buffer size is too small." error. After doing a bit of research, it appears that the buffer size needs to be 4x larger than the data (why? I don't know). The problem with this is I want to send a pattern that is 8xN to Port0. After the Nth byte is sent, the pattern should immediately repeat but because the buffer size is larger than the data, there is a large "dead time" before the data repeats. For example, if I want to repeat this pattern "10101010", I will get "10101010000000000000000000000000" then it will repeat.
Unfortunately I can't answer your question on how the 2nd pattern was triggered in our original tradition code. I don't have the code which our DLL was created.
Thanks,
Jason
07-01-2011 02:25 PM
Jason,
Thanks for replying. Let me make sure I understand what you are hoping to do. You want to output a pattern of 8xN data from port 0 and you want this to happen continuously, with no gaps between data. But you also want to be able to change that pattern that you output at some point. Therefore, I assume you are configuring to regenerate data from the PC Buffer. Here are some suggestions that I have:
-Have you tried not manually configuring the output buffer? The device should automatically set the buffer size for you if it is not given explicit numbers. If you do, does it still give you the "buffer size is too small" error?
-Have you tried using different data formats for your samples such as uint8 or uint16 and see if that has any effect on the required buffer size? Try that and see if it affects the output.
Regards,
Joe S.