Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » Software » comp.soft-sys.matlab

Topic: mex function to control National Instruments function generator card
Replies: 2   Last Post: Mar 5, 2013 9:57 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
Nathan

Posts: 9
Registered: 9/3/10
mex function to control National Instruments function generator card
Posted: Feb 27, 2013 10:54 AM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

Hello,

I am hoping some nice person would be willing to help me out with some Matlab code I have been working on to run a National Instruments function generator card. I had no luck in using the Instrument Control toolbox (or manually using loadlibrary to access the NI libraries), so I am writing a few mex functions to do this. This has worked for me in the past.

Right now, the code works for a while - I can initialize the card and do a few commands. But after a while, it crashes Matlab. I expect that I have some sort of memory handling error somewhere. I rarely code in C any more, and I bet I'm making some really simple but dumb mistake. If anyone has time, could they look through the brief code below and let me know if they see any problems?

Here is the function I use to initialize (myniFGENInit.cpp)
//****************************************************************************************************************************
#include <yvals.h>
#if(_MSC_VER)>=1600
#define __STDC_UTF_16__
#endif
#include "mex.h"
#include <stdio.h>
#include <fstream>
#include <winsock2.h>

//useage in matlab:
// [obj, errorstruct]=MyniFGENInit(obj, channel);

#include <stdlib.h>
#include "C:\Program Files\IVI Foundation\IVI\Include\niFgen.h"
#define MAX_STRING_SIZE 50

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
ViStatus error = VI_SUCCESS;
ViRsrc resourceName = "Dummy";
ViChar errorMessage[512] = " ";
ViSession vi;
size_t buflen;
mxArray *value_ptr;
double *start_of_value;

const char *errorfield_names[] = {"error","errorMessage"};
struct ErrorStruct
{
ViStatus error;
ViChar errorMessage;
};

if(nrhs!=1) mexErrMsgTxt("1 input only (resourceName!)");
if(nlhs!=2) mexErrMsgTxt("2 outputs required (vi, errorstruct).");

if (mxIsChar(prhs[0]) != 1) mexErrMsgIdAndTxt( "MATLAB:revord:inputNotString","Input must be a string.");
if (mxGetM(prhs[0])!=1) mexErrMsgIdAndTxt( "MATLAB:revord:inputNotVector","Input must be a row vector.");

buflen=(mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
resourceName = mxArrayToString(prhs[0]);

if(resourceName == NULL) mexErrMsgIdAndTxt( "MATLAB:revord:conversionFailed", "Could not convert input to string.");

checkErr (niFgen_init (resourceName, VI_TRUE, VI_TRUE, &vi));
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = vi;

Error :
if (error != VI_SUCCESS) {
niFgen_ErrorHandler (vi, error, errorMessage);
mexPrintf("%s\n",errorMessage);
mexPrintf("Resource name: %s\n",resourceName);
mexPrintf("error: %5.1f\n",resourceName);
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
}
else {
strcpy (errorMessage, "Success!");
}

plhs[1] = mxCreateStructMatrix(1,1,2,errorfield_names);

value_ptr=mxCreateDoubleMatrix(1,1,mxREAL);
start_of_value=mxGetPr(value_ptr);
start_of_value[0]=error;
mxSetField(plhs[1],0,"error",value_ptr);

value_ptr=mxCreateString(errorMessage);
mxSetField(plhs[1],0,"errorMessage",value_ptr);
}


Here is a typical function where I use the card. Here I query it to get some information about its current state (QueryWaveform.cpp)
//****************************************************************************************************************************
#include <yvals.h>
#if(_MSC_VER)>=1600
#define __STDC_UTF_16__
#endif
#include "mex.h"
#include <stdio.h>
#include <fstream>
#include <winsock2.h>

//useage in matlab:
// [waveform,amplitude,dcOffset,frequency,startPhase,errorstruct]=QueryWaveform(obj, channel);

#include <stdlib.h>
#include "C:\Program Files (x86)\IVI Foundation\IVI\Include\niFgen.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

