i figured I must use a MEX-File to output Digital pulses in a loop (40 kHz) from Matlab to my DAQ-Board, I have some APIs from the DAQ-Board vendor, but I really dont know if they are useful. It´s a big documentation on the Mathworks website about MEX-File and APIs, that just make me confused. So I´m asking here if someone can orientate me or showing me an example Code 开发者_如何学Goto realise this!!
I wrote a small winsock package using mex functions a while back because Matlab's tcpip stuff was having issues with sending large amounts of data (like images). I don't know much about mex functions other than what I learned to get that package working, and even that was quite some time ago. But, here's some of my notes from before and one of the functions I wrote as an example that hopefully might be some help for you.
Before writing any mex functions, you need to configure Matlab to be able to compile them. You do this by typing "mex -setup" in the matlab command line and following the instructions it gives. I configured it to use the Visual Studio compiler (note that you have to have Visual Studio installed for this option to show up).
After configuring the compiler, you compile your mex functions by typing "mex filename.cpp" in the Matlab command-line. This produces a .mexw32 file (assuming 32-bit) that Matlab uses when you call your mex function.
To write the mex function itself, you write an m-file to declare it and provide comments as well as a cpp file with the actual implementation.
As an example, here's one of the m-files I wrote:
function sendColorImage( socketHandle, colorImage ) %#ok<*INUSD>
%SENDCOLORIMAGE Sends a color image over the given socket
% This function sends a color image over the socket provided. The image
% is really just an MxNx3 matrix. Note that this function sends the
% image data in the order in which Matlab stores it (non-interlaced
% column major order), which is different from most other languages.
% This means the red values for every pixel will be sent first, then the
% green values, then the blue values. Furthermore, the scanlines read
% from the top of the image to the bottom, starting at the left side of
% the image.
%
% socketHande - A handle to the socket over which the image should be
% sent. This handle is returned by the openSocket function when the
% socket is first created.
%
% colorImage - An MxNx3 matrix containing the image data. This matrix
% should be in the same format as a matrix loaded using Matlabs imread
% function.
%
% This is a mex function and is defined in its corresponding .cpp file.
And here's the corresponding cpp file. Note that I just made up my own message format and had corresponding C# code that parsed it back out of the byte stream.
// Instruct the compiler to link with wsock32.lib (in case it isn't specified on the command line)
#pragma comment(lib,"wsock32.lib")
#include "mex.h"
#include <winsock2.h>
#include <cstdio>
#include "protocol.h"
// See the corresponding .m file for documentation on this mex function.
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){
char errorMessage[100];
// Validate input and output arguments
if(nlhs != 0)
mexErrMsgTxt("There are no output arguments for this function.");
if(nrhs != 2)
mexErrMsgTxt("Must have 2 input parameters: the socket handle and the MxNx3 image matrix");
if(!mxIsClass(prhs[0], "uint32"))
mexErrMsgTxt("The first input parameter should be a uint32 containing the socket handle");
if(!mxIsClass(prhs[1], "uint8") || mxGetNumberOfDimensions(prhs[1]) != 3 || mxGetDimensions(prhs[1])[2] != 3)
mexErrMsgTxt("The 2nd input parameter should be an MxNx3 uint8 matrix containing the image");
// Get the socket handle
SOCKET socketHandle = (int)(mxGetPr(prhs[0])[0]);
// Set up the header
int frameWidth = mxGetDimensions(prhs[1])[1];
int frameHeight = mxGetDimensions(prhs[1])[0];
int header[3];
header[0] = COLOR_IMAGE;
header[1] = frameWidth;
header[2] = frameHeight;
// Send the header
int bytesSent;
int totalBytesSent = 0;
while(totalBytesSent < 3*sizeof(int)){
bytesSent = send(socketHandle, ((char*)header) + totalBytesSent, 3*sizeof(int) - totalBytesSent, 0);
if(bytesSent == SOCKET_ERROR){
sprintf(errorMessage, "Error sending image header over the socket: %d", WSAGetLastError());
mexErrMsgTxt(errorMessage);
}
totalBytesSent += bytesSent;
}
// Send the image
totalBytesSent = 0;
int totalBytesToSend = frameWidth * frameHeight * 3;
char* dataPointer = (char*)mxGetData(prhs[1]);
while(totalBytesSent < totalBytesToSend){
bytesSent = send(socketHandle, dataPointer + totalBytesSent, totalBytesToSend - totalBytesSent, 0);
if(bytesSent == SOCKET_ERROR){
sprintf(errorMessage, "Error sending image over the socket: %d", WSAGetLastError());
mexErrMsgTxt(errorMessage);
}
totalBytesSent += bytesSent;
}
}
精彩评论