Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Finite samples vs. Hardware timed single point: Different acquisiton speed?

Solved!
Go to solution

Hi All,

 

Although I did have several questions about this application before which separately have been solved there is a final thing which remains difficult.

 

Shortly:

My application acquires data of 2 analog input channels and synchronously output on 2 analog output channels.

There is a stop trigger defined on a PFI-channel working with a simple switch. To make this

work I had to switch from hardware timed single point to finite acquition.

This all works fine when I don't read less then a 100 samples a time with a 1000 Hz sample rate. (When I go below a 100 sample to read --> E-200279)

 

Ideally I would like to read about 10 samples with a 1000 Hz sample rate.

 

However, using Hardware timed single point acquisition I can easily do this without a problem. Even reading just

a single sample a time with a 1000 Hz sample rate doesn't give a problem. But you cant use the reference trigger block as a stop trigger with this setting!

 

Question:

For me there are two solutions but so far I haven't been able to work out any of them:

1) Build a stop trigger in a hardware timed single point acquisition

2) Change something in the finite acquisition so that I can read faster.

 

Any suggestions what causes the difference between the two speeds of being able to read the data and a way to solve it?

 

Thanks,

Mark

 

Download All
0 Kudos
Message 1 of 13
(6,375 Views)

Mark,

 

What hardware are you using with your application?

 

Here's my guess as to why you have issues when you set 'Sample Per Read' to a small value.  For a finite acquisition, this value (samples per channel input to Timing VI) is used by DAQmx to configure the size of the buffer DAQmx allocates for hardware to stream data into.  Typically this works just fine, since without reference triggering we'd never need more space than this for the entire acquisition.  Reference triggering throws a bit of a wrench into this, since it is kind of a hybrid between finite and continuous acquisition.  I would recommend you use DAQmx Configure Input Buffer.vi, and explicitly create a larger buffer.  From DAQmx Help, we can see that by for your sampling rate, DAQmx would by default set the buffer size to 10,000 samples for a continuous acquisition.  I would recommend that you use DAQmx Configure Input Buffer to make this same setting for your task.  Place this VI between the DAQmx Timing VI and DAQmx Start Task.

 

Hope that helps,

Dan

0 Kudos
Message 2 of 13
(6,371 Views)

Hi Dan,

 

Thanks,

Forgot mentioning the hardware: BNC-2090 with a PCI-6024E card

 

I tried the configure input buffer. This makes me able to run it much longer then before. However

the buffer start to fill quickly and at some point it reaches its limit again. In addition as it can't keep

up with the processing my feedback and ao gets delayed by seconds while I'd like them

to be as synchronisly as possible.

 

It just doesn't make sense to me that with hardware timed single point acq I can do it read mich faster without having

trouble with processing time.

 

Your help is very much appreciated,

 

Regards

Mark

0 Kudos
Message 3 of 13
(6,367 Views)

Mark,

 

"However the buffer start to fill quickly and at some point it reaches its limit again. In addition as it can't keep

up with the processing my feedback and ao gets delayed by seconds while I'd like them

to be as synchronisly as possible."

 

This to me is the root of your problem.  Can you figure out which operations start to take longer?  Issues like this can often be traced to operations which consume more and more memory.  It appears as though you do use waveform charts in your bottom loop... How many points of data do you end up displaying as your application runs?  What happens if you remove this loop?  What happens if you replace them with waveform graphs?  Waveform graphs do not build history like charts do.  Can you use Windows task manager to look to see if your application consumes an ever-increasing amount of memory?  You can also try adding a timeout value to your Enqueue Element VI, and see if your top loop gets bottlenecked by the enqueue operation.  This would be indicative if the bottom loop slowing down, consequently forcing the top loop to wait until there was space in the queue for more data.

 

Those are a few ideas that first come to mind.  I'll let you know if I have any more thoughts.


Dan

 

 

 

0 Kudos
Message 4 of 13
(6,356 Views)

Mark,

 

I noticed one other strange thing about your VI... Since you don't call DAQmx Write before calling DAQmx Start you will end up with a hardware-timed non-buffered task.  Tasks configured in this way generally do not do what people want them to.  Additionally, this task is setup for finite generation, meaning that once it generates 'Samples Per Read' sample clocks, I believe it will stop outputting data.

 

I think that maybe you'd be better off setting your AO task to be continuous, and explicitly setting the buffer size to be some multiple of 'Samples Per Read' in length via the DAQmx Configure Output Buffer VI.  For this to work, you'll need to write at least 'Samples Per Read' amount of data before starting the task.  Basically use write to write whatever data you want you AO channels to output before you ever read any data.  I believe that you'll also need to disable buffer regeneration.

 

I think this would get you closer to the behavior you are looking for, but I think this would be very fragile since you will essentially be calculating new values to write at the same time your device has consumed all previous data you've written.  If you don't write new data soon enough, I believe DAQmx will error.

 

In reality, it seems like hardware timed single point might be a good solution for you, however, you will lose the ability to set up a reference trigger.  Is there any way you can live without this?

 

Sorry if that raises more questions than it answers, but I'm trying to get an idea of what you need to do then hopefully can give you some better suggestions.

 

Dan

0 Kudos
Message 5 of 13
(6,354 Views)

Hi Dan,

 

To clarify a bit on how I programmed it. My first intension was to built a Hardware Timed single point acquisition based application.

When that worked well (5000 Hz sampling, single sample acquisition without problems!) I decided that I needed an extra safety measure as the device controlled by this application is used to do

some electrical stimulation in humans (to make sure the AO channels are both on 0 V when the application is terminated in case something goes wrong).

 

That is when I switched to finite acquisition and added the stop and start tasks behind the producer loop (were the flat sequence is used)

to reset the AO channels. This works as well now.

 

It just surprises me that the only change 'hardware timed' --> 'finite acquisition' and adding the reference trigger slows down the application from the possibility to do

 5000 Hz single sample acqusition to only Fs = 1000 Hz / 100 sample to read acquisition.. 

 

I will try some of your suggestions and get back to you as soon as possible.

 

Thanks,

Mark

 

 

0 Kudos
Message 6 of 13
(6,343 Views)

Hi Dan,

 

As you suggested I did a few tests.

 

- Removing the consumer loop made me able to change samples to read to 20 with a Fs = 1000 Hz. (opposed to a 100 at 1000 Hz with the consumer loop)

- Changing the charts to graph didn't make any difference

- Adding a time-out time to the Enqueue VI didn't make any difference either. It still stops with the same error message (E-200279).

- The program doesn't show in increasing memory consumption when running before it stops on the E-200279 error

 

Does this make any sense? Why can the consumer loop execute so much faster in the hardware timed task than the finite acquisition task?

 

I didn't really get your comment about calling the Write VI before the Start VI. If you mean the bit in the flat sequence then this just

serves to set the AO utput back to 0V when the application is stopped.

 

Thanks your comments help a lot!

Mark

0 Kudos
Message 7 of 13
(6,324 Views)

Mark,

I'll comment on your points one at a time.  Two of my own question first.  1) What are you using for buffer size? 2) What operating system are you running this on?

 

"- Removing the consumer loop made me able to change samples to read to 20 with a Fs = 1000 Hz. (opposed to a 100 at 1000 Hz with the consumer loop)"

This corresponds to a 20 ms loop time, which makes sense given that you're reading 20 samples at 1 kHz.  If there is any operation in your loop that takes longer than this (either enqueing data or calculating your output waveform), then you will slowly back data up into the buffer until it overflows.

 

"- Changing the charts to graph didn't make any difference"

Shot in the dark on my part, and apparently not the issue.

 

"- Adding a time-out time to the Enqueue VI didn't make any difference either. It still stops with the same error message (E-200279)."

What value did you use for timeout?  This goes back to the first point... If it takes longer than 20 ms for this operation, or any other operation then you're going to build up data in the buffer.  If this goes on for long enough, you'll see error -200279.  This brings up another interesting point... If data is collecting in the buffer, you're feedback is going to be based on older and older data (in the case of a 10 kS buffer, data could be up to 10 seconds old).  It sounds like this is not desirable for your application.  More on this later.

 

