08-09-2008 10:26 AM
08-11-2008 01:15 PM
While I suspect I'll have this figured out by trial and error before I get a response, I've figured out more about this for anyone interested.
I'm not sure why this is the case, but I've tracked down something that makes this code kind of work. I really have two threads running, which I'll psuedo-code below (hiding details like how I save and the fact that really I'm using Mutexs). If I just do Fetch commands in one of the threads the saved channels do not line up. If I do a cout command (which does have some thread sync'ing implications but I don't think that's related) after each fetch, everything works. I suspect this is still more of a triggering issue (giving the card time to catch up perhaps) than a thread issue, but at least the code is working. I still don't have confidence yet that I'm not missing something. I might need to find some attribute which says it's okay to Fetch again, but I'd think for the continuous acquisition I could call Fetch right after each other.
volatile bool bDataToSave1, bDataToSave2; // there is data available to be saved
FetchThread()
{
while(1)
{
while(bDataToSave1);
handleErr(niScope_FetchBinary16 (vi, channelName, 0, actualRecordLength , (ViInt16*)waveformPtr1, wfmInfo1));
cout << "whatever" << endl; // remove this and the channels don't line up
bDataToSave1 = true;
while(bDataToSave2);
handleErr(niScope_FetchBinary16 (vi, channelName, 0, actualRecordLength , (ViInt16*)waveformPtr2, wfmInfo2));
cout << "whatever" << endl; // remove this and the channels don't line up
bDataToSave2 = true;
}
}
SaveThread()
{
while(1)
{
if(bDataToSave1)
SaveData(waveformPtr1);
if(bDataToSave2)
SaveData(waveformPtr2);
}
}
08-11-2008 01:51 PM - edited 08-11-2008 01:52 PM
Hi Greg,
The 5105 does sample simultaneously on all 8 channels. You should be able to use a simple NI-Scope example (like ConfiguredAcquisition) to convince yourself of this. As you mentioned, split your signal to multiple channels and you should see simultaneous data regardless of trigger source.
If you are performing a continuous acquisition, then your problem is not likely due to triggering since a continuous acquisition works by configuring a SW trigger that will never occur. I would be more suspicious of how the read pointer is being manipulated. This will determine what data is fetched back.
08-11-2008 04:24 PM
Thank you so much for responding. I am intrigued by your "read pointer" comment. I'm getting gaps in my captured data (though it's aligned now that I added the cout commands).
Could you please be more specific about "how the read pointer is manipulated"? I'm thinking this means I need to use a FetchInChunks style capture for continuous acquisition. I have been using the FetchForever scheme, which I now think is more for benchmarking than data collection. The data is coming in aligned as mentioned in my last post, but I'm getting gaps in the captured data.
Also, is there a document that explains the attributes in one place? The help file seems to touch on the attributes here and there, and the quick reference guide shows how to read/write the attributes, but I haven't found a comprehensive list and description.
Thanks again,
Greg
08-11-2008 04:49 PM - edited 08-11-2008 04:50 PM
Hi Greg,
The fetch relative to attribute is what I was referring to. The behavior you are describing sounds like it could be caused by fetching relative to "now" instead of "read pointer". From the NI High-Speed Digitizers Help file:
NISCOPE_ATTR_FETCH_RELATIVE_TO
Description
Position to start fetching within one record.
Default Value: NISCOPE_VAL_PRETRIGGER
Defined Values
NISCOPE_VAL_PRETRIGGER (477)—Fetches relative to the first pretrigger point requested with niScope_ConfigureHorizontalTiming.
NISCOPE_VAL_NOW (481—Fetch data at the last sample acquired.
NISCOPE_VAL_START (482)—Fetch data starting at the first point sampled by the digitizer.
NISCOPE_VAL_TRIGGER (483)—Fetch at the first posttrigger sample.
NISCOPE_VAL_READ_POINTER (388)—The read pointer is set to zero when a new acquisition is initiated. After every fetch the read pointer is incremented to be the sample after the last sample retrieved. Therefore, you can repeatedly fetch relative to the read pointer for a continuous acquisition program.
Hope this helps.
08-11-2008 06:49 PM
08-12-2008 02:31 PM
Hey,
I'm still tweaking the settings a bit but based on a limited amount of testing I think it's working. I'm stepping through some of the settings like minRecordLength and the timeout to see what's most efficient but that's just details.
Thank you so much for your help!
Cheers,
Greg
08-13-2008 03:59 PM
Hi, I hope you're still watching this thread.
The code is not really working after all, not as I expect. There is something I'm not getting about the minimum record length, the minimum number of samples to fetch, the number of channels, and probably some other related parameters.
If I set the minimum number of samples to fetch low (to ~8k when the device would move 12k chunks at a time if it was higher) then the data I capture is syncronized between the two channels. If I set the data high (~128k) then the data is no longer syncronized. However with the low number of fetch samples, I am missing data from chunk to chunk- the data is obviously not aligned correctly from chunk to chunk when I feed an AM modulated signal into both channels, even though .
I would think a higher fetch number is better. Sometimes even when the data starts saving as syncronized from channel to channel it drifts out.
When I save the data to file, I do save the actualSamples from wfmInfo and use that to reconstruct the data. Also if I output the data to the console I can see the channels are not reading the same values. I'm very confused.
The following is in my code:
// Start acquiring data
handleErr (niScope_InitiateAcquisition (vi));
// this is a low level set command to perform continuous acquisition
checkErr (niScope_SetAttributeViInt32 (vi, VI_NULL,
NISCOPE_ATTR_FETCH_RELATIVE_TO, NISCOPE_VAL_READ_POINTER ));
08-13-2008 05:03 PM
08-13-2008 05:45 PM