06-29-2009 05:09 PM
I'm a research assistant for Northeastern University in Boston. We had a class using the 6024E PCI card in our Electrical Engineering lab and are now trying to migrate to a USB 6009 in order to move into a standard computer lab and expand the number of sections being taught.
This lab is taught to first-year engineering undergraduates of all disciplines, some of whom have no programming background. As well-written as NIDAQmx.h is, we believe it may be intimidating for our purposes. Therefore, I'm attempting to develop a "front-end" so that they only have to code, say, write_digital(14) to put [0111] on P0.0-P0.3 (with a #include statement at the top, of course). However, I've run into a problem.
I'm using Visual C++ 2008 without Measurement Studio. I've stored the task inside a class, as that's the best method I can think of to let the students write their own .cpp file (and #include my class as a .h file). I am able to run the attached code once (to write 13, in this example) but the task is somehow rendered invalid between writing 13 and attempting to write 14. The 14 is not written, and I get an error (reprodeuced below). I've tried using DAQmxIsTaskDone() to look into where it may be turning invalid, but that only confused me further (saying it's still running even after throwing the error, giving me different results depending on where I put the function call with no other changes, etc.).
I'm thinking it is related to a task's behaviour at the end of a block, but I'm not sure. I'm completely open to any advice or suggestions anyone may have, including a full re-design if that's the best option.
Thanks in advance!
-Geoff
This is the output:
107
108
DAQmx Error: Measurements: Task specified is invalid or does not exist.
Status Code: -200088
of this code:
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else class TaskEnvelope{ TaskHandle task; public: TaskEnvelope(){ task = 0; DAQmxCreateTask("",&task); DAQmxCreateDOChan(task,"Dev1/port0/line0:7","",DAQmx_Val_ChanForAllLines); } void write(int data){ int temp = data%256; uInt8 output[8]; int32 error=0; char errBuff[2048]={'\0'}; for(int i = 0; i < 8; i++){ output[i] = temp % 2; temp = temp / 2; } DAQmxStartTask(task); DAQmxErrChk (DAQmxWriteDigitalLines(task,1,1,10.0,DAQmx_Val_GroupByChannel,output,NULL,NULL)); Error: if( DAQmxFailed(error) ) DAQmxGetExtendedErrorInfo(errBuff,2048); if( task!=0 ) { DAQmxStopTask(task); DAQmxClearTask(task); } if( DAQmxFailed(error) ) printf("DAQmx Error: %s\n",errBuff); } }; int main(void){ TaskEnvelope env; for(int i = 13; i < 15; i++){ cout<<i<<endl; env.write(i); } return 0; }
07-06-2009 10:07 AM
The_Sea,
It looks like you always start the task in the body of the class but only in the error handling do you stop/clear the task. If the stop/clear is executing (which I believe it is) then the clear will remove the task and you would have to create a new one. What happens if you move the clear to a different part of the program or reorganize so that stop and clear are not executed together.