"- The program doesn't show in increasing memory consumption when running before it stops on the E-200279 error"

I just wanted to check this, because increasing memory consumption is often the cause of loop slowdown.  It sounds like this is not your issue.

 

"I didn't really get your comment about calling the Write VI before the Start VI."

I'm not referring to the flat sequenced part of your code, I'm referring to the 'main' loop. Here is brief description of the mode you will end up being in by virtue of not calling write before start on your finite analog output task.  If you don't explicitly set a buffer size, DAQmx will use data written a pre-start call to DAQmx Write to infer the buffer size it should use.  Since you don't do this, DAQmx puts your output in the mode mentioned above.  If I remember correctly (I will check this when I have a little time), DAQmx does not write to the FIFO in this mode.  As such, if you write more than one sample between sample clocks, only the last sample written gets output.  Since you use the NSamp version of write, it is highly likely this will happen.

 

Is data backing up in your buffer bad for your application (I would guess yes, based on what you've told me about the application)?  Do you necessarily need to read every sample?  Depending on the answer to these questions, there are several approaches we can take.  If you can stand to miss data, then you can use the DAQmx Read Property node to set the 'relativeTo' property, and set this to 'Most Recent Sample'.  This will cause DAQmx to always read the newest data available in the buffer.  You can use the 'offset' property to tell DAQmx which data to read from this point.  For example, you can specify an offset of negative 'Samples Per Read' to ensure that you don't have to wait for hardware to produce new samples.  The tough part of doing this is that if your loop is slower than hardware, you will simply drop and data between reads.  If your loop is faster than hardware, you can get into a situation where you re-read some data from one iteration of the loop to the next.

 

Because of this, hardware-timed single point is probably a better way to go, however you'll need some other mechanism to detect stop (perhaps use a counter task to count edges on your 'stop' signal).  If you get a count, you'd know that you need to shut things down.  If you are running on a windows system, I suspect that you'll never reliably be able to run at 5 kHz without missing some samples.

 

That was verbose, but hopefully helpful.

Dan

Message 8 of 13
(6,312 Views)

Hi Dan,

 

Thanks a lot, I should be able to work something out now. 

 

To answer your questions:

 

1) Set it to 10k samples (increasing it only makes the time before it runs into the error longer, which makes sense) 

2) Windows XP.

 

You are right about data buffering. I don't want to buffer any data or if it is necessary reduce it the the absolute minimum. I don't necessarily need every sample the most important

thing is that I can update my AO channel with a sufficient high rate (e.g. 500 Hz) based on the most recent acquired AI. Your point about this made me actually think about my application again. Although it is nice to see the all

data acquired in the waveform graph I might need to reconsider if I really need this. I definitely need to see some of the data but not all of it.

 

The Relative To and Offset suggestion is definitely worth a try although like you mention my feeling, after all you told me, is that hardware timed single point acquisition is the way to go. I need to read a bit on counter tasks to see how that works and if I can use it as a stop task.

 

If I make any progress tomorrow I'll let you know.

 

Mark

0 Kudos
Message 9 of 13
(6,309 Views)
Solution
Accepted by topic author MLVDR

Mark,

 

I've mocked up how I think I would approach this and attached it.  The general idea is that we use HWTSP for our analog I/O, and a counter to look for edges on our 'stop' signal.  Each iteration of the loop, we check if we've seen the stop signal.  If we have, then we write zero to the output channels, and stop the loop.  If not, we write the feedback data we calculated.  I've added a few comments to the block diagram which I hope are helpful.  I don't currently have any E Series hardware on hand, so it may not function correctly out of the box, but I thought it'd point you in the right direction.

 

I will offer this precaution:

Windows is not a real time operating system.  As such, it may take the liberty to give as much CPU time to other processes or applications as it likes.  As a result, it's highly likely that you'll miss some samples (ie, your loop will not iterate as fast as the hardware issues sample clocks).  I have configured DAQmx should return a warning to you when this happens.

 

 

Hope that helps,

Dan

Message 10 of 13
(6,301 Views)