uInt8 ReadDigitalU8(uInt32 port) { uInt8 data=0; #ifdef _USE_REAL_KIT_ int32 error_0=0; char errBuff_0[2048]={'\0'}; int32 read_0; TaskHandle task_handle = tasks[port]; DAQmxReadDigitalU8(task_handle,1,10.0,DAQmx_Val_GroupByChannel,&data,1,&read_0,NULL); #else data=sim_ReadDigitalU8(port); #endif /* bool flag_error=false; if( (port==0) && !(portos[port] & 1<<2) && (data & 1<<2) && (portos[2]&1<<6)) {printf("\nATTENTION: XX beyond left limit...\n");flag_error=true;} if( (port==0) && !(portos[port] & 1<<0) && (data & 1<<0) && (portos[2]&1<<7)) {printf("\nATTENTION: XX beyond right limit...\n");flag_error=true;} if( (port==1) && !(portos[port] & 1<<3) && (data & 1<<3) && (portos[2]&1<<2)) {printf("\nATTENTION: ZZ below lower limit...\n");flag_error=true;} if( (port==0) && !(portos[port] & 1<<6) && (data & 1<<6) && (portos[2]&1<<3)) {printf("\nATTENTION: ZZ above upper limit...\n");flag_error=true;} if( (port==0) && !(portos[port] & 1<<5) && (data & 1<<5) && (portos[2]&1<<4)) {printf("\nATTENTION: YY beyond OUTSIDE sensor...\n"); flag_error=true;} if( (port==0) && !(portos[port] & 1<<3) && (data & 1<<3) && (portos[2]&1<<5)) {printf("\nATTENTION: YY beyond INSIDE sensor...\n");flag_error=true;} portos[port]=data; if(flag_error) { WriteDigitalU8(2, 0); exit(0); } */ return(data); }
//Gateway routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Read input arguments char outputFormat[10]; char outputVarName[MAXVARNAMESIZE]; int outputVarSampsPerChan; double timeout; int numSampsPerChan; bool outputData; //Indicates whether to return an outputData argument mxClassID outputDataClass; uInt32 bufSize; bool writeDigitalLines; uInt32 bytesPerChan=0; TaskHandle taskID, *taskIDPtr; int32 status; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; //Determine if this is a buffered read operation status = DAQmxGetBufInputBufSize(taskID, &bufSize); if (status) handleDAQmxError(status, "DAQmxGetBufInputBufSize"); //Handle input arguments if ((nrhs < 2) || mxIsEmpty(prhs[1]) || mxIsInf(mxGetScalar(prhs[1]))) { if (bufSize==0) numSampsPerChan = 1; else numSampsPerChan = DAQmx_Val_Auto; } else numSampsPerChan = (int) mxGetScalar(prhs[1]); if ((nrhs < 3) || mxIsEmpty(prhs[2])) { //Automatic determination of read type bool isLineBased = (bool) mxGetScalar(mxGetProperty(prhs[0],0,"isLineBasedDigital")); if ((bufSize==0) && isLineBased) //This is a non-buffered, line-based Task: return data as a double array outputDataClass = mxDOUBLE_CLASS; else { status = DAQmxGetReadDigitalLinesBytesPerChan(taskID,&bytesPerChan); //This actually returns the number of bytes required to represent one sample of Channel data if (status) handleDAQmxError(status, "DAQmxGetReadDigitalLinesBytesPerChan"); if (bytesPerChan <= 8) outputDataClass = mxUINT8_CLASS; else if (bytesPerChan <= 16) outputDataClass = mxUINT16_CLASS; else if (bytesPerChan <= 32) outputDataClass = mxUINT32_CLASS; else mexErrMsgTxt("It is not currently possible to read integer values from Task with greater than 32 lines per sample value"); } } else { mxGetString(prhs[2], outputFormat, 10); if (_strcmpi(outputFormat,"uint8")) outputDataClass = mxUINT8_CLASS; else if (_strcmpi(outputFormat,"uint16")) outputDataClass = mxUINT16_CLASS; else if (_strcmpi(outputFormat,"uint32")) outputDataClass = mxUINT32_CLASS; else if (_strcmpi(outputFormat,"double")) outputDataClass = mxDOUBLE_CLASS; else if (_strcmpi(outputFormat,"logical")) outputDataClass = mxLOGICAL_CLASS; else mexErrMsgTxt("The specified 'outputFormat' value (case-sensitive) is not recognized."); } if ((outputDataClass == mxDOUBLE_CLASS) || (outputDataClass == mxLOGICAL_CLASS)) { writeDigitalLines = true; if (bytesPerChan == 0) { status = DAQmxGetReadDigitalLinesBytesPerChan(taskID,&bytesPerChan); //This actually returns the number of bytes required to represent one sample of Channel data if (status) handleDAQmxError(status, "DAQmxGetReadDigitalLinesBytesPerChan"); } } else writeDigitalLines = false; if ((nrhs < 4) || mxIsEmpty(prhs[3]) || mxIsInf(mxGetScalar(prhs[3]))) timeout = DAQmx_Val_WaitInfinitely; else timeout = mxGetScalar(prhs[3]); if ((nrhs < 5) || mxIsEmpty(prhs[4])) //OutputVarSizeOrName argument { outputData = true; outputVarSampsPerChan = numSampsPerChan; //If value is DAQmx_Val_Auto, then the # of samples available will be queried before allocting array } else { outputData = mxIsNumeric(prhs[4]); if (outputData) { if (nlhs < 2) mexErrMsgTxt("There must be two output arguments specified if a preallocated MATLAB variable is not specified"); outputVarSampsPerChan = (int) mxGetScalar(prhs[4]); } else mxGetString(prhs[4], outputVarName, MAXVARNAMESIZE); } //Determin # of output channels uInt32 numChannels; DAQmxGetReadNumChans(taskID, &numChannels); //Reflects number of channels in Task, or the number of channels specified by 'ReadChannelsToRead' property //Determine output buffer/size (creating if needed) mxArray *outputDataBuf, *outputDataBufTrue; void *outputDataPtr; //float64 *outputDataPtr; if (outputData) { mwSize numRows; if (outputVarSampsPerChan == DAQmx_Val_Auto) { status = DAQmxGetReadAvailSampPerChan(taskID, (uInt32 *)&outputVarSampsPerChan); if (status) { handleDAQmxError(status, "DAQmxGetReadAvailSampPerChan"); return; } } if (writeDigitalLines) numRows = (mwSize) (outputVarSampsPerChan * bytesPerChan); else numRows = (mwSize) outputVarSampsPerChan; if (outputDataClass == mxDOUBLE_CLASS) { outputDataBuf = mxCreateNumericMatrix(numRows,numChannels,mxUINT8_CLASS,mxREAL); outputDataBufTrue = mxCreateDoubleMatrix(numRows,numChannels,mxREAL); } else outputDataBuf = mxCreateNumericMatrix(numRows,numChannels,outputDataClass,mxREAL); } else //I don't believe this is working { outputDataBuf = mexGetVariable("caller", outputVarName); outputVarSampsPerChan = mxGetM(outputDataBuf); //TODO: Add check to ensure WS variable is of correct class } outputDataPtr = mxGetData(outputDataBuf); //Read data int32 numSampsRead; int32 numBytesPerSamp; switch (outputDataClass) { case mxUINT8_CLASS: status = DAQmxReadDigitalU8(taskID, numSampsPerChan, timeout, fillMode, (uInt8*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxUINT16_CLASS: status = DAQmxReadDigitalU16(taskID, numSampsPerChan, timeout, fillMode, (uInt16*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxUINT32_CLASS: status = DAQmxReadDigitalU32(taskID, numSampsPerChan, timeout, fillMode, (uInt32*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxLOGICAL_CLASS: case mxDOUBLE_CLASS: status = DAQmxReadDigitalLines(taskID, numSampsPerChan, timeout, fillMode, (uInt8*) outputDataPtr, outputVarSampsPerChan * numChannels * bytesPerChan, &numSampsRead, &numBytesPerSamp, NULL); break; default: mexErrMsgTxt("There must be two output arguments specified if a preallocated MATLAB variable is not specified"); } //Return output data if (!status) { //mexPrintf("Successfully read %d samples of data\n", numSampsRead); if (outputData) { if (nlhs > 0) { if (outputDataClass == mxDOUBLE_CLASS) { //Convert logical data to double type double *outputDataTruePtr = mxGetPr(outputDataBufTrue); for (size_t i=0;i < mxGetNumberOfElements(outputDataBuf);i++) *(outputDataTruePtr+i) = (double) *((uInt8 *)outputDataPtr+i); mxDestroyArray(outputDataBuf); plhs[0] = outputDataBufTrue; } else plhs[0] = outputDataBuf; } else mxDestroyArray(outputDataBuf); //If you don't read out, all the reading was done for naught } else //I don't believe this is working { mexErrMsgTxt("invalid branch"); mexPutVariable("caller", outputVarName, outputDataBuf); if (nlhs > 0) //Return empty value for output data plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } if (nlhs > 1) //Return number of samples actually read { double *sampsReadOutput; plhs[1] = mxCreateDoubleScalar(0); sampsReadOutput = mxGetPr(plhs[1]); *sampsReadOutput = (double)numSampsRead; } } else //Read failed handleDAQmxError(status, mexFunctionName()); }