LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Basic configuration issue with DAQmxWriteAnalogF64

Solved!
Go to solution

Hello,

I must be missing something very basic, but I've been lost for hours...

I'm trying to send a Current flash of 10 mA during 5 ms, sent by a C software.

The issue is that the card seems to be stuck at the first value (10 mA) and never to go down to 0 mA.

My code is the following.

Any clue? Thanks so much!

 

int32       error = 0;
TaskHandle  taskOutput = 0;
float64     waveform[1000];
char        errBuff[2048] = { '\0' };
int         i = 0;


// set-up the waveform buffer to 10 mA for the first miliseconds and then 0.
for (; i < 5 ; i++) waveform[i] = 0.01;
for (; i < 1000; i++) waveform[i] = 0.;
 
DAQmxErrChk(DAQmxCreateTask("Current flash", &taskOutput));
DAQmxErrChk(DAQmxCreateAOCurrentChan(taskOutput, "/cDAQ2Mod2/ao2", "IR_flash", 0.0, 0.01, DAQmx_Val_Amps, NULL));

DAQmxErrChk(DAQmxCfgSampClkTiming(taskOutput, NULL, 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000));
DAQmxErrChk(DAQmxWriteAnalogF64(taskOutput, 1000, 0, 10.0, DAQmx_Val_GroupByChannel, waveform, NULL, NULL));
DAQmxErrChk(DAQmxRegisterDoneEvent(taskOutput, 0, DoneCallback, NULL));
DAQmxErrChk(DAQmxStartTask(taskOutput));

 

 

0 Kudos
Message 1 of 6
(3,748 Views)
Solution
Accepted by topic author appareil

After some try & fail periods, I have some insights...


Apparently, the waveform generation stops when I leave the function, keeping the last value. In my case, I left shortly after my code and Error management, so the value was kept at the original point.

 

The configuration works if I put a getchar() at the end of the code (not convenient), or if I put a Sleep(1000) or Sleep(100), so that it can finish emitting the samples.
 

0 Kudos
Message 2 of 6
(3,699 Views)

Well, you didn't show us the code following the abstract so it's difficult to guess what is happening, but if you have a StopTask or a ClearTask immediately following the code shown, the generation is stopped at that point.

 

CVI shipping examples like e.g. MultCurrUpdates-IntClk simply exit the start function but the program is not stopped since it remains alive waiting in RunUserInterface () instruction (thus leaving the generation time to terminate), the task being cleared only in DoneCallback (), which you actually have in your code but apparently are not executing at the right point.

 

GetChar () leaves the program alive until a key press; Sleep (1000) leaves the program time to terminate the whole generation; Sleep (100) just aborts the generation prematurely but since the 5 ms burst has already terminated it seems all is well even if the process is still going on.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 6
(3,692 Views)

If I may...

I still have issues with this topic, in fact.

I want to launch the Flashes in threads (so that the "Sleep" do not block the reception of the flash). So the code is the following :

 

int32 CVICALLBACK DoneCallback(TaskHandle taskHandle, int32 status, void *callbackData)
{
	printf("\ndone\n");
	DAQmxClearTask(taskHandle);
	return 0;
}

void flash()
{
	int32       error = 0;
	TaskHandle  taskOutput = 0;
	float64     waveform[1000];
	char        errBuff[2048] = { '\0' };
	int         i = 0;


	// set-up the waveform buffer to 10 mA for the first miliseconds and then 0.
	for (; i < 5 ; i++) waveform[i] = 0.01;
	for (; i < 1000; i++) waveform[i] = 0.;
 
	DAQmxErrChk(DAQmxCreateTask("Current flash", &taskOutput));
	DAQmxErrChk(DAQmxCreateAOCurrentChan(taskOutput, "/cDAQ2Mod2/ao2", "IR_flash", 0.0, 0.01, DAQmx_Val_Amps, NULL));

	DAQmxErrChk(DAQmxCfgSampClkTiming(taskOutput, NULL, 1000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000));
	DAQmxErrChk(DAQmxWriteAnalogF64(taskOutput, 1000, 0, 10.0, DAQmx_Val_GroupByChannel, waveform, NULL, NULL));
	DAQmxErrChk(DAQmxRegisterDoneEvent(taskOutput, 0, DoneCallback, NULL));
	DAQmxErrChk(DAQmxStartTask(taskOutput));


	Sleep(1010);

	Error:
	if (DAQmxFailed(error))
		DAQmxGetExtendedErrorInfo(errBuff, 2048);
	if (taskOutput != 0) {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskOutput);
		DAQmxClearTask(taskOutput);
	}
	if (DAQmxFailed(error))
		printf("DAQmx Error: %s\n", errBuff);
}



main(){
	// create 5 threads flashing once each
	nbThreads = 0;
	std::thread process[5];
	for (; nbThreads < 5 ; nbThreads ++ ) 
	{
		process[nbThreads ++] = std::thread(flash);
		Sleep(2000);
	}
// at this point, I expected all threads to be finished and self-killed. But it's not the case... }

But the code does not exit cleanly: the "DoneCallback" is never launched (I don't see the printf), and  I get an error at the end of "main" :unhandled exception when trying to close the threads , on the "terminate" line of

 

~thread() _NOEXCEPT       {    if (joinable())  _XSTD terminate();    }    .

 

So the process of flasing and sleeping does not terminate (I expected the thread to be killed automatically after the Sleep).
What may be the solution? Why don't I launch the DoneCallback function???

Thanks!

0 Kudos
Message 4 of 6
(3,678 Views)

The reason the done callback is not executed lies probably in that the task is cleared before the process is complete.

If I were you I'll get rid of the done callback and instead of the sleep I'd sit in a loop waiting for DAQmxIsTaskDone () function to signal the task is terminated. In the main you should check if all threads are terminated before terminating: you should get no error on exit.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 6
(3,673 Views)

Thanks a lot, I think this solution solves my problems!

 

0 Kudos
Message 6 of 6
(3,660 Views)