Exemple #1
0
int DllExport _nidaq_read (int id)
{
	int32 samplesRead;
	sTask *pTask;
	sDataChain *pData, *pNext;
	
	pTask = tasks.item + id;
	if (pTask->type != DAQmx_Val_OnDemand) return 0;
	pData = pTask->current;
	/* if the data is full, make another chain */
	if (pData->num == NBUF)
	{
		pNext = malloc(sizeof(sDataChain));
		pNext->data = malloc(NBUF * pTask->numChannels * sizeof(short));
		pNext->num = 0;
		pNext->next = 0;
		pData->next = pNext;
		pTask->current = pNext;
		pTask->num++;
		pData = pNext;
	}
	DAQmxReadBinaryI16 (pTask->handle, DAQmx_Val_Auto, 10.0, DAQmx_Val_GroupByScanNumber, pData->data + pData->num * pTask->numChannels,
		(NBUF - pData->num) * pTask->numChannels, &samplesRead, NULL);
	pData->num += samplesRead;

	return pTask->num;
}
Exemple #2
0
// [outputData, sampsPerChanRead] = readAnalogData(task, numSampsPerChan, outputFormat, timeout, outputVarSizeOrName)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	//Read input arguments

	// Get the task handle
	mxArray *mxTaskID = mxGetProperty(prhs[0],0,"taskID");
	mxClassID clsID = mxGetClassID(mxTaskID);
	localAssert(clsID==TASKHANDLE_MXCLASS);
	TaskHandle *taskIDPtr = (TaskHandle*)mxGetData(mxTaskID);
	TaskHandle taskID = *taskIDPtr;

	//Determine if this is a buffered read operation
	uInt32 bufSize = 0;
	int32 status = DAQmxGetBufInputBufSize(taskID,&bufSize);
	if (status) {
		handleDAQmxError(status,"DAQmxGetBufInputBufSize");
	}

	// Handle input arguments

	int32 numSampsPerChan = 0; // this does take negative vals in the case of DAQmx_Val_Auto
	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]);
	}
	
	char outputFormat[10];
	if ((nrhs < 3) || mxIsEmpty(prhs[2]))
		strcpy_s(outputFormat,"scaled");
	else
		mxGetString(prhs[2], outputFormat, 10);

	double timeout;
	if ((nrhs < 4) || mxIsEmpty(prhs[3]) || mxIsInf(mxGetScalar(prhs[3])))
		timeout = DAQmx_Val_WaitInfinitely;
	else
		timeout = mxGetScalar(prhs[3]);

	bool outputData; //Indicates whether to return an outputData argument
	int outputVarSampsPerChan = 0; // this CAN take negative values in case of DAQmx_Val_Auto
	char outputVarName[MAXVARNAMESIZE];	
	if ((nrhs < 5) || mxIsEmpty(prhs[4])) {
		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);
		}
	}

	//Determine output data type
	mxClassID outputDataClass;
	mxArray *mxRawDataArrayAI = mxGetProperty(prhs[0],0,"rawDataArrayAI"); //Stored in MCOS Task object as an empty array of the desired class!
	mxClassID rawDataClass = mxGetClassID(mxRawDataArrayAI); 

	char errorMessage[30];
	if (!_strcmpi(outputFormat,"scaled"))
		outputDataClass = mxDOUBLE_CLASS;
	else if (!_strcmpi(outputFormat,"native"))
		outputDataClass = rawDataClass;
	else {
		sprintf_s(errorMessage,"Unrecognized output format: %s\n",outputFormat);
		mexErrMsgTxt(errorMessage);
	}		

	//Determine # 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 *mxOutputDataBuf = NULL;
	if (outputData)	{
		if (outputVarSampsPerChan == DAQmx_Val_Auto) {
			uInt32 buf = 0;
			status = DAQmxGetReadAvailSampPerChan(taskID,&buf);
			if (status) {
				handleDAQmxError(status, mexFunctionName());
			}
			outputVarSampsPerChan = buf;
		}

		//localAssert(outputVarSampsPerChan >= 0);
		localAssert(outputVarSampsPerChan > 0);
		mxOutputDataBuf = mxCreateNumericMatrix(outputVarSampsPerChan,numChannels,outputDataClass,mxREAL);
	} else {
		localAssert(false);
		////I don't believe this is working
		//mxOutputDataBuf = mexGetVariable("caller", outputVarName);
		//outputVarSampsPerChan = mxGetM(mxOutputDataBuf);
		////TODO: Add check to ensure WS variable is of correct class
	}

	void* outputDataPtr = mxGetData(mxOutputDataBuf);
	localAssert(outputDataPtr!=NULL);

	uInt32 arraySizeInSamps = outputVarSampsPerChan * numChannels;
	localAssert(mxGetNumberOfElements(mxOutputDataBuf)==(size_t)arraySizeInSamps);
	int32 numSampsPerChanRead;

	
	if (outputDataClass == mxDOUBLE_CLASS) //'scaled' 
		// float64 should be double
		status = DAQmxReadAnalogF64(taskID,numSampsPerChan,timeout,fillMode,
				(float64*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL);
	else { //'raw'
		switch (outputDataClass)
		{
			case mxINT16_CLASS:
				status = DAQmxReadBinaryI16(taskID, numSampsPerChan, timeout, fillMode, (int16*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL);
				break;
			case mxINT32_CLASS:
				status = DAQmxReadBinaryI32(taskID, numSampsPerChan, timeout, fillMode, (int32*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL);
				break;
			case mxUINT16_CLASS:
				status = DAQmxReadBinaryU16(taskID, numSampsPerChan, timeout, fillMode, (uInt16*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL);
				break;
			case mxUINT32_CLASS:
				status = DAQmxReadBinaryU32(taskID, numSampsPerChan, timeout, fillMode, (uInt32*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL);
				break;
		}
	}

	//Return output data
	if (!status)
	{
		//mexPrintf("Successfully read %d samples of data\n", numSampsRead);

		if (outputData) {
			if (nlhs > 0)
				plhs[0] = mxOutputDataBuf;
			else				
				mxDestroyArray(mxOutputDataBuf); //If you don't read out, all the reading was done for naught
		} else {
			//I don't believe this is working
			localAssert(false);
			//mexPutVariable("caller", outputVarName, mxOutputDataBuf);
			//
			//if (nlhs >= 0) //Return empty value for output data
			//	plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
		}
			

		if (nlhs>1) { //Return number of samples actually read
			plhs[1] = mxCreateDoubleScalar(0.0);	
			double *sampsReadOutput = mxGetPr(plhs[1]);
			*sampsReadOutput = (double)numSampsPerChanRead;
		}
	} else { //Read failed
		handleDAQmxError(status, mexFunctionName());
	}

}
Exemple #3
0
int DllExport _nidaq_store (int id, char *nodeName, int simultaneous)
{
	char channelName[256], pathName[256];
	int16 *data;
	int32 stats, samplesRead, idesc, idesc1, idesc2, idesc3, idesc4, idesc5, idesc6, dtype, null = 0;
	uInt32 i, arraySize, nPacket, packetSize;
	uInt64 numSamples;
	float64 convRate, dt, range, resolution, period;
	sTask *pTask;
	sDataChain *pData, *pNext;
	
	pTask = tasks.item + id;
	if (simultaneous)
	{
		dt = 0.0;
	}
	else
	{
		DAQmxGetTimingAttribute (pTask->handle, DAQmx_AIConv_Rate, &convRate);
		dt = 1.0/convRate;
	}

	if (pTask->type== DAQmx_Val_OnDemand)
	{
		pData = pTask->current;
		samplesRead = pTask->num * NBUF + pData->num;
		arraySize = pTask->numChannels * samplesRead;
		data = (int16 *)malloc(arraySize * sizeof (int16));
		nPacket = NBUF * pTask->numChannels;
		packetSize = nPacket * sizeof (int16);
		pNext = pTask->start;
		for (i=0; i<pTask->num; i++)
		{
			pData = pNext;
			memcpy (data + i * nPacket, pData->data, packetSize);
			pNext = pData->next;
			free (pData->data);
			free (pData);
		}
		memcpy (data + i * nPacket, pNext->data, pNext->num * pTask->numChannels * sizeof (int16));
		free (pNext->data);
		free (pNext);
	}
	else
	{
		/* # of samples */
		DAQmxGetTimingAttribute (pTask->handle, DAQmx_SampQuant_SampPerChan, &numSamples);
		arraySize = pTask->numChannels * numSamples;
		data = (int16 *)malloc(arraySize * sizeof (int16));
		DAQmxReadBinaryI16 (pTask->handle, DAQmx_Val_Auto, 10.0, DAQmx_Val_GroupByScanNumber, data, arraySize, &samplesRead, NULL);
	}
	/* Get the ADC resolution 12bits=NI6071,NI6115, 16bits=NI6143, 14bits but packed from bit 15=NI6133 */
	DAQmxGetChanAttribute (pTask->handle, NULL, DAQmx_AI_Resolution, &resolution);
	if (resolution == 14.) resolution = 16.;
	resolution = ldexp (1.0, (int) resolution-1);  

	/* Sampling time */
	DAQmxGetTimingAttribute (pTask->handle, DAQmx_SampClk_Rate, &period);
	period = 1.0/period; //Rate -> Time
	
	dtype = DTYPE_SHORT;
	idesc1 = descr(&dtype, data, &arraySize, &null);

	dtype = DTYPE_ULONG;
	idesc2 = descr(&dtype, &i, &null);

	idesc3 = descr(&dtype, &pTask->numChannels, &null);

	dtype = DTYPE_ULONGLONG;
	numSamples = samplesRead - 1;
	idesc4 = descr(&dtype, &numSamples, &null);

	dtype = DTYPE_DOUBLE;
	idesc = descr(&dtype, &range, &null);
	idesc5 = descr(&dtype, &convRate, &null);
	idesc6 = descr(&dtype, &period, &null);
	for (i=0; i<pTask->numChannels; i++)
	{
		/* Translate a channel name to a node name */
		DAQmxGetNthTaskChannel (pTask->handle, i+1, channelName, 256);
		sprintf (pathName, "%s:%s:FOO", nodeName, channelName);

		DAQmxGetChanAttribute (pTask->handle, channelName, DAQmx_AI_Max, &range);
		range /= resolution;

		convRate = i * dt;
		stats = MdsPut(pathName,"BUILD_SIGNAL(BUILD_WITH_UNITS($*$VALUE,'V'),(`$[$:*:($)]),MAKE_DIM(MAKE_WINDOW(0,$,$),MAKE_SLOPE(MAKE_WITH_UNITS($,'s'))))",
			&idesc, &idesc1, &idesc2, &idesc3, &idesc4, &idesc5, &idesc6, &null);
	}
	free (data);
	
	DAQmxStopTask (pTask->handle);
	return 1;
}