02-23-2012 03:38 PM - edited 02-23-2012 03:42 PM
Hi,
So I have a situation where I'm using a retriggerable DAQ task to acquire data, and just recently I've had a problem come up. I have the following error-catching scheme. On the relevant line, I have:
if(ev = DAQmxStopTask(ce.cTask)) { goto error; }
Which goes to the "error" region of the program (where I do garbage collection, error popups, etc, basically emulating try-catch statements):
error: if(ce_locked) { CmtReleaseLock(lock_ce); } SetCtrlVal(mc.mainstatus[1], mc.mainstatus[0], 0); // Experiment is done! SetCtrlAttribute(mc.mainstatus[1], mc.mainstatus[0], ATTR_LABEL_TEXT, "Stopped"); SetRunning(0); if(data != NULL) { free(data); } if(avg_data != NULL) { free(avg_data); } if(ev) { if((ev < -247 && ev >= -250) || (ev < -6201 && ev >= -6224)) { display_ddc_error(ev); } else { uInt32 es_size = DAQmxGetExtendedErrorInfo(NULL, 0); char *es = malloc((es_size > 0)?(es_size+1):100); if(es_size > 0) { DAQmxGetExtendedErrorInfo(es, es_size); } else { sprintf(es, "Unknown DAQmx Error, code was %d", ev); } MessagePopup("DAQmx Error", es); free(es); } }
I'm using a USB-6229 M series DAQ, ce.cTask is a counter task, which is built (without throwing any errors) to be triggered by an external channel, then fire off a square wave which triggers each point in the acquisition by another task, ce.aTask. It's done this way so that I can do things like acquire for 2 seconds, wait a varied amount of time, then acquire for another 2 seconds. Currently what I'm doing is simpler than that, ce.cTask is on /Dev1/ctr0, and ce.aTask is triggered by Ctr0InternalOutput. This has always worked in the past.
I've gone through with breakpoints and it certainly seems like ce.cTask triggers just fine, all the data are read in by aTask, and everything goes peachy-keen with no errors until the line where I try and stop ce.cTask. This throws me error 200010, but DAQmxGetExtendedErrorInfo(NULL, 0) returns 0, and if I just hard-code es_size to be something like 10, I get an empty string. I can see no description of error 200010 anywhere online, other than a few forum postings relating to readout buffer overflows, which I highly doubt is the issue with stopping a counter task. Any idea how to fix this?
Edit:
I have changed the error checking to this:
if(ev = DAQmxStopTask(ce.cTask)) { if(ev != 200010) { goto error; } }
Things are now working like they did before, and I've seen no consequences from this. I'm still a bit concerned that I'm hard-coding in a mechanism to ignore a specific error code, though.
Solved! Go to Solution.
02-24-2012 02:53 AM
Hello, passing that error code to DAQmxGetErrorString function returns the text "Finite acquisition or generation has been stopped before the requested number of samples were acquired or generated": it appears as if you have stopped the task prematurely so you may want to check your code for such a condition. Using DAQmxIsTaskDone function may help you in avoiding this condition.
I'm not sure about it, but the reason why DAQmxGetExtendedErrorInfo does not return any description may lie in some DaqMx function that is executed without error after you get the original error (possibly in your SetRunning function?): DAQmxGetExtendedErrorInfo does return meaningful informations only after a function on error, so you should use DAQmxGetErrorString instead if you need to run some other DaqMx function before you elaborate the error code to give informations to the operator. Alternatively you could store both the error code and extended informations before you clean up your environment and warn the operator after that moment with informations in memory.
02-24-2012 03:07 AM
I don't believe so. Running is a Thread-Safe Variable indicating if an experiment is running. SetRunning(1) is defined by macro I think, doesn't have any DAQmx stuff in it. No other threads should be able to execute any DAQmx functions. For one thing no other threads do have any DAQmx stuff in it, and for another all functions which call DAQmx functions are locked with lock_DAQ, which isn't released until after the error string is retrieved. It's a real head-scratcher. When I get back to work I'll try moving the DAQmxGetExtendedErrorInfo closer to the function call just in case I'm missing something. I'll also take a look at the task-not-done situation. May be some situation with the retriggerability.
Also, thanks for the info about DAQmxGetErrorString. For some reason I don't seem to have the full documentation for DAQmx functions - the docs I'm using are missing things like DAQmxGetDeviceAttribute and such, so I have to kind of look at function panels and stuff to find new functions. I'll try using DAQmxGetErrorString in the future.