Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmxRegisterEveryNSamplesEvent with USB-6211

I am trying to use the DAQmxRegisterEveryNSamplesEvent with an analog output channel to do continuous waveform generation. Here is a simple example which reproduces the errors I am observing:

#include <stdio.h>
#include <NIDAQmx.h>
#include <math.h>

#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
#define DATA_SIZE 1000
#define BUFF_SIZE 20000

int32 CVICALLBACK EveryNSamplesCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void* callbackData);
int32 write_to_buffer(int32 samples);
void Cleanup(void);

static TaskHandle	taskHandle = 0;
static float64		data[DATA_SIZE];

float64 sample_rate = 1000.0;
uInt64 samples_written = 0;
int32 gap = 1000;

int main(void)
{
	int32       error = 0;
	char        errBuff[2048] = { '\0' };

	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk(DAQmxCreateTask("", &taskHandle));
	DAQmxErrChk(DAQmxCreateAOVoltageChan(taskHandle, "Dev1/ao0", "", -10.0, 10.0, DAQmx_Val_Volts, NULL));
	DAQmxErrChk(DAQmxSetWriteRegenMode(taskHandle, DAQmx_Val_DoNotAllowRegen));
	DAQmxErrChk(DAQmxCfgOutputBuffer(taskHandle, BUFF_SIZE));
	DAQmxErrChk(DAQmxCfgSampClkTiming(taskHandle, "", sample_rate, DAQmx_Val_Rising, DAQmx_Val_ContSamps, BUFF_SIZE));
	DAQmxErrChk(DAQmxRegisterEveryNSamplesEvent(taskHandle, DAQmx_Val_Transferred_From_Buffer, gap/2, 0, EveryNSamplesCallback, NULL));
	DAQmxErrChk(write_to_buffer(gap));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk(DAQmxStartTask(taskHandle));

	printf("Acquiring samples continuously.  Press Enter key to interrupt\n");

	getchar();

	DAQmxErrChk(DAQmxStopTask(taskHandle));

	printf("\nWrote %d total samples.\n", (int)samples_written);

Error:
	if (DAQmxFailed(error))
	{
		DAQmxGetExtendedErrorInfo(errBuff, 2048);
		Cleanup();
		printf("DAQmx Error: %s\n", errBuff);
	}
	printf("End of program, press Enter key to quit\n");
	getchar();
	return 0;
}

int32 CVICALLBACK EveryNSamplesCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void* callbackData)
{
	printf("samples written:\t%d\n", samples_written);
	char errBuff[2048] = { '\0' };
	int32 error;
	uInt64 samples_generated;
	DAQmxErrChk(DAQmxGetWriteTotalSampPerChanGenerated(taskHandle, &samples_generated));
	uInt64 sample_gap = samples_written - samples_generated;
	int32 samples = gap - sample_gap;
	DAQmxErrChk(write_to_buffer(samples));

Error:
	if (DAQmxFailed(error))
	{
		DAQmxGetExtendedErrorInfo(errBuff, 2048);
		Cleanup();
		printf("DAQmx Error: %s\n", errBuff);
	}
	return 0;
}

int32 write_to_buffer(int32 samples)
{
	int32 error_code = 0;;
	while (samples > 0) {
		int32 chunk = samples < DATA_SIZE ? samples : DATA_SIZE;
		for (int i = 0; i < chunk; i++) {
			data[i] = (samples_written+i) % 5;
		}
		int32 delta_samples_written;
		error_code = DAQmxWriteAnalogF64(taskHandle, chunk, 0, 0, DAQmx_Val_GroupByChannel, data, &delta_samples_written, NULL);
		printf("delta samples written: %d\n", delta_samples_written);
		if (error_code != 0) {
			return error_code;
		}
		samples_written += delta_samples_written;
		samples -= delta_samples_written;
	}
	return 0;
}

void Cleanup(void)
{
	if (taskHandle != 0)
	{
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
		taskHandle = 0;
	}
}

 When I run this using a simulated USB-6341 device, I get the expected behavior:

creillymolecule_1-1616268151635.png

With my (non-simulated) USB-6211 device, I get the following:

creillymolecule_2-1616268222054.png

The program just hangs in this state. To summarize the issues:

  • The callback fires after 1 sample is generated, instead of the requested 50
  • It again fires immediately, instead of the requested 50
  • Then the callback fails to fire at all. The task is still generating output, which I can observe on the scope, and also:
  • when I hit return, I get an error that says there was a memory underflow, which makes sense because the callback wasn't firing as it should so the buffer was emptied:

creillymolecule_3-1616268595318.png

I can accomplish this same task just using a loop where I poll the device using DAQmxGetWriteTotalSampPerChanGenerated and write samples accordingly. So why is the callback behavior completely wrong for this device?

  

 

0 Kudos
Message 1 of 1
(735 Views)