04-05-2006 06:03 AM
Hi,
I'm trying to use National Instruments 6289 Card, VS-C++.NET and Measurmentstudio 8.0 in an attempt to acquire a large amount of data (oversampled using a timestamping approach). A piece of hardware generates a stream of data to be sampled, it also generates a train of digital pulses at an approximately constant frequency of 1kHz (this is generated by a mechanical
process, and consequently can vary by a reasonable amount that cannot be more accurately controlled).
The First pulse coincides with the start of the data streaming.
Within the Acquisition Code a Task is created to acquire voltage samples on
2
Channels and is configured for Continuous Acquisition with a start trigger being taken from the first pulse in the stream. The task is stopped after a predefined number of digital pulses have been counted.
To be able to count the number of digital pulses emitted by the equipment and therefore stop the task this channel has been connected to a DIO line and is used as a Start trigger.
When the events are triggered, I create a timestamp so that I can correlate the data in the continuous stream with the trigger pulses. However I've noticed a considerable variation in the time taken for a digital pulse to trigger a Digital Event (much larger than the variation in the pulse stream).
To test this I modified the ReadDigChan_ChangeDetection_Events Example Provided and connected the DIO to a signal generator set to emit a 5V square pulse with a mark time of 999µs and a space time of 1µs (1KHz) - this is an approximation of the 'ideal' pulse stream our hardware would emit. We verified that the generated pulse stream timing was accurate using an oscilloscope. The software was set to detect falling edges only. I then measured how long it would take to generate a number of pulses.
After 1000 pulses, which should theoretically take 1 sec to generate with the time between each pulse being 1ms, I found that my average time between each pulse was 1.02ms, but more importantly that the standard deviation was 2.46 ms ( variation of 239.7% wrt mean 😞
sum 1024.271172
mean 1.024271172
min 0.136636433
max 21.78575258
median 0.978832059
stdev 2.455225228
stdev% 239.7046109
I need to acquire data at a much higher rate (up to 100KHz) than the trigger events are being generated, but it is important that I keep some temporal coherence. Initially, I was intending to use the event system to create timestamps for the pulses (as above), but the large variation makes this solution unviable. I have also tried a hardware solution to multiply the incoming pulse stream and feed this in as an external sample clock, but this doesn't give me sufficient control over the acquisition speed.
Do you have any suggestions as to how I might go about achieving a solution to this problem using the hardware we have available?
Software Details: Measurement Studio for Visual C++ version 8.0 NI Hardware : Multifunction DAQ device PCI-6289 Driver Version : 8.0.0f0 Operating System: Windows XP
04-10-2006 04:22 AM
Hi,
you say :
@Edvard Dvorak wrote:
When the events are triggered, I create a timestamp so that I can correlate the data in the continuous stream with the trigger pulses. However I've noticed a considerable variation in the time taken for a digital pulse to trigger a Digital Event (much larger than the variation in the pulse stream).
To test this I modified the ReadDigChan_ChangeDetection_Events Example Provided and connected the DIO to a signal generator set to emit a 5V square pulse with a mark time of 999µs and a space time of 1µs (1KHz) - this is an approximation of the 'ideal' pulse stream our hardware would emit. We verified that the generated pulse stream timing was accurate using an oscilloscope. The software was set to detect falling edges only. I then measured how long it would take to generate a number of pulses.
I'm a little unsure of exactly how you're taking this measurement - are you using the system time stamp at the start and after 1000 pulses, or are you looking directly at the pci bus for when it sends the interrupt to say it's had a digital event? If the latter, where exactly are you probing?
THe reason I ask is if you're involving the software, then you also have the operating system to figth for processor time, and it could be a combination of the code, and what the rest of the PC is doing at that time that's adding in the jitter. I would assume that if this was the case, then the messages being handled would actually be out at the end (on the assumption that the code you're running completes fine within the 1ms window before it fires again.
It's also possible therefore that you're missing a couple of events at this rate if the handling code (including driver level software and handler) then that would contribute to the 24ms overrun.
What happens if you run at a slower rate? This would prove if there was an issue missing pulses due to software time.
Can you post your exact code (and project) here so we can investigate a little further?
The timestamping of data works against the onboard clock, and is therefore not subject to the jitter experienced getting timestamps etc.
Working against the pre-defined number of pulses, then it's possible to use a reference trigger based on a counter terminal count - setup a counter to count down from the pre-determined count you need, and then use the stop trigger from the ctr0internaloutput, which is where the counter fires when it hits terminal count.
We have an example in LabVIEW here :
at the minute, and you could use that as a roadmap (you can freely download an evaluation copy of LabVIEW here : http://digital.ni.com/demo.nsf/websearch/14f9ce475127ade786256ac60070926c?opendocument)
since DAQmx calls are the same across ADEs then this should work out easy to follow. This way everything is timed from your actual DAQ card, and not from timestamps generated from the software side of things.
Correlating the digital pulses is the trickier part. Ordinarily you could track them with the analog channels (use an extra channel) but since your signal width is only 1uS then this isn't great.
Another option, depending on what you're tracking, would be to externally clock the acquisition. A simple setup would involve useing a straight external clock setup. This would mean that every clock edge, you'd know what the analog input was.
A variation on this is to use a retriggerable pulse train to generate a set number of pulses every incoming edge, so that you get the higher acquisition rate, but you know every x pulses is in time with your incoming signal. Finite retriggerable pusle trains use two counters however, so this would stop you using the setup of a reference trigger after x pulses to stop the acquisition.
Hope that help
Sacha Emery
National Instruments (UK)