Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Use M-Series cards with DAQmx in Matlab!

Highlighted
Hi DAQers!

Who is this message for?
For all people wanting to use their M-Series cards (and/or NI_CAQmx drivers) with Matlab.

Content:
Basic introduction into importing DAQmx into Matlab. Simple AI (analog input), advanced AI (synchronous)
and simple AO solutions are displayed with Matlab source code.

Motivation:
There's probably little disagreement that the new M-Series cards are superior to the old E-Series cards.
However, Matlab does (as of February 2005) not support either directly.
By buying the Data Acquisition Toolbox you can access most of the E-Series' functions from within Matlab.
But this will not help you with your new M-Series card! But it is possible to use M-Series cards with Matlab.

First step
Start by loading the NI dll:
funclist = loadlibrary('nicaiu.dll','nidaqmx.h','alias','myni')
(You can choose any alias as long as it is a legal variable name.)
If your version of Matlab is too old to provide the "loadlibrary" function directly, download it here:
http://www.codeproject.com/dll/MatlabGenericDll.asp?df=100&forumid=26247&exp=0&select=972623
After importing, you see the list of available functions.
You can also display them by
libfunctionsview('myni')

That's basically it. By using the National Instruments NI-DAQmx C Reference manual and libfunctionsview('myni')
you have access to those functions. One special thing you need to keep in mind is the fact that pointers
work differently in Matlab than in C. This problem can be solved by using the Matlab function "libpointer".
Sometimes Matlab does not require a pointer when C would. But I found that it does not hurt to
specify a pointer in this case. Whether Matlab expects a pointer can be seen in the output
created by libfunctionsview('myni')

The general syntax for calling DAQmx functions is:
[outputarguments]=calllib(alias,NIDAQmx_functionname,inputarguments)

My next message will show a function I wrote that enables basic and advanced analoginput.
Jens
0 Kudos
Message 1 of 106
(20,556 Views)
Hi!

As promised, my Matlab function to use the M-Series card with Matlab.
I have the bad habit of programming in German and English at the same time.
I tried to correct that for this posting. I hope I succeeded!
I wrote this function to suit my needs -which it does.
Feel free to modify it to suit yours.

Jens

Edit: I just saw that my m-File is longer than 5000 characters! #duh#
Sorry!
I'll see if I can get a download up!

Here's the abbreviated m-file without synchronous AI:

function messmatrix=NImess(synchron,trigger,numofchans,samprate,samptime)
funclist = loadlibrary('nicaiu.dll','nidaqmx.h','alias','myni');
disp('NI: Create Tasks')
taskh1=uint32(1);
[a,b,taskh1] = calllib('myni','DAQmxCreateTask','master',taskh1)
taskchans1=['Dev1/ai0:' num2str(numofchans-1)];
[a,b,c,d] = calllib('myni','DAQmxCreateAIVoltageChan',uint32(taskh1),taskchans1,'',-1,-10,10,DAQmx_Val_Volts,'')
nsample=samprate*samptime; %
disp('NI: Config Sample Clock')
[a,b]=calllib('myni','DAQmxCfgSampClkTiming',taskh1,'',samprate,DAQmx_Val_Rising,...
DAQmx_Val_FiniteSamps,nsample)
disp('NI: Config Digital edge start trigger')
if trigger==1
[a,b]=calllib('myni','DAQmxCfgDigEdgeStartTrig',taskh1,'/Dev1/PFI0',DAQmx_Val_Rising );
else
[a]=calllib('myni','DAQmxDisableStartTrig',taskh1)
end

disp('NI: Start task(s)')
[a]=calllib('myni','DAQmxStartTask',taskh1)

