DAQManager::DAQManager() { stateCount = 8; states = new uInt32[stateCount]; states[0] = 0x8; states[1] = 0xC; states[2] = 0x4; states[3] = 0x6; states[4] = 0x2; states[5] = 0x3; states[6] = 0x1; states[7] = 0x9; stateNum = 0; dataAcquired = 0; voltageData = new float64[SAMPLE_COUNT]; #ifdef _WIN32 DAQmxCreateTask("", &motorTaskHandle); DAQmxCreateTask("", &adcTaskHandle); DAQmxCreateTask("", &triggerTaskHandle); DAQmxCreateDOChan(motorTaskHandle, "Dev1/port0", "", DAQmx_Val_ChanForAllLines); DAQmxCreateDOChan(triggerTaskHandle, "Dev1/port1", "", DAQmx_Val_ChanForAllLines); DAQmxCreateAIVoltageChan(adcTaskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxCfgSampClkTiming(adcTaskHandle, "", SAMPLE_FREQ, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, SAMPLE_COUNT); DAQmxCfgDigEdgeStartTrig(adcTaskHandle, "/Dev1/PFI0", DAQmx_Val_Rising); DAQmxRegisterEveryNSamplesEvent(adcTaskHandle, DAQmx_Val_Acquired_Into_Buffer, 1000, 0, EveryNCallbackWrapper, this); DAQmxStartTask(motorTaskHandle); DAQmxStartTask(triggerTaskHandle); uInt32 data; int32 written; data = states[0]; DAQmxWriteDigitalU32(motorTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); data=0x0; DAQmxWriteDigitalU32(triggerTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); #elif __APPLE__ DAQmxBaseCreateTask("motorTask", &motorTaskHandle); DAQmxBaseCreateDOChan(motorTaskHandle, "Dev1/port0", "", DAQmx_Val_ChanForAllLines); DAQmxBaseStartTask(motorTaskHandle); DAQmxBaseCreateTask("adcTask", &adcTaskHandle); DAQmxBaseCreateAIVoltageChan(adcTaskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxBaseCfgSampClkTiming(adcTaskHandle,"OnboardClock", SAMPLE_FREQ, DAQmx_Val_Rising, DAQmx_Val_ContSamps, SAMPLE_COUNT); DAQmxBaseCfgInputBuffer(adcTaskHandle,0); DAQmxBaseStartTask(adcTaskHandle); uInt32 data; int32 written; data = states[0]; DAQmxBaseWriteDigitalU32(motorTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); #endif }
void DAQManager::trigger() { uInt32 data; int32 written; #ifdef _WIN32 data = 0xFFFF; DAQmxWriteDigitalU32(triggerTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); data = 0x0; DAQmxWriteDigitalU32(triggerTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); #elif __APPLE__ DAQmxBaseStopTask(adcTaskHandle); DAQmxBaseStopTask(motorTaskHandle); #endif }
int motorControl::motorDisable() { int32 error=0; char errBuff[2048] = {'\0'}; uInt32 dataDisable=0x00000000; int32 written; float64 zeroVoltages[3]={0.0,0.0,0.0}; while(isControlling){ } DAQmxErrChk (DAQmxStartTask(motorEnableHandle)); DAQmxErrChk (DAQmxStartTask(motorTaskHandle)); DAQmxErrChk (DAQmxWriteDigitalU32(motorEnableHandle,1,1,10.0,DAQmx_Val_GroupByChannel,&dataDisable,NULL,NULL)); DAQmxErrChk (DAQmxWriteAnalogF64(motorTaskHandle,1,FALSE,10,DAQmx_Val_GroupByChannel,zeroVoltages,NULL,NULL)); Sleep(500); DAQmxStopTask(motorTaskHandle); DAQmxStopTask(motorEnableHandle); isControlling = FALSE; isWindUp = FALSE; live = FALSE; isEnable = FALSE; Error: if( DAQmxFailed(error) ){ printf("DisableMotor Error: %s\n",errBuff); DAQmxGetExtendedErrorInfo(errBuff,2048); printf("DAQmx Error: %s\n",errBuff); DAQmxStopTask(motorEnableHandle); DAQmxStopTask(motorTaskHandle); DAQmxClearTask(motorEnableHandle); DAQmxClearTask(motorTaskHandle); } return 0; }
int motorControl::motorEnable() { uInt32 dataEnable=0x00000001; char errBuff[2048]={'\0'}; int32 error=0; float64 zeroVoltages[3]={0.0,0.0,0.0},zeroVoltage={0.0}; DAQmxErrChk (DAQmxStartTask(motorEnableHandle)); DAQmxErrChk (DAQmxStartTask(motorTaskHandle)); DAQmxErrChk (DAQmxWriteDigitalU32(motorEnableHandle,1,1,10.0,DAQmx_Val_GroupByChannel,&dataEnable,NULL,NULL)); DAQmxErrChk (DAQmxWriteAnalogF64(motorTaskHandle,1,FALSE,10,DAQmx_Val_GroupByChannel,zeroVoltages,NULL,NULL)); Sleep(500); DAQmxStopTask(motorTaskHandle); DAQmxStopTask(motorEnableHandle); isEnable = TRUE; Error: if( DAQmxFailed(error) ) { DAQmxGetExtendedErrorInfo(errBuff,2048); DAQmxStopTask(motorTaskHandle); DAQmxClearTask(motorTaskHandle); DAQmxStopTask(motorEnableHandle); DAQmxClearTask(motorEnableHandle); printf("DAQmx Error: %s\n",errBuff); printf("Motor enable Error\n"); } return 0; }
void DAQManager::motorAdvance(){ uInt32 data; int32 written; data = states[stateNum]; #ifdef _WIN32 DAQmxWriteDigitalU32(motorTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); stateNum++; if (stateNum == stateCount) stateNum = 0; Sleep(5); #elif __APPLE__ DAQmxBaseWriteDigitalU32(motorTaskHandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel, &data, &written, NULL); stateNum++; if (stateNum == stateCount) stateNum = 0; usleep(5000); #endif }
void DexNiDaqTargets::SetTargetStateInternal( unsigned long state ) { int32 channels_written; DAQmxWriteDigitalU32( taskHandle, 1, true, 1.0, DAQmx_Val_GroupByScanNumber, &state, &channels_written, NULL ); screen_targets->SetTargetStateInternal( state ); }
//Gateway routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //General vars char errMsg[512]; //Read input arguments float64 timeout; bool writeDigitalLines; uInt32 bytesPerChan; int numSampsPerChan; bool32 autoStart; int32 status; TaskHandle taskID, *taskIDPtr; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; mxClassID writeDataClassID = mxGetClassID(prhs[1]); if ((writeDataClassID == mxLOGICAL_CLASS) || (writeDataClassID == mxDOUBLE_CLASS)) writeDigitalLines = true; else writeDigitalLines = false; if (writeDigitalLines) { status = DAQmxGetWriteDigitalLinesBytesPerChan(taskID,&bytesPerChan); //This actually returns the number of bytes required to represent one sample of Channel data if (status) handleDAQmxError(status,"DAQmxGetWriteDigitalLinesBytesPerChan"); } if ((nrhs < 3) || mxIsEmpty(prhs[2])) timeout = DAQmx_Val_WaitInfinitely; else { timeout = (float64) mxGetScalar(prhs[2]); if (mxIsInf(timeout) || (timeout < 0)) timeout = DAQmx_Val_WaitInfinitely; } if ((nrhs < 4) || mxIsEmpty(prhs[3])) { if (writeDigitalLines) autoStart = true; else autoStart = false; } else autoStart = (bool32) mxGetScalar(prhs[3]); mwSize numRows = mxGetM(prhs[1]); if ((nrhs < 5) || mxIsEmpty(prhs[4])) if (writeDigitalLines) { numSampsPerChan = numRows / bytesPerChan; } else numSampsPerChan = numRows; else numSampsPerChan = (int) mxGetScalar(prhs[4]); //Verify correct input length //Write data int32 sampsWritten; switch (writeDataClassID) { case mxUINT32_CLASS: status = DAQmxWriteDigitalU32(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt32*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxUINT16_CLASS: status = DAQmxWriteDigitalU16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt16*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxUINT8_CLASS: status = DAQmxWriteDigitalU8(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt8*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxDOUBLE_CLASS: case mxLOGICAL_CLASS: { if (numRows < (numSampsPerChan * bytesPerChan)) mexErrMsgTxt("Supplied writeData argument must have at least (numSampsPerChan x numBytesPerChannel) rows."); else if (writeDataClassID == mxLOGICAL_CLASS) status = DAQmxWriteDigitalLines(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt8*) mxGetData(prhs[1]), &sampsWritten, NULL); else //mxDOUBLE_CLASS { //Convert DOUBLE data to LOGICAL values double *writeDataRaw = mxGetPr(prhs[1]); mwSize numElements = mxGetNumberOfElements(prhs[1]); uInt8 *writeData = (uInt8 *)mxCalloc(numElements,sizeof(uInt8)); for (unsigned int i=0;i<numElements;i++) { if (writeDataRaw[i] != 0) writeData[i] = 1; } status = DAQmxWriteDigitalLines(taskID, numSampsPerChan, autoStart, timeout, dataLayout, writeData, &sampsWritten, NULL); mxFree(writeData); } } break; default: sprintf_s(errMsg,"Class of supplied writeData argument (%s) is not valid", mxGetClassName(prhs[1])); mexErrMsgTxt(errMsg); } //Handle output arguments if (nlhs > 0) { plhs[0] = mxCreateDoubleScalar(0); double *sampsPerChanWritten = mxGetPr(plhs[0]); if (!status) { //mexPrintf("Successfully wrote %d samples of data\n", sampsWritten); *sampsPerChanWritten = (double)sampsWritten; } else //Write failed handleDAQmxError(status, mexFunctionName()); } }
//Gateway routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //General vars char errMsg[512]; //Read input arguments float64 timeout; //bool dataIsLogicalOrDouble; // For unsigned int data (8, 16, or 32-bit) we call DAQmxWriteDigitalU<whatever>() to // write the data to the buffer. For logical or double data, we call DAQmxWriteDigitalLines(). // For the first, the several channel settings have to be "packed" into a single unsigned int. // For the second, each channel is set individually. // Note that a "channel" in this context is a thing you set up with a single call to the // DAQmxCreateDOChan() function. // That is, a channel can consist of more than one TTL line. // This var is set to true iff the data is logical or double. uInt32 maxLinesPerChannel; int32 numSampsPerChan; // The number of time points to output, aka the number of "scans" bool32 autoStart; int32 status; TaskHandle taskID, *taskIDPtr; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; // Get type and dimensions of data array mxClassID writeDataClassID = mxGetClassID(prhs[1]); bool dataIsLogicalOrDouble = ((writeDataClassID == mxLOGICAL_CLASS) || (writeDataClassID == mxDOUBLE_CLASS)) ; mwSize numRows = mxGetM(prhs[1]); mwSize numCols = mxGetN(prhs[1]); // Determine the timeout if ((nrhs < 3) || mxIsEmpty(prhs[2])) timeout = DAQmx_Val_WaitInfinitely; else { timeout = (float64) mxGetScalar(prhs[2]); if (mxIsInf(timeout) || (timeout < 0)) timeout = DAQmx_Val_WaitInfinitely; } // Determine whether to start automatically or not if ((nrhs < 4) || mxIsEmpty(prhs[3])) { int32 sampleTimingType; status = DAQmxGetSampTimingType(taskID, &sampleTimingType) ; if (status) handleDAQmxError(status,"DAQmxSetSampTimingType"); if ( sampleTimingType == DAQmx_Val_OnDemand ) { // The task is using on-demand timing, so we want the // new values to be immediately output. (And trying to call // DAQmxWriteDigitalLines() for an on-demand task, with autoStart set to false, // will error anyway. autoStart = (bool32) true; } else { autoStart = (bool32) false; } } else { autoStart = (bool32) mxGetScalar(prhs[3]); } // Determine the number of scans (time points) to write out if ((nrhs < 5) || mxIsEmpty(prhs[4])) { if (dataIsLogicalOrDouble) { status = DAQmxGetWriteDigitalLinesBytesPerChan(taskID,&maxLinesPerChannel); // maxLinesPerChannel is maximum number of lines per channel. // Each DO "channel" can consist of multiple DO lines. (A channel is the thing created with // a call to DAQmxCreateDOChan().) So this returns the maximum number of lines per channel, // across all the channels in the task. When you call DAQmxWriteDigitalLines(), the data must consist // of (number of scans) x (number of channels) x maxLinesPerChannel uint8 elements. If a particular channel has fewer lines // than the max number, the extra ones are ignored. if (status) handleDAQmxError(status,"DAQmxGetWriteDigitalLinesBytesPerChan"); numSampsPerChan = (int32) (numRows/maxLinesPerChannel); // this will do an implicit floor } else numSampsPerChan = (int32) numRows; } else { numSampsPerChan = (int32) mxGetScalar(prhs[4]); } // Verify that the data contains the right number of columns uInt32 numberOfChannels; status = DAQmxGetTaskNumChans(taskID, &numberOfChannels) ; if (status) handleDAQmxError(status,"DAQmxGetTaskNumChans"); if (numCols != numberOfChannels ) { mexErrMsgTxt("Supplied writeData argument must have as many columns as there are channels in the task."); } // Verify that the data contains enough rows that we won't read off the end of it. // Note that for logical or double data, the different lines for each channel must be stored in the *rows*. // So for each time point, there's a maxLinesPerChannel x nChannels submatrix for that time point. int numberOfRowsNeededPerScan = (dataIsLogicalOrDouble ? maxLinesPerChannel : 1) ; int minNumberOfRowsNeeded = numberOfRowsNeededPerScan * numSampsPerChan ; if (numRows < minNumberOfRowsNeeded ) { mexErrMsgTxt("Supplied writeData argument does not have enough rows."); } //Write data int32 scansWritten; switch (writeDataClassID) { case mxUINT32_CLASS: status = DAQmxWriteDigitalU32(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt32*) mxGetData(prhs[1]), &scansWritten, NULL); break; case mxUINT16_CLASS: status = DAQmxWriteDigitalU16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt16*) mxGetData(prhs[1]), &scansWritten, NULL); break; case mxUINT8_CLASS: status = DAQmxWriteDigitalU8(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt8*) mxGetData(prhs[1]), &scansWritten, NULL); break; case mxLOGICAL_CLASS: status = DAQmxWriteDigitalLines(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt8*) mxGetData(prhs[1]), &scansWritten, NULL); break; case mxDOUBLE_CLASS: { //Convert DOUBLE data to LOGICAL values double *writeDataRaw = mxGetPr(prhs[1]); mwSize numElements = mxGetNumberOfElements(prhs[1]); uInt8 *writeData = (uInt8 *)mxCalloc(numElements,sizeof(uInt8)); for (unsigned int i=0;i<numElements;i++) { if (writeDataRaw[i] != 0) writeData[i] = 1; } status = DAQmxWriteDigitalLines(taskID, numSampsPerChan, autoStart, timeout, dataLayout, writeData, &scansWritten, NULL); mxFree(writeData); } break; default: sprintf_s(errMsg,"Class of supplied writeData argument (%s) is not valid", mxGetClassName(prhs[1])); mexErrMsgTxt(errMsg); } // If an error occured at some point during writing, deal with that if (status) handleDAQmxError(status, mexFunctionName()); // Handle output arguments, if needed if (nlhs > 0) { plhs[0] = mxCreateDoubleScalar(0); double * sampsPerChanWritten = mxGetPr(plhs[0]); *sampsPerChanWritten = (double)scansWritten ; } }