简体   繁体   English

MEX文件可在循环中将脉冲输出到DAQ板

[英]MEX-File to Output Pulse in a Loop to a DAQ-Board

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. 我以为我必须使用MEX文件在Matlab到DAQ板的循环(40 kHz)中输出数字脉冲,我从DAQ板供应商那里获得了一些API,但是我真的不知道它们是否有用。 It´sa big documentation on the Mathworks website about MEX-File and APIs, that just make me confused. 这是Mathworks网站上有关MEX文件和API的重要文档,这让我感到困惑。 So I´m asking here if someone can orientate me or showing me an example Code to 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). 我前一段时间使用mex函数编写了一个小的winsock程序包,因为Matlab的tcpip东西在发送大量数据(例如图像)时遇到问题。 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. 除了我了解到如何使该程序包正常工作之外,我对mex函数了解不多,即使是很久以前。 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. 在编写任何混合功能之前,您需要配置Matlab使其能够进行编译。 You do this by typing "mex -setup" in the matlab command line and following the instructions it gives. 您可以通过在matlab命令行中输入“ mex -setup”并按照其说明进行操作。 I configured it to use the Visual Studio compiler (note that you have to have Visual Studio installed for this option to show up). 我将其配置为使用Visual Studio编译器(请注意,必须安装Visual Studio才能显示此选项)。

After configuring the compiler, you compile your mex functions by typing "mex filename.cpp" in the Matlab command-line. 配置编译器后,您可以通过在Matlab命令行中键入“ mex filename.cpp”来编译mex函数。 This produces a .mexw32 file (assuming 32-bit) that Matlab uses when you call your mex function. 这将生成一个.mexw32文件(假定为32位),当您调用mex函数时,Matlab将使用该文件。

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. 要编写mex函数本身,您可以编写一个m文件来声明它并提供注释以及带有实际实现的cpp文件。

As an example, here's one of the m-files I wrote: 例如,这是我编写的m文件之一:

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. 这是相应的cpp文件。 Note that I just made up my own message format and had corresponding C# code that parsed it back out of the byte stream. 请注意,我只是编写了自己的消息格式,并具有将其解析出字节流的相应C#代码。

// 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM