Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronized AI-AO with data processing

Solved!
Go to solution

Hi All,

 

I am trying to build a fairly simple VI which should work in the following way:

 

1: Acquire data from two AI channels with a sample rate of 2000 Hz

2: Process the data: some time averaging and scaling of the output signal dependent on input

3: Write data to two AO channels. (A button controls if AO output is either 0 or dependent on the input)

 

Most important is that the delay between actual AI and processed AO is kept to a minimum. 

 

Following several examples I came up with the attached VI. 

 

Two problems exist: 

1: Although the synchronization principle works without the data processing subVI in between, integrating the subVI and all the displays

makes a simple test sine wave from a function generator having a lot of flaws (not being smooth). I know all the displays slow down the loop time but those are essential

for the application. Any suggestions? 

2: Although it runs, it keeps on giving E- 209802, something with Unnamed Task, Doesn't really make sense to me.

 

Thanks in advance for any help,

 

Mark 

 

 

Download All
0 Kudos
Message 1 of 10
(5,554 Views)

Mark,

 

A couple of points:

1) If you're not running on a real time operating system, I doubt that you'll be able to dependably run at 2 kHz.

2) I would separate the 'time critical' I/O logic from your display logic.  This seems like a good candidate for a producer-consumer design (ie... your main loop should simply enqueue data which needs to be displayed, and a second loop should dequeue this data and handle display logic).  Updating a display at 2 kHz seems unreasonable.

 


The error you receive tells you that at least one sample clock has occurred between calls to wait for next sample clock.  Essentially this is feedback telling you that your loop is not running as fast as your sample clock.

 

Hope that helps,

Dan

0 Kudos
Message 2 of 10
(5,543 Views)

Hi Dan,

 

Cheers, clarifies a lot. I indeed have to drop update rate of the graphs.

 

Do you know if the indicators in the subVI also influence loop time significantly? 

I have been looking for a way to get rid of them in the subVI but apparantly then you lack the possibilty to select that data as an output line on your VI.

 

Could I use continious acquisition to achieve a higher sample frequency still being able to create an analog output depending on the analog input signal 

with a reasonable (<50 ms) delay? I am not really sure about how harware timed acquisition relates to continious acquisition.

 

Mark

0 Kudos
Message 3 of 10
(5,536 Views)

Mark,

 

The indicators in the subVI would only slow things down if you have the front panel of that VI open (LV would then need to update the indicators).

 

Could I use continuous acquisition to achieve a higher sample frequency still being able to create an analog output depending on the analog input signal 

with a reasonable (<50 ms) delay?

This really depends on the needs of your application.  How often do you need to update your output?  How does this output need to be synchronized with your input?

 

Dan

0 Kudos
Message 4 of 10
(5,532 Views)
Hi,
The output update rate needs to be as high as possible. The application will be used in a action-reaction type of manner. Compare it with a controller. The ai should control the ao as good as possible f.e. A 1 volt input should lead to a 3 v output asap. It is ment to be controlled by a human so the more responsive it is to the smallest changes in time the better.
Hope this makes sense.

Thanks again.

Mark
0 Kudos
Message 5 of 10
(5,529 Views)

Hi All,

 

As suggested I did implement the producer / consumer structure (see attached VIs). 

However, same problems as described in start post persist. 

 

The goal of the code is to generate two AO signals dependent on two AI signals. The AO should follow the AI

with the slightest delay possible, preferably in the order of a miliseconds. Some simple processing is done in between.

The more responsive it is the better, and so a high sample rate it preferred (>= 1000 Hz). We use a BNC-2090 with PCI-6024 DAQ Card.

 

Anymore suggestions? (I tried a lot in recent days but strangely the current code doesn't allow me to esceed a sample rate of 10 Hz to function properly).

 

Thanks,

Mark

Download All
0 Kudos
Message 6 of 10
(5,515 Views)
Solution
Accepted by topic author MLVDR

Mark,

 

I think that hardware timed single point is appropriate for this application, however, I suspect that you'll have issues running above 10s of Hz on Windows without eventually seeing errors such as -209802 as the OS itself may decide to suspend your application for unpredictable amounts of time.  I would recommend that you take the remaining waveform chart out of your IO loop.  I would recommend that you throttle back your display loop a little bit, as it will still pull data out of the queue and update displays as quickly as possible.  I would think that adding logic to wait for a certain number of elements to be present in the queue before dequeuing and displaying data may be reasonable.  If you do this, you'll also wait to add 'wait' function in this loop so that you're not polling the queue and using up as much CPU as possible.

 

With hardware timed single point, DAQmx will always return the newest sample.  This means that if your loop runs slowly, you will lose some samples.  If this is acceptable for your application, then receiving the -209802 error may not be important.  You can use the DAQmx real-time property node's 'Convert Late Errors To Warnings' property to make this a non-fatal condition.

 

My final suggestion is to determine which parts of your code are taking the longest to execute.  If you know where you're spending your time, it may point you toward places where you can optimize and remove some execution time.  To do this, you can try removing some parts of the logic and seeing how this affects the loop rate you're able to maintain.

 

Hope that helps,

Dan

Message 7 of 10
(5,505 Views)

Mark,

 

I had one other idea... If I remember correctly, when using wait for next sample clock DAQmx should allow you to specify how it should wait.  I believe that for E Series devices, by default, DAQmx will wait for an interrupt from the device to indicate to it that a sample clock has occurred.  This is often good in terms of CPU usage, however, it is not the most efficient operation.  To change this, you can use the DAQmx Real-Time Property node to set the 'Wait For Next Sample Clock Wait Mode' to 'Poll'.  This may get you a little more performance out of your I/O loop.

 

Hope that helps,

Dan

0 Kudos
Message 8 of 10
(5,499 Views)

Hi Dan,

 

Thanks for your replies!

The problem has been solved and all seems to work fine. Need to run some full tests yet but it looks promising.

 

I do however have an interesting notion on the subject.

It turned out that the Dequeue element block introduced problems in the code. I replaced the Dequeue element for Release queue block

and just took out the final element each time the logic went true, as you proposed, and passed it on to my graphs. 

However, when I started to turn down the requirement for my logic to become true (started with 100 elements in the queue) I found

out that it can keep up even with reading every single element a time without giving any errors. 

This hugely surprised me and points to some issues with the dequeue element block in my code.

 

Another note: If I make the requirement of my logic feedback to update slower than each 100 elements being available in the queue it crashes with the usual 209802 error.

For some reason it doesn't like the queue to get bigger than a 100 elements.

 

Nonetheless it works! If you have any thought about these issues I'd like to know what you think, just curious.

 

EDIT: I didn't implement any of your other suggestions apart from the logic to decrease graph update rate and changing the method to dequeue.

 

Many thanks,

Mark

0 Kudos
Message 9 of 10
(5,484 Views)

Mark,

 

I was under the impression that release queue closed your reference to the queue, and would prevent data from either being written to or read from the queue on future iterations.  If you want to read multiple items from the queue, I believe that 'Flush Queue' can be used.  This will return an array of all items that are in the queue.  In your graphing loop, I imagine your logic would look like this:

 

1) Get Queue Status

2) If # elements in Queue < threshold, do nothing or wait for some number of milliseconds

3) If # elements >= threshold, flush queue and display data as required by your application.

 

Glad to hear that things are working for you.

Dan

0 Kudos
Message 10 of 10
(5,478 Views)