DAQmx_Val_GroupByScanNumber = 1;
readarray1=ones(numofchans,nsample);
readarray1_ptr=libpointer('doublePtr',readarray1);
sampread=0;
sampread_ptr=libpointer('int32Ptr',sampread);
empty=[];
empty_ptr=libpointer('uint32Ptr',empty);
arraylength=nsample*numofchans; % more like "buffersize",
disp('NI: Reading Data!')
[a,readarray1,sampread,empty]=calllib('myni','DAQmxReadAnalogF64',taskh1,-1,-1,...
DAQmx_Val_GroupByScanNumber,readarray1_ptr,arraylength,sampread_ptr,empty_ptr);
disp('NI: Stop task')
[a] = calllib('myni','DAQmxStopTask',taskh1);
disp('NI: Clear task(s)')
[a] = calllib('myni','DAQmxClearTask',taskh1);
messmatrix=[readarray1'];
disp('NImess finished')
0 Kudos
Message 2 of 106
(20,486 Views)
Hi Jens,
thanks a lot for your help.
Yesterday I finally managed to get my PCI-6221 card running using Matlab based on your last message, help from my colleagues and the manuals.
Since I thought that there might be some more users having the same difficulty I sent the simple example to Matlab's Central File Exchange explicitly referencing your message in the NI discussion forum.
Anyway, I am very glad and thankful for your example.
One last question: do you know if there is a possibility to load the constants defined in a header-file directly into matlab (without redefining them)?
Best regards from snowy Karlsruhe
Andreas
0 Kudos
Message 3 of 106
(20,455 Views)
Hi Andreas!

Glad it works for you.
I now have my personal webpage updated with the complete file contents:
http://www.jr-worldwi.de/work/matlab/
(opens in new window)

Regarding your last question about the constants:
Yes, this is possible.
I converted one of the NI files to be loaded as an .m-file.
This included hex to decimal, commenting and ";"ing Smiley Wink
right click, save as
I think I stripped a few lines out, not too sure. All of the important constants should be in there.
Please note that Matlab truncates long (>63 chars) variable names!
The included error code definitions are rather useless for Matlab.
A reverse look-up would be more useful:
You can get the full error message by calling the DAQmxGetErrorString function.
But this often causes Matlab 7.0.1 to crash dump (?!),
so I search the NI documents whenever I receive an error code.

CU
Jens
Message 4 of 106
(20,453 Views)
Hi Jens_DE,

Thanks for your info on using NI-DAQmx with matlab, works fine, not sure why NI didnt make it more obvious which dll to use in the documentation.

Could you please repost the link to the constants loading file in matlab because it appears to be broken

Thanks to Kapp for your examples in matlab, a great help in getting my 6229 working!

Cheers
Luke
0 Kudos
Message 5 of 106
(20,157 Views)
Hi Luke!

Thanks for the info!
I had to take down the site and re-upload it again a few weeks ago.
This file was not sitting on my home PC so I forgot the upload. My bad.
Anyway, link should work now.


Good luck, these are some nice cards!
Jens
0 Kudos
Message 6 of 106
(20,125 Views)

Hi Jens,

Thx 1000x for your solution working with DAQmx.

I have 1 problem left: I cant load the 'DAQmxCfgSampClkTiming' function, as I get an error message due to the uint64 data type.

I use Matlab 6.5.0, Release 13.

I can now set the 'DAQmxCfgSampClkTiming' in the MAX tool, but thats not very elegant. Is there a better solution?

How did you load that function?

Thanks

Wendelin

0 Kudos
Message 7 of 106
(19,899 Views)
Hi Wendelin!
I am sorry, I have no idea what is happening on your side.
It should be as simple as
disp('NI: Config Sample Clock')
[a,b]=calllib('myni','DAQmxCfgSampClkTiming',taskh1,'',samprate,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,nsample)

I use Matlab 7.0 (which has its own problems...),
but I think Matlab 6.5 should fully work with uint64.

What is the error message you get?

Cya
Jens


0 Kudos
Message 8 of 106
(19,888 Views)

Jens,

Thanks again for the very fast response.

So I played with the card yesterday and I am pretty sure its the uInt64 in the sampsPerChanToAcquire

When I load the dll like in your example,

    funclist = loadlibrary('nicaiu.dll','nidaqmx.h','alias','myni');

I get : Warning: The data type 'uint64' used by function DAQmxCfgSampClkTiming does not exist

When I then call

[a,b]=calllib('myni','DAQmxCfgSampClkTiming',taskh1,'',samprate,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,nsample)

I get

??? method was not found

I then used funclist = loadlibrary('nicaiu.dll',@mxproto); to change the header into uint32 for the sampsPerChanToAcquire, after which the "??? method was not found"

didnt come up again, but the call didnt work.

 

So the only way right now is to start MAX, set all the timing parameters and then run your program. Not very elegant, hmmm.

This must be hidden somewhere in the 6.5 and 7.0 difference how they handle the uint64, I can remember seeing threads on that somewhere, but cant track it down.

Maybe there is a fix around? Something with 2*uint32 or *uint64..I dont know, I am not a C expert (as u might already have realized)

Regards

Wendelin

0 Kudos
Message 9 of 106
(19,881 Views)
Hi Wendelin,

this may be a purely Matlab-related problem:
http://www.mathworks.com/access/helpdesk_r13/help/base/relnotes/matlab/matlab13sp1.html
If the problem appears already when loading the library, I assume you cannot work around this problem.
Maybe the guys&gals in the Mathworks forum can help you out :-/

Good luck
Jens

0 Kudos
Message 10 of 106
(19,878 Views)