07-07-2010 04:04 PM
Howdy,
I'm having some quite strange problems with a data acquisition program that I'm writing, and I'm looking for some slightly better debugging tools. I've got a USB-6229 board and I want to have retriggerable finite acquisitions, so I'm using a counter as the clock for a continuous analog measurement. I know that the configuration works because I can run the retriggerable AI example code and I wrote a stand-alone program to test it out (not integrated into my main program). However, it simply doesn't work in my main program for some reason - I never read out any samples.
What I'm looking for now is a way to see what my tasks are doing to determine what's going wrong. Is there a way to determine if the counter task is triggering and/or if the analogue task has the clock setup correctly?
Any help would be appreciated.
07-08-2010 10:41 AM
One method would be to use the other counter on the M Series board to do an edge count the InternalOutput of the first counter. If the second counter is able to count the first one, then you know the counter has triggered and that the issue lies in the implementation of the AI code. If the counter doesn't trigger, there is a different issue.
07-09-2010 11:39 AM
This doesn't seem like a great solution, because now I don't know if I've somehow messed up the configuration on the second counter that I'm now adding into the mix. Is there no way to ask for the status of a task and/or channel?
Additionally, with this retriggered setup, I'm having a lot of problems figuring out how to determine when to grab the data. I want to grab it all as one chunk, but if I get there too early the buffer isn't full and I don't get all the data. Before I had a while() loop that I could terminate with an external command (in the event of some triggering problem) which just checked if the task was done every 50 milliseconds, but when I have the acquisition task configured as continuous acquisitions and the counter configured as retriggerable, the task isn't done until I've told it to stop. If there's a way to ask a counter task how many times it has been triggered or how many pulse trains it generated that would be ideal. Less ideal but still acceptable would be perhaps to ask how many samples are in the buffer - I could wait until the correct number of samples have been generated, then read them out. (I say that this is less ideal because if for some reason it generates too many samples and I just grab the first N samples, my data will likely be split up into channels incorrectly).
07-09-2010 07:54 PM
OK, in case anyone is interested, I haven't found any easy way to figure out how far along I am in the counter task, but I have found a good way to figure out how many samples I've read without reading out, which I've done like so:
while(i < 200 && !GetQuitIdle())
{
DAQmxGetReadAttribute(acquireSignal, DAQmx_Read_AvailSampPerChan, &bc);
if(bc >= np)
break;
i++;
Delay(0.05);
if(i == 200) {
sprintf(errmess, "The readout task is about to time out. It has been occuring for %ld seconds and has read %d samples. Allow it to wait another 2 seconds?", Timer() - time, bc);
j = ConfirmPopup("Timeout Warning", errmess);
if(j)
i -= 40;
else
return -2;
}
}
Also, I have good reason to suspect that whatever is causing my problems is some kind of a resource conflict that I've been unable to identify, because occasionally I'll actually be able to get a set of data through and it works well, and when it does hang, it will hang on Timer(). Additionally, I've seen it hang on DAQmxReadAnalogF64() for longer than the timeout time, which seems to similarly indicate a resource conflict.
07-12-2010 02:01 AM
Paul,
I'm not in the possibility of testing it now, but could DAQmxGetWriteAttribute (taskHandle, DAQmx_Write_TotalSampPerChanGenerated, &count); help you in monitoring counter generation?
Additionally, since Timer () returns a double you may have troubles printing it a %ld. You should get errors on such a line: do you happen to have cleared Run >> Break ON >> Library errors menu item? I suggest you to reenable it at least while you are debugging a critical function so that every possible incoherence in the code can be found.
07-12-2010 02:13 AM
Yeah, I changed that bit to %lf when I first ran the code. What I didn't realize was that there's a physical channel associated with these counters, so I can monitor the counter output with an oscilloscope. Seems like things trigger, but the program hangs somewhere - I think it's a resource allocation problem due to some problem with the multiple threads. Sometimes it hangs on Timer() or Delay(), other times it's like DAQmxReadAnalogF64() or DAQmxStartTask() - I noticed that even if I put a 2.0s timeout delay on the DAQmxReadAnalogF64, it'll sit there for a minute or more just hung up, which seems like a resource allocation problem.
07-13-2010 11:17 AM - edited 07-13-2010 11:18 AM
By the way, for anyone curious about the final solution (ouch, that sounds bad), I installed a bunch of multithreading locks whenever I was calling DAQmx functions - this may have helped because I no longer saw it hanging, but it still was not consistently working. When I tried plugging it into some test equipment, I found that it worked every time (Heisenbug). In the end, I think it was some sort of grounding issue where the ground was floating relative to the trigger pulse and was being pulled high on triggering. By consciously adding a wire to ground my DAQ the problem has been entirely eliminated. Very odd, but it works.