int NationalInstrumentsDAQ::writeAO(float64 *data) { int32 written, N = _config->ao_samples_per_waveform(); #if 0 { uInt32 nchan; char buf[1024], name[1024]; memset(buf ,0,sizeof(buf )); memset(name,0,sizeof(name)); DAQWRN( DAQmxGetTaskName(_ao.daqtask,name,sizeof(name)) ); DAQWRN( DAQmxGetTaskNumChans(_ao.daqtask,&nchan) ); DAQWRN( DAQmxGetTaskChannels(_ao.daqtask,buf,sizeof(buf)) ); HERE; debug("NI-DAQmx Task (%s) has %d channels"ENDL"\t%s"ENDL, name, nchan, buf); while(nchan--) { DAQWRN( DAQmxGetNthTaskChannel(_ao.daqtask, 1+nchan, buf, sizeof(buf)) ); DAQWRN( DAQmxGetPhysicalChanName(_ao.daqtask, buf, buf, sizeof(buf)) ); debug("\t%d:\t%s"ENDL,nchan,buf); } } { FILE *fp = fopen("NationalInstrumentsDAQ_writeAO.f64","wb"); fwrite(data,sizeof(f64),3*N,fp); fclose(fp); } #endif DAQJMP( DAQmxWriteAnalogF64(_ao.daqtask, N, 0, // autostart? 1.0, // timeout (s) - to write - 0 causes write to fail if blocked at all DAQmx_Val_GroupByChannel, data, &written, NULL)); Guarded_Assert( written == N ); return 0; // success Error: return 1; // fail }
int32 Tweezers::Degauss(float U, float duration) { clock_t startTime; float freq = 100; int bufferSize = (int)(5000 * duration); float64 *data = new float64[bufferSize]; // fill buffer with data for(int i=0;i<bufferSize;i++) { float64 amp = U * (1 - (double)i/(double)(bufferSize-1)); data[i] = amp * cos( 2.0 * PI * freq * (double)i/5000.0); // degauss Srate must be independent of run!! } DAQmxErrRtn(DAQmxClearTask(AOtaskHandle)); // create and setup analog task DAQmxErrRtn(DAQmxCreateTask("AO",&AOtaskHandle)); DAQmxErrRtn(DAQmxCreateAOVoltageChan(AOtaskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL)); // configure sample clock for buffered write DAQmxErrRtn(DAQmxCfgSampClkTiming(AOtaskHandle,"",5000,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,(int)(duration*5000))); // write data and start task DAQmxErrRtn(DAQmxWriteAnalogF64(AOtaskHandle,bufferSize,0,10.0,DAQmx_Val_GroupByChannel,data,&written,NULL)); startTime = clock(); DAQmxErrRtn(DAQmxStartTask(AOtaskHandle)); while(!done) { DAQmxErrRtn(DAQmxIsTaskDone(AOtaskHandle,&done)); if (!done) Sleep(100); } done = false; DAQmxErrRtn(DAQmxStopTask(AOtaskHandle)); residual = 0.0; delete data; }
int32 Tweezers::SetCurrent(float current) { // init output data array float64 out_data[1]; out_data[0] = current; // setup HTSP timing and deactivate onboard memory DAQmxErrRtn(DAQmxCfgSampClkTiming(AOtaskHandle,"",Srate_HTSP,DAQmx_Val_Rising,DAQmx_Val_HWTimedSinglePoint,1)); // start task DAQmxErrRtn(DAQmxStartTask(AOtaskHandle)); // write single sample DAQmxErrRtn(DAQmxWriteAnalogF64(AOtaskHandle,1,true,-1,DAQmx_Val_GroupByChannel,out_data,&written,NULL)); // stop task DAQmxErrRtn(DAQmxStopTask(AOtaskHandle)); residual = (abs(current) > abs(residual) ? current : residual); }
//Gateway routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { TaskHandle task,task2; float64 sampleRate = 100000; float64 acqTime = 5; uInt64 numSamples = (uInt64) sampleRate * acqTime; char chanName[128]; int32 sampsWritten; //Create the task DAQmxCreateTask("",&task); DAQmxCreateTask("",&task2); //Add AI channels to task DAQmxCreateAIVoltageChan(task, "Dev1/ai0:2", "ScanImageAcq", -1, -1, 1, DAQmx_Val_Volts, NULL); DAQmxCreateAOVoltageChan(task2, "Dev1/ao0:2", "ScanImageControl", -1, 1, DAQmx_Val_Volts, NULL); //Configure task timing DAQmxCfgSampClkTiming(task, NULL, 100000, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, numSamples); DAQmxCfgSampClkTiming(task2, NULL, 100000, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, numSamples); //Configure some task properties for (int i=0; i<2; i++) { sprintf_s(chanName, "Dev1/ai%d", i); DAQmxSetAIMax(task, chanName, 10); DAQmxSetAIMax(task, chanName, -10); } //Write some data DAQmxWriteAnalogF64(task, (int32) numSamples, false, -1, DAQmx_Val_GroupByChannel, outputData, &sampsWritten, NULL); //Screw it DAQmxClearTask(task); }
/****************************************************************************** ** ** Fonction de démarage de la tache d'alimentation du moteur ** La vitesse du moteur est défini à 50% ** ******************************************************************************/ int NI6211::startMotor() { int error=0; taskVOut = new TaskHandle; float64 data[1] = {0}; /*------ DAQmx Configure Code ------*/ DAQmxErrChk (DAQmxCreateTask("",taskVOut)); DAQmxErrChk (DAQmxCreateAOVoltageChan(*taskVOut,"/Equilibreuse/ao0","",-10.0,10.0,DAQmx_Val_Volts,"")); /*------ DAQmx Start Code ------*/ DAQmxErrChk (DAQmxStartTask(*taskVOut)); /*------ DAQmx Write Code ------*/ DAQmxErrChk (DAQmxWriteAnalogF64(*taskVOut,1,1,-1,DAQmx_Val_GroupByChannel,data,NULL,NULL)); Erreur: checkError(error); return 0; }
int StartStartle(void) { int i=0; int32 written; /*********************************************/ // DAQmx Write Code /*********************************************/ DAQmxWriteAnalogF64(startleDaqHandle,400,0,10.0,DAQmx_Val_GroupByChannel,gStartleData,&written,NULL); /*********************************************/ // DAQmx Start Code /*********************************************/ DAQmxStartTask(startleDaqHandle); /*********************************************/ // DAQmx Wait Code /*********************************************/ //DAQmxWaitUntilTaskDone(startleDaqHandle,10.0); return 0; }
//Gateway routine //sampsPerChanWritten = writeAnalogData(task, writeData, timeout, autoStart, numSampsPerChan) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //General vars char errMsg[512]; //Read input arguments float64 timeout; int numSampsPerChan; bool32 autoStart; TaskHandle taskID, *taskIDPtr; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; if ((nrhs < 3) || mxIsEmpty(prhs[2])) timeout = 10.0; else { timeout = (float64) mxGetScalar(prhs[2]); if (mxIsInf(timeout)) timeout = DAQmx_Val_WaitInfinitely; } if ((nrhs < 4) || mxIsEmpty(prhs[3])) { int32 sampTimingType = 0; int32 status = DAQmxGetSampTimingType(taskID,&sampTimingType); if (status!=0) { mexErrMsgTxt("Failed to get sample timing type from DAQmx."); } autoStart = (sampTimingType==DAQmx_Val_OnDemand); } else autoStart = (bool32) mxGetScalar(prhs[3]); size_t numRows = mxGetM(prhs[1]); if ((nrhs < 5) || mxIsEmpty(prhs[4])) numSampsPerChan = numRows; else numSampsPerChan = (int) mxGetScalar(prhs[4]); //Verify correct input length //Write data int32 sampsWritten; int32 status; switch (mxGetClassID(prhs[1])) { case mxUINT16_CLASS: status = DAQmxWriteBinaryU16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt16*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxINT16_CLASS: status = DAQmxWriteBinaryI16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (int16*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxDOUBLE_CLASS: status = DAQmxWriteAnalogF64(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (float64*) mxGetData(prhs[1]), &sampsWritten, NULL); break; default: sprintf_s(errMsg,"Class of supplied writeData argument (%s) is not valid", mxGetClassName(prhs[1])); mexErrMsgTxt(errMsg); } //Handle output arguments and errors if (!status) { if (nlhs > 0) { plhs[0] = mxCreateDoubleScalar(0); double *sampsPerChanWritten = mxGetPr(plhs[0]); } //mexPrintf("Successfully wrote %d samples of data\n", sampsWritten); } else //Write failed handleDAQmxError(status, mexFunctionName()); }
int main() { //////////////////////////////// // Program settings /////////////////////////////// float stageStepSize = 5.0/2; // in um int stepTotalX = 1600;//2000/stageStepSize; int stepTotalY = 600;//2000/stageStepSize; int stepX = 1; int stepY = 1; int stageLocation[2] = { 0, 0 }; int16 *stageLocationSave[2]; // Ensure that this is made large enough for some spillover int stageCount = 0; stageLocationSave[0] = new int16[NUMSTAGELOCATIONS]; stageLocationSave[1] = new int16[NUMSTAGELOCATIONS]; // Motors off XON(0); YON(0); //////////////////////////////// // Initialize DAQ settings /////////////////////////////// TaskHandle directionX = 0; TaskHandle directionY = 0; DAQmxCreateTask("XDir", &directionX); DAQmxCreateTask("YDir", &directionY); DAQmxCreateAOVoltageChan(directionX, "Dev1/ao1", "XDir", 0.0, 5.0, DAQmx_Val_Volts, NULL); // X Direction DAQmxCreateAOVoltageChan(directionY, "Dev1/ao0", "YDir", 0.0, 5.0, DAQmx_Val_Volts, NULL); // Y Direction float64 fiveVoltOut[2] = { 5.0, 5.0 }; // 5.0 V float64 zeroVoltOut[2] = { 0.0, 0.0 }; // 0.0 V //Must be 2 bits uInt8 outClock[2] = { 0 , 1 }; uInt8 onSig[2] = { 1, 1 }; //////////////////////////////// // Initialize Gage card /////////////////////////////// if (initializeGage(stageStepSize)) { fprintf(stdout, ("Error initializing Gage card, please check settings\n\n")); getchar(); return -1; } fprintf(stdout, ("Gage card sucessfully initialized.\n\n")); //////////////////////////////// // Initial settings checks /////////////////////////////// // Check program buffer sizes int currBufferSize = checkBufferSize(); int totalNumStageMoves = (stepTotalX / stepX)*(stepTotalY / stepY); if (currBufferSize >= totalNumStageMoves && NUMSTAGELOCATIONS >= totalNumStageMoves) { fprintf(stdout, ("Buffer sizes appear correct.\n\n")); } else { fprintf(stdout, ("Buffer size is not set correctly. Stage locations (%d) and segment count (%d) must be greater than %d.\n\n"), (int)NUMSTAGELOCATIONS, currBufferSize, totalNumStageMoves); getchar(); return -1; } //////////////////////////////// // Print scan settings /////////////////////////////// fprintf(stdout, ("\n\n Scan Settings\n---------------\n\n")); fprintf(stdout, ("X stage step size: %3.2f um\nY stage step size: %3.2f um\n"), (float)stepX*stageStepSize, (float)stepY*stageStepSize); fprintf(stdout, ("X range: %3.2f mm\nY range: %3.2f mm\n\n"), (float)stepTotalX * stageStepSize / 1000.0, (float)stepTotalY * stageStepSize / 1000.0); //fprintf(stdout, ("Total stage moves: %d\nStage clock speed: %d Hz\n\n---------------\n\n"), (stepTotalX / stepX)*(stepTotalY / stepY),getStageClockSpeed()); fprintf(stdout, ("Total stage moves: %d\nStage clock speed: %d Hz\n"), (stepTotalX / stepX)*(stepTotalY / stepY), getStageClockSpeed()); fprintf(stdout, ("Set trigger holdoff bettween %d us and %d us\n\n"), (int)(1.0 / (float)getStageClockSpeed()*1e6), (int)(2.0 / (float)getStageClockSpeed()*1e6)); fprintf(stdout, ("---------------\n\n")); //////////////////////////////// // Prep for scan /////////////////////////////// // Ready to start scan fprintf(stdout, ("Ensure stage is centered.\nPress any key to start scan.\n\n")); getchar(); fprintf(stdout, ("Moving stage to start location.\n\n")); // Motors on XON(1); YON(1); // Scan variables int steps; //int gageCollectStatus; int XDir = 1; int saveCount = 1; // Move to start position steps = stepTotalX / 2; DAQmxWriteAnalogF64(directionX, 1, 1, 0.0, DAQmx_Val_GroupByChannel, zeroVoltOut, NULL, NULL); // dir moveXStage(steps, outClock); stageLocation[0] -= steps; steps = stepTotalY / 2; DAQmxWriteAnalogF64(directionY, 1, 1, 0.0, DAQmx_Val_GroupByChannel, zeroVoltOut, NULL, NULL); // dir moveYStage(steps, outClock); // Move stageLocation[1] -= steps; //////////////////////////////// // Scan /////////////////////////////// moveXStage(1, onSig); // hold on // Start data collection if (collectData()) { fprintf(stdout, ("Data Collection Failed")); getchar(); return (-1); } // Scan along Y for (int countY = 0; countY < stepTotalY; countY += stepY) { if (countY != 0) { // Step Y DAQmxWriteAnalogF64(directionY, 1, 1, 0.0, DAQmx_Val_GroupByChannel, fiveVoltOut, NULL, NULL); // dir moveYStage(stepY, outClock); // Move-- stageLocation[1] += stepY; } if (countY > 0) { _ftprintf(stdout, ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b")); } _ftprintf(stdout, _T("%04.0f um remaining in Y"), (float)(stepTotalY - countY) * stageStepSize); // Scan along X if (XDir == 1) { DAQmxWriteAnalogF64(directionX, 1, 1, 0.0, DAQmx_Val_GroupByChannel, fiveVoltOut, NULL, NULL); // dir stageLocation[0] += stepTotalX; } else { DAQmxWriteAnalogF64(directionX, 1, 1, 0.0, DAQmx_Val_GroupByChannel, zeroVoltOut, NULL, NULL); // dir stageLocation[0] -= stepTotalX; } moveXStage(stepTotalX, outClock); // Move // Save stage data and change direction if (XDir == 1) { XDir = 0; } else { XDir = 1; } } _ftprintf(stdout, _T("\nScan complete. Returning to start position.\n\n")); // Move stage to center (0,0) if (stageLocation[0] > 0){ steps = stageLocation[0]; DAQmxWriteAnalogF64(directionX, 1, 1, 0.0, DAQmx_Val_GroupByChannel, zeroVoltOut, NULL, NULL); // dir moveXStage(steps, outClock); // Move stageLocation[0] -= steps; } else{ steps = -stageLocation[0]; DAQmxWriteAnalogF64(directionX, 1, 1, 0.0, DAQmx_Val_GroupByChannel, fiveVoltOut, NULL, NULL); // dir moveXStage(steps, outClock); // Move stageLocation[0] += steps; } if (stageLocation[1] > 0){ steps = stageLocation[1]; DAQmxWriteAnalogF64(directionY, 1, 1, 0.0, DAQmx_Val_GroupByChannel, zeroVoltOut, NULL, NULL); // dir moveYStage(steps, outClock); // Move stageLocation[1] -= steps; } else{ steps = -stageLocation[1]; DAQmxWriteAnalogF64(directionY, 1, 1, 0.0, DAQmx_Val_GroupByChannel, fiveVoltOut, NULL, NULL); // dir moveYStage(steps, outClock); // Move stageLocation[1] += steps; } moveXStage(2, onSig); // Move // Motors off XON(0); YON(0); //moveXStage(4, onSig); // hold on // Stage stage data int countX = 0; int countY = 0; XDir = 1; for (countY = 0; countY < stepTotalY; countY += stepY) { if (countY != 0) { stageLocationSave[0][stageCount] = countX; stageLocationSave[1][stageCount++] = countY; } if (XDir == 1) { for (countX = 0; countX < stepTotalX; countX += stepX) { stageLocationSave[0][stageCount] = countX; stageLocationSave[1][stageCount++] = countY; } XDir = 0; } else { for (countX = stepTotalX-1; countX > -1; countX -= stepX) { stageLocationSave[0][stageCount] = countX; stageLocationSave[1][stageCount++] = countY; } XDir = 1; } } // Check if aquisition is completed checkScanComplete(); // Transfer and save data int nSaveError = saveGageData(); if (nSaveError) { fprintf(stdout, ("Data Save Failed")); getchar(); return (-1); } // Save stage data TCHAR StageFileName[MAX_PATH]; FILE *fidStage; // Open Save files int nCount = 0; while (1) { nCount++; _stprintf(StageFileName, _T("E:\\GageData\\MechStageDataScan%d.txt"), nCount); fidStage = fopen(StageFileName, "r"); if (fidStage) { fclose(fidStage); } else { fidStage = fopen(StageFileName, "w"); break; } } //_stprintf(StageFileName, _T("E:\\GageData\\MechStageData.txt")); //fidStage = fopen(StageFileName, "w"); for (int n = 0; n < stageCount; n++) { _ftprintf(fidStage, _T("%d %d\n"), stageLocationSave[0][n], stageLocationSave[1][n]); // print peakData } fclose(fidStage); fidStage = NULL; delete stageLocationSave[0]; delete stageLocationSave[1]; return 0; }
void ScanThreadLinear::InitializeSyncAndScan(void) { //CLEAR TASKS DAQmxClearTask(taskClock); DAQmxClearTask(taskTrig); DAQmxClearTask(taskTrA); DAQmxClearTask(taskAnalog); Samps = globalOptions->IMAGEHEIGHT+NumPtsDw; LineRate = Samps*FrameRate; //CREATE TASKS DAQmxCreateTask("",&taskAnalog); DAQmxCreateTask("",&taskTrig); DAQmxCreateTask("",&taskTrA); DAQmxCreateTask("",&taskClock); /************************* CLOCK SOURCE *************************/ //CREATE INTERNAL CLOCK SOURCE DAQmxCreateCOPulseChanFreq(taskClock, "Dev1/ctr0", "", DAQmx_Val_Hz, DAQmx_Val_Low, __DDELAY, FrameRate, .2); /************************* DIGITAL PULSE TRAIN *************************/ //CREATE DIGITAL LINE DAQmxCreateDOChan(taskTrig,"Dev1/port0/line0","",DAQmx_Val_ChanPerLine); //SET TIMING AND STATE CLOCK SOURCE //Clock source is based off the analog sample clock DAQmxCfgSampClkTiming(taskTrig,"ao/SampleClock",FrameRate*Samps, DAQmx_Val_Rising,DAQmx_Val_ContSamps,Samps); /************************* ANALOG SAW TOOTH *************************/ //CREATE ANALOG CHANNEL DAQmxCreateAOVoltageChan(taskAnalog,"Dev1/ao0", "",-10,10.0,DAQmx_Val_Volts,NULL); DAQmxCreateAOVoltageChan(taskAnalog,"Dev1/ao1", "",-10,10.0,DAQmx_Val_Volts,NULL); //SET TIMING DAQmxCfgSampClkTiming(taskAnalog,"",FrameRate*Samps, DAQmx_Val_Rising,DAQmx_Val_ContSamps,Samps); //GET TERMINAL NAME OF THE TRIGGER SOURCE GetTerminalNameWithDevPrefix(taskTrig, "Ctr0InternalOutput",trigName); //TRIGGER THE ANALOG DATA BASED OFF INTERNAL TRIGGER (CLOCK SOURCE) DAQmxCfgDigEdgeStartTrig(taskAnalog,trigName,DAQmx_Val_Rising); if (globalOptions->bVolumeScan == false) { GenSawTooth(Samps,XScanVolts_mV,XScanOffset_mV,ScanBuff); for (int i = 0; i< Samps; i++) VolBuff[i] = ScanBuff[i]; for (int i = Samps; i < 2*Samps; i++) VolBuff[i] = YScanOffset_mV/1000; DAQmxWriteAnalogF64(taskAnalog, Samps, false ,10 ,DAQmx_Val_GroupByChannel, VolBuff,NULL,NULL); //GENERATE PULSE TRAIN TO TRIGGER CAMERA GenPulseTrain(Samps,digiBuff); DAQmxWriteDigitalLines(taskTrig,Samps,false,10.0,DAQmx_Val_GroupByChannel,digiBuff,NULL,NULL); } else { int frameCount; GenSawTooth(Samps,XScanVolts_mV,XScanOffset_mV,ScanBuff); for (frameCount = 0; frameCount < globalOptions->NumFramesPerVol; frameCount++) { for (int i = 0; i< Samps; i++) VolumeBuff[i+frameCount*Samps] = ScanBuff[i]; } GenStairCase(Samps,globalOptions->NumFramesPerVol,YScanVolts_mV, YScanOffset_mV, tempBuff); for (int i = 0; i < Samps*globalOptions->NumFramesPerVol; i++) VolumeBuff[i + Samps*globalOptions->NumFramesPerVol] = tempBuff[i]; DAQmxWriteAnalogF64(taskAnalog, Samps*globalOptions->NumFramesPerVol, false ,10 ,DAQmx_Val_GroupByChannel, VolumeBuff,NULL,NULL); //GENERATE PULSE TRAIN TO TRIGGER CAMERA for (int frameCount = 0; frameCount < globalOptions->NumFramesPerVol; frameCount++) { GenPulseTrain(Samps,digiBuff); for (int i = 0; i< Samps; i++) digiVolBuff[i+frameCount*Samps] = digiBuff[i]; } DAQmxWriteDigitalLines(taskTrig,Samps*globalOptions->NumFramesPerVol,false,10.0,DAQmx_Val_GroupByChannel,digiVolBuff,NULL,NULL); } //GENERATE PULSE TRAIN TO TRIGGER CAMERA DAQmxCreateCOPulseChanFreq(taskTrA,"Dev1/ctr1","",DAQmx_Val_Hz,DAQmx_Val_Low,0.0,LineRate,0.2); DAQmxCfgImplicitTiming(taskTrA,DAQmx_Val_FiniteSamps,globalOptions->IMAGEHEIGHT); DAQmxCfgDigEdgeStartTrig(taskTrA,"/Dev1/PFI4",DAQmx_Val_Rising); DAQmxSetStartTrigRetriggerable(taskTrA, 1); DAQmxConnectTerms ("/Dev1/Ctr1InternalOutput", "/Dev1/RTSI0", DAQmx_Val_DoNotInvertPolarity); //START TASKS //IMPORTANT - Need to arm analog task first to make sure that the digital and analog waveforms are in sync DAQmxStartTask(taskAnalog); DAQmxStartTask(taskTrA); DAQmxStartTask(taskTrig); DAQmxStartTask(taskClock); }
void motorControl::controlLoop(void) { int32 error=0; float cotexDrive = 0.0; bool keepReading=TRUE; bool32 isLate = {0}; double tick=0.0,tock=0.0; float64 motorCommand[3]={0.0,0.0,0.0},errorForce[2]= {0.0,0.0},integral[2]={0.0,0.0},EMG={0.0}; char errBuff[2048]={'\0'}; FILE *dataFile; time_t t = time(NULL); tm* timePtr = localtime(&t); char fileName[200]; char dataSample[600]=""; char dataTemp[100]=""; sprintf_s( fileName, "C:\\data\\realTimeData%4d_%02d_%02d_%02d_%02d_%02d.txt", timePtr->tm_year+1900, timePtr->tm_mon+1, timePtr->tm_mday, timePtr->tm_hour, timePtr->tm_min, timePtr->tm_sec ); dataFile = fopen(fileName,"w"); //fprintf(dataFile,"Time, Load Cell1, Load Cell2, Motor Command1, Motor Command2, Length 1, Length2, Velocity1, Velocity2, EMG1, EMG2, is sample missed\n"); //fprintf(dataFile,"Time, Load Cell1, Load Cell2, Length 1, Length2, Velocity1, Velocity2, EMG1, EMG2, GammaStat, GammaDyn, is sample missed\n"); //fprintf(dataFile,"Time, Load Cell1, Load Cell2, Length 1, Length2, motorRef1, motorRef2, spindleIa1, spindleIa2, spindleII1, spindleII2, EMG1, EMG2, GammaStat, GammaDyn, is sample missed\n"); //fprintf(dataFile,"Time, Length 1, Length2, EMG1, EMG2, GammaStat, GammaDyn, is sample missed\n"); fprintf(dataFile,header); DAQmxErrChk (DAQmxStartTask(loadCelltaskHandle)); DAQmxErrChk (DAQmxStartTask(motorTaskHandle)); DAQmxErrChk (DAQmxStartTask(encodertaskHandle[0])); DAQmxErrChk (DAQmxStartTask(encodertaskHandle[1])); timeData.resetTimer(); tick = timeData.getCurrentTime(); float64 goffsetLoadCell[2]={0}; int expProtocol = 0; int expProtocoAdvance = 0; while(live) { WaitForSingleObject(hIOMutex, INFINITE); //desire Forced, muscle Length, muscle Velocity PIPES should be read here DAQmxErrChk(DAQmxWaitForNextSampleClock(loadCelltaskHandle,10, &isLate)); DAQmxErrChk (DAQmxReadAnalogF64(loadCelltaskHandle,-1,10.0,DAQmx_Val_GroupByScanNumber,loadCellData,2,NULL,NULL)); DAQmxErrChk (DAQmxWriteAnalogF64(motorTaskHandle,1,FALSE,10,DAQmx_Val_GroupByChannel,motorCommand,NULL,NULL)); DAQmxErrChk (DAQmxReadCounterF64(encodertaskHandle[0],1,10.0,encoderData1,1,NULL,0)); DAQmxErrChk (DAQmxReadCounterF64(encodertaskHandle[1],1,10.0,encoderData2,1,NULL,0)); if (dataAcquisitionFlag[1]){ EMG = muscleEMG[0]; if (EMG > 6) EMG = 6; if (EMG < -6) EMG = -6; } else EMG = 0; tock = timeData.getCurrentTime(); if (resetMuscleLength) { muscleLengthOffset[0] = 2 * PI * shaftRadius * encoderData1[0] / 365; muscleLengthOffset[1] = 2 * PI * shaftRadius * encoderData2[0] / 365; resetMuscleLength = FALSE; } muscleLength[0] = ((2 * PI * shaftRadius * encoderData1[0] / 365) - muscleLengthOffset[0]); //muscleLength[0] = 0.95 + (muscleLength[0] + 0.0059)*24.7178; //muscleLength[0] = 0.95 + (muscleLength[0] + 0.0059)*40; muscleLength[0] = encoderBias[0] + muscleLength[0] *encoderGain[0]; muscleLength[1] = ((2 * PI * shaftRadius * encoderData2[0] / 365) - muscleLengthOffset[1]); //muscleLength[1] = 1 + (muscleLength[1] - 0.0058)*30 + 0.5; //muscleLength[1] = 0.95 + (muscleLength[1] - 0.0058)*24.4399; muscleLength[1] = encoderBias[1] + muscleLength[1] *encoderGain[1]; muscleVel[0] = (muscleLength[0] - muscleLengthPreviousTick[0]) / (tock - tick); muscleVel[1] = (muscleLength[1] - muscleLengthPreviousTick[1]) / (tock - tick); muscleLengthPreviousTick[0] = muscleLength[0]; muscleLengthPreviousTick[1] = muscleLength[1]; loadCellData[0] = (loadCellData[0] * loadCellScale1) - loadCellOffset1; loadCellData[1] = (loadCellData[1] * loadCellScale2) - loadCellOffset2; errorForce[0] = motorRef[0] - loadCellData[0]; errorForce[1] = motorRef[1] - loadCellData[1]; integral[0] = integral[0] + errorForce[0] * (tock - tick); integral[1] = integral[1] + errorForce[1] * (tock - tick); motorCommand[0] = integral[0] * I; motorCommand[1] = integral[1] * I; motorCommand[2] = EMG; if (motorCommand[0] > motorMaxVoltage) motorCommand[0] = motorMaxVoltage; if (motorCommand[0] < motorMinVoltage) motorCommand[0] = motorMinVoltage; if (motorCommand[1] > motorMaxVoltage) motorCommand[1] = motorMaxVoltage; if (motorCommand[1] < motorMinVoltage) motorCommand[1] = motorMinVoltage; printf("F1: %+6.2f; F2: %+6.2f;L1: %+6.2f; L2: %+6.2f;, Dyn: %d, Sta: %d, \r",loadCellData[0],loadCellData[1],muscleLength[0],muscleLength[1],gammaDynamic1, gammaStatic1); ReleaseMutex( hIOMutex); //fprintf(dataFile,"%.3f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%d\n",tock,loadCellData[0],loadCellData[1],motorRef[0],motorRef[1], muscleLength[0], muscleLength[1], muscleVel[0],muscleVel[1], muscleEMG[0], muscleEMG[1], isLate); //fprintf(dataFile,"%.3f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%d,%d,%d\n",tock,loadCellData[0],loadCellData[1], muscleLength[0], muscleLength[1], muscleVel[0],muscleVel[1], muscleEMG[0], muscleEMG[1], gammaStatic, gammaDynamic, isLate); //fprintf(dataFile,"%.3f,%.6f,%.6f,%.6f,%.6f,%d,%d,%d\n",tock, muscleLength[0], muscleLength[1], muscleEMG[0], muscleEMG[1], gammaStatic, gammaDynamic, isLate); sprintf(dataSample,"%.3f,%d,%.6f,%.6f,%.6f,%.6f",tock,expProtocol,muscleLength[0], muscleLength[1], loadCellData[0],loadCellData[1]); if (dataAcquisitionFlag[0]){ sprintf(dataTemp,",%.6f,%.6f",motorRef[0],motorRef[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[1]){ sprintf(dataTemp,",%.6f,%.6f",muscleEMG[0], muscleEMG[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[2]){ sprintf(dataTemp,",%.6f,%.6f",spindleIa[0], spindleIa[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[3]){ sprintf(dataTemp,",%.6f,%.6f",spindleII[0], spindleII[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[4]){ sprintf(dataTemp,",%d,%d",muscleSpikeCount[0], muscleSpikeCount[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[5]){ sprintf(dataTemp,",%u,%u",raster_MN_1[0], raster_MN_1[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[6]){ sprintf(dataTemp,",%u,%u",raster_MN_2[0], raster_MN_2[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[7]){ sprintf(dataTemp,",%u,%u",raster_MN_3[0], raster_MN_3[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[8]){ sprintf(dataTemp,",%u,%u",raster_MN_4[0], raster_MN_4[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[9]){ sprintf(dataTemp,",%u,%u",raster_MN_5[0], raster_MN_5[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[10]){ sprintf(dataTemp,",%u,%u",raster_MN_6[0], raster_MN_6[1]); strcat (dataSample, dataTemp); } if (dataAcquisitionFlag[11]){ cortexDrive[0] = max((cortexVoluntaryAmp -0) * sin (2 * 3.1416 * cortexVoluntaryFreq * tick), 0); cortexDrive[1] = max((cortexVoluntaryAmp -0) * sin (2 * 3.1416 * cortexVoluntaryFreq * tick + 3.1416), 0); } //sprintf(dataTemp,",%d,%d,%d,%d,%.3f,%.3f,%d\n",gammaStatic1, gammaDynamic1, gammaStatic2, gammaDynamic2, cortexDrive[0], cortexDrive[1],newTrial); sprintf(dataTemp,"\n"); if (trialTrigger == 1){ expProtocoAdvance = 1; trialTrigger = 0; } if (trialTrigger == 2){ expProtocoAdvance = 10; trialTrigger = 0; } if (trialTrigger == 3){ expProtocoAdvance = 11; trialTrigger = 0; } expProtocol = 0; switch(expProtocoAdvance){ case 1: expProtocol = -1000; expProtocoAdvance = 2; break; case 2: expProtocol = gammaDynamic1; expProtocoAdvance = 3; break; case 3: expProtocol = gammaStatic1; expProtocoAdvance = 4; break; case 4: expProtocol = cortexDrive[0]; expProtocoAdvance = 5; break; case 5: expProtocol = gammaDynamic2; expProtocoAdvance = 6; break; case 6: expProtocol = gammaStatic2; expProtocoAdvance = 7; break; case 7: expProtocol = cortexDrive[1]; expProtocoAdvance = 8; break; case 8: expProtocol = angle; expProtocoAdvance = 9; break; case 9: expProtocol = velocity; expProtocoAdvance = 0; break; case 10: expProtocol = -1; expProtocoAdvance = 0; break; case 11: expProtocol = -2; expProtocoAdvance = 0; break; } strcat (dataSample, dataTemp); fprintf(dataFile,dataSample); tick = timeData.getCurrentTime(); } isControlling = FALSE; DAQmxStopTask(motorTaskHandle); fclose(dataFile); Error: if( DAQmxFailed(error) ) { DAQmxGetExtendedErrorInfo(errBuff,2048); /*********************************************/ // DAQmx Stop Code /*********************************************/ DAQmxStopTask(loadCelltaskHandle); DAQmxClearTask(loadCelltaskHandle); DAQmxStopTask(encodertaskHandle); DAQmxClearTask(encodertaskHandle); DAQmxStopTask(motorTaskHandle); DAQmxClearTask(motorTaskHandle); DAQmxStopTask(motorEnableHandle); DAQmxClearTask(motorEnableHandle); printf("DAQmx Error: %s\n",errBuff); printf("Motor control Error\n"); } }
int _tmain(int argc, _TCHAR* argv[]) { TaskHandle task; int acqTime = 6; float64 sampleRate = 500000.0; float64 linePeriod = .002; int lineSamples = (int)(linePeriod * sampleRate); int numLines = (int) (acqTime / (lineSamples/sampleRate)); int acqSamples = numLines * lineSamples; int32 sampsWritten; bool32 taskDone; //Create the task DAQmxCreateTask("a task", &task); //Add AO channels DAQmxCreateAOVoltageChan(task, "Dev1/ao0", "", -10, 10, DAQmx_Val_Volts, NULL); //Configure timing DAQmxCfgSampClkTiming(task, NULL, sampleRate, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, acqSamples); //Write output data float64 *outputData = (float64*) calloc(acqSamples, sizeof(float64)); for (int i=0;i<numLines;i++) { for (int j=0;j<lineSamples;j++) { outputData[i*lineSamples + j] = ((float64) j/(float64)lineSamples) * 10.0; } } DAQmxWriteAnalogF64(task, acqSamples, false, 10.0, DAQmx_Val_GroupByChannel, outputData, &sampsWritten, NULL); printf("Wrote %d samples of data!\n", sampsWritten); printf("Sample #33: %g\n", outputData[32]); printf("Sample #121: %g\n", outputData[120]); printf("Sample #6032: %g\n", outputData[6031]); //Start Task DAQmxStartTask(task); printf("Started task...\n"); while (true) { DAQmxIsTaskDone(task,&taskDone); if (taskDone) break; else Sleep(1000); } //Clear Task DAQmxClearTask(task); return 0; }
int32 Tweezers::Run(float64* force, float64* indata, void* lpParam) { threadinfo* t = (threadinfo*)lpParam; // init output data array float64 out_data[1]; out_data[0] = 0.0; register int i = 0,j = 0; // # of samples to be generated per cycle register int nofSamples = (int)(t->nofFrames/(*t->cycles)) * (*t->delta)*1E-3 * Srate_HTSP; //cerr<<nofSamples<<" samples\n"; // setup HTSP timing and deactivate onboard memory DAQmxErrRtn(DAQmxCfgSampClkTiming(AOtaskHandle,"OnboardClock",Srate_HTSP,DAQmx_Val_Rising,DAQmx_Val_HWTimedSinglePoint,nofSamples)); DAQmxSetRealTimeConvLateErrorsToWarnings(AOtaskHandle, TRUE); // setup start trigger DAQmxErrRtn(DAQmxCfgDigEdgeStartTrig(AOtaskHandle, "PFI0", DAQmx_Val_Rising)); // setup counter task and start trigger // maybe change trigger to digital line? need to use ContSamps, otherwise limited frame # //DAQmxErrRtn(DAQmxCreateCOPulseChanTime(DOtaskHandle,"Dev1/Ctr0","",DAQmx_Val_Seconds,DAQmx_Val_Low,0,1E-3*(*t->delta)/2,1E-3*(*t->delta/2))); DAQmxErrRtn(DAQmxCfgImplicitTiming(DOtaskHandle, DAQmx_Val_ContSamps, 1)); // setup start trigger DAQmxErrRtn(DAQmxCfgDigEdgeStartTrig(DOtaskHandle, "PFI0", DAQmx_Val_Rising)); // setup analog in task DAQmxErrRtn(DAQmxCfgSampClkTiming(AItaskHandle,"Ctr0Out",100,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,*t->cycles * t->nofFrames)); //DAQmxErrRtn(DAQmxCfgDigEdgeStartTrig(AItaskHandle, "PFI0", DAQmx_Val_Rising)); // start tasks (still waiting for edge trigger from TRtask) DAQmxErrRtn(DAQmxStartTask(DOtaskHandle)); DAQmxErrRtn(DAQmxStartTask(AOtaskHandle)); DAQmxErrRtn(DAQmxStartTask(AItaskHandle)); // precalulate number of loop runs to speed up loop int samps = (nofSamples * (*t->cycles) - 1); // write first sample outside loop, so there is enough time to send the TR start trigger out_data[0] = current(force[0],t->dist); DAQmxErrRtn(DAQmxWriteAnalogF64(AOtaskHandle,1,true,-1,DAQmx_Val_GroupByChannel,out_data,&written,NULL)); // GO! DAQmxErrRtn(DAQmxWriteDigitalLines(TRtaskHandle,1,1,10,DAQmx_Val_GroupByChannel,trigdata[1],&written,NULL)); // 1 kHz sample generation loop while(!(*t->bead_lost && // [email protected]: 05/10/2012 16:16 - dont stop recording if bead is lost in Creep-noint protocol *t->protocol != "Creep-noint" // end of change ) && i < samps) { j = (++i % nofSamples); //cerr<<j<<"\r"; out_data[0] = current(force[j],t->dist); DAQmxErrRtn(DAQmxWaitForNextSampleClock(AOtaskHandle, 1.0, &islate)); DAQmxErrRtn(DAQmxWriteAnalogF64(AOtaskHandle,1,true,-1,DAQmx_Val_GroupByChannel,out_data,&written,NULL)); if(islate) { cerr<<i++<<"\n****** late write - out of sync! *******\n"; *t->bead_lost = TRUE; t->syncerror = TRUE; } } printf("DEBUG: bead_lost(%d) protocol(%s) i(%d) samps(%d)\n", *t->bead_lost, *t->protocol, i, samps); // wait for last sample to be generated DAQmxErrRtn(DAQmxWaitForNextSampleClock(AOtaskHandle, 1.0, &islate)); // make sure enough trigger pulses are generated Sleep(*t->delta * 5); // stop tasks DAQmxErrRtn(DAQmxStopTask(DOtaskHandle)); DAQmxErrRtn(DAQmxStopTask(AOtaskHandle)); // number of frames actually taken t->FramesTaken = 1 + floor(t->nofFrames * (double)i/(double)(nofSamples * (*t->cycles))); // read protocol samples DAQmxReadAnalogF64(AItaskHandle,t->FramesTaken,5.0,DAQmx_Val_GroupByChannel,indata,t->FramesTaken*2,&read,NULL); DAQmxErrRtn(DAQmxStopTask(AItaskHandle)); // disable start triggers DAQmxErrRtn(DAQmxDisableStartTrig(DOtaskHandle)); DAQmxErrRtn(DAQmxDisableStartTrig(AOtaskHandle)); // reset trigger line DAQmxErrRtn(DAQmxWriteDigitalLines(TRtaskHandle,1,1,10,DAQmx_Val_GroupByChannel,trigdata[0],&written,NULL)); }
// from ConfigDAQmxTasks(float xVolts, float yVolts, ScanStructure scanStructure); int LifetimeAcq::configDAQmxTasks(float xVolts, float yVolts, ScanEngine* scanStruct) { int error; int retVal; char errBuff[2048]; double voltagePair[2]; //extern Trig_Channel; voltagePair[0] = (double)xVolts; voltagePair[1] = (double)yVolts; //_____DAQmx Configure Code________________________________________________________________ //_____Setup analog output task_____ DAQmxErrChk (DAQmxCreateTask("AnalogOuput",&aoTaskHandle)); DAQmxErrChk (DAQmxCreateAOVoltageChan (aoTaskHandle, scanStruct->getXChan(), "xChan", -2.0, 2.0, DAQmx_Val_Volts, NULL)); DAQmxErrChk (DAQmxCreateAOVoltageChan (aoTaskHandle, scanStruct->getYChan(), "yChan", -2.0, 2.0, DAQmx_Val_Volts, NULL)); DAQmxErrChk (DAQmxWriteAnalogF64 (aoTaskHandle, 1, 1, 10, DAQmx_Val_GroupByChannel, voltagePair, DAQmx_Val_GroupByChannel, NULL)); //_____Setup Analog input task_____ DAQmxErrChk (DAQmxCreateTask("TrigAcq",&acqTaskHandle)); /*Add analog input channel to acqtask*/ DAQmxErrChk (DAQmxCreateAIVoltageChan(acqTaskHandle, ACQ_CHANNEL, "PMT", DAQmx_Val_RSE,ACQMIN, ACQMAX, DAQmx_Val_Volts,NULL)); /*config analog input to use counter output as sample clock and continuous samps*/ DAQmxErrChk (DAQmxCfgSampClkTiming (acqTaskHandle, SAMPCLK_CHANNEL, SAMP_RATE, DAQmx_Val_Rising, DAQmx_Val_ContSamps, totSamps)); /*Make buffer size slightly larger than default*/ DAQmxErrChk (DAQmxSetBufferAttribute (acqTaskHandle, DAQmx_Buf_Input_BufSize, totSamps+1000)); //_____Setup counter task_____ DAQmxErrChk (DAQmxCreateTask ("couterOutTask", &ctrTaskHandle)); /*Add counter clock to counter task*/ DAQmxErrChk (DAQmxCreateCOPulseChanFreq (ctrTaskHandle, COUNTER_CHANNEL, "coChannel", DAQmx_Val_Hz,DAQmx_Val_Low, 0, SAMP_RATE, 0.5)); /*config clock for counter output task to generate correct numSamps*/ DAQmxErrChk (DAQmxCfgImplicitTiming (ctrTaskHandle, DAQmx_Val_FiniteSamps, numSamps)); /*Config triggering of counter task*/ DAQmxErrChk (DAQmxCfgDigEdgeStartTrig (ctrTaskHandle, TRIG_CHANNEL, DAQmx_Val_Rising)); DAQmxErrChk (DAQmxSetTrigAttribute (ctrTaskHandle, DAQmx_StartTrig_Retriggerable, TRUE)); return 1; Error: if( DAQmxFailed(error) ) DAQmxGetExtendedErrorInfo(errBuff,2048); retVal = this->stopTasks(); //if( DAQmxFailed(error) ) // MessagePopup("DAQmx Error",errBuff); return 0; }