MATLAB Answers

C MEX file issue in for loop

2 views (last 30 days)
A R
A R on 17 Mar 2020
Commented: A R on 17 Mar 2020
Hi, I have a MEX file which transmits data to MCC DAQ. My data is 128x160 double values. But I am not receiving the full output matrix. I have attached the mat file of output variable b. Please give your suggestions.
int analogoutputMatlab(double* data,double* b,int M,int N)
{
int i,j;
int BoardNum = 0;
int ULStat = NOERRORS;
for (j=0;j<M;j++) %M is number of rows, M=128
{
for (i=0;i<N;i++) %N is number of columns, N=160
{
ULStat = cbAOut(BoardNum, Chan1, Range, data[j,i]); %pushing the data to analog output pin of DAQ
ULStat = cbAIn(BoardNum, Chan, Range, &data[j,i]); %receiving the same data via the analog input pin
b[j,i] = data[j,i];
}
}
return 0;
}
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
double *a;
int M,N;
double* b;
const mwSize *dims;
/* Check for proper number of arguments. */
if(nrhs!=1) {
mexErrMsgTxt("one input required.");
}
else if(nlhs!=1) {
mexErrMsgTxt("one output arguments required.");
}
/* get dimensions of the input matricies */
dims=mxGetDimensions(prhs[0]);
M=(int)dims[0];
N=(int)dims[1]; //m and n is 1x256
mexPrintf("m and n is %d %d",M,N);
/* create a pointer to the real data in the input matricies */
a=mxGetData(prhs[0]);
/* create the output matricies */
plhs[0] = mxCreateDoubleMatrix((mwSize)M,(mwSize)N,mxREAL);
b = mxGetPr(plhs[0]);
analogoutputMatlab(a,b,M,N);
}
I think the for loop outputs data columnwise and it only outputs 160 data values. I need to transmit 128x160 data. Please give your suggestions

  0 Comments

Sign in to comment.

Accepted Answer

James Tursa
James Tursa on 17 Mar 2020
Edited: James Tursa on 17 Mar 2020
These lines do not do what you think they do:
double* data
:
... data[j,i] ...
From your code it is obvious that you think data[j,i] is the (j,i)'th element of data. It isn't. Same comment goes for this code and variable b:
double* b
:
b[j,i] = data[j,i];
You cannot double index into a single level of indirection pointer like this and expect the syntax to generate a two level of indirection result. What you actually have is valid C/C++ syntax but it doesn't do at all what you think it does. This expression:
j,i
is a comma operator, which evaluates the first expression (j), throws the result away, then evaluates the second expression (i) and returns that result. That is, as far as the overall result is concerned,
data[j,i]
is equivalent to just
data[i]
and
b[j,i]
is equavalent to
b[i]
So your code is really equivalent to this as far as the compiler is concerned:
ULStat = cbAOut(BoardNum, Chan1, Range, data[i]);
ULStat = cbAIn(BoardNum, Chan, Range, &data[i]);
b[i] = data[i];
Not at all what you intended. To get that 2D indexing that you want, you will need to manually calculate the equivalent linear indexing and use that instead of the j,i expression you are currently using. E.g.,
ULStat = cbAOut(BoardNum, Chan1, Range, data[j+i*M]);
ULStat = cbAIn(BoardNum, Chan, Range, &data[j+i*M]);
b[j+i*M] = data[j+i*M];
P.S. And you can't use data[j][i] or b[j][i] either since that would be too many levels of indirection for data and b.

  1 Comment

A R
A R on 17 Mar 2020
Hi James, Thanks a lot for your help. I tried your code and it worked.

Sign in to comment.

More Answers (0)

Sign in to answer this question.

Tags