ViStatus error = VI_SUCCESS;
double dummy;
ViChar errorSource[512];
ViChar errorMessage[512] = " ";
ViSession vi;
ViInt32 *waveform;
ViConstString channelName;
mxArray *value_ptr;
double *start_of_value;
ViReal64 *amplitude, *dcOffset, *frequency, *startPhase;

const char *errorfield_names[] = {"error","errorMessage"};
struct ErrorStruct
{
ViStatus error;
ViChar errorMessage;
};

if(nrhs!=2) mexErrMsgTxt("2 input only (session,channelName)");
if(nlhs!=6) mexErrMsgTxt("6 outputs only (waveform,amplitude,dcOffset,frequency,startPhase,errorstruct)");

dummy=*mxGetPr(prhs[0]);
vi=(ViSession)dummy;

if (mxIsChar(prhs[1]) != 1) mexErrMsgIdAndTxt( "MATLAB:revord:inputNotString","Input must be a string.");
if (mxGetM(prhs[1])!=1) mexErrMsgIdAndTxt( "MATLAB:revord:inputNotVector","Input must be a row vector.");
channelName = mxArrayToString(prhs[1]);

plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
plhs[1] = mxCreateDoubleMatrix(1,1, mxREAL);
plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL);
plhs[3] = mxCreateDoubleMatrix(1,1, mxREAL);
plhs[4] = mxCreateDoubleMatrix(1,1, mxREAL);

waveform = (ViInt32 *)mxGetData(plhs[0]);
amplitude = mxGetPr(plhs[1]);
dcOffset = mxGetPr(plhs[2]);
frequency = mxGetPr(plhs[3]);
startPhase = mxGetPr(plhs[4]);

if (vi != VI_NULL) {
checkErr (niFgen_GetAttributeViInt32 (vi,channelName,NIFGEN_ATTR_FUNC_WAVEFORM,waveform));
checkErr (niFgen_GetAttributeViReal64 (vi,channelName,NIFGEN_ATTR_FUNC_AMPLITUDE,amplitude));
checkErr (niFgen_GetAttributeViReal64 (vi,channelName,NIFGEN_ATTR_FUNC_DC_OFFSET,dcOffset));
checkErr (niFgen_GetAttributeViReal64 (vi,channelName,NIFGEN_ATTR_FUNC_FREQUENCY,frequency));
checkErr (niFgen_GetAttributeViReal64 (vi,channelName,NIFGEN_ATTR_FUNC_START_PHASE,startPhase));
}

Error :
if (error != VI_SUCCESS) {
niFgen_ErrorHandler (vi, error, errorMessage);
mexPrintf("%s\n",errorMessage);
mexPrintf("%s\n",errorSource);
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
plhs[3] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
plhs[4] = mxCreateDoubleMatrix(1, 1, mxREAL);
*mxGetPr(plhs[0]) = -1.0;
}
else {
strcpy (errorMessage, "Success!");
}

plhs[5] = mxCreateStructMatrix(1,1,2,errorfield_names);
value_ptr=mxCreateDoubleMatrix(1,1,mxREAL);
start_of_value=mxGetPr(value_ptr);
start_of_value[1]=error;
mxSetField(plhs[5],0,"error",value_ptr);

value_ptr=mxCreateString(errorSource);
mxSetField(plhs[5],0,"errorSource",value_ptr);
value_ptr=mxCreateString(errorMessage);
mxSetField(plhs[5],0,"errorMessage",value_ptr);

}

Here is the code I use to compile (Matlab R2012b, Windows 7 64bit):

mex('-v', '-LC:\Program Files\IVI Foundation\IVI\Lib_x64\msc', '-lniFgen', '-livi','-liviFgen', '-IC:\Program Files\IVI Foundation\VISA\Win64\Include','QueryWaveform.cpp');

Previously I wrote similar code for an NI High Speed digitizer card and an older version of Matlab (R2010). It worked fine for years, but recently it started giving me problems where it would crash Matlab whenever I executed either "clear all" or "clear functions". At least in that state, I could use my software. Now it doesn't work either. The inability to clear things makes me wonder if I have a memory handling problem. However, I don't know for sure.

Any help anyone could give would be really appreciated. At one point in my life I probably could figure this out, but my memory of C programming is pretty hazy, and debugging this is driving me crazy.

-N



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.