Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Read Analog input channels in multiple VIs

Hi,

I have designed some hardware with 2 test slots running off a PCI-6021 DAQ Card.

I wanted to write a single VI to run the test, paste two copies of it on the top level VI and pass the appropriate channels to it for each test slot.

I am just measuring some voltages - so I don't need to acquire lots of data that will block execution.

I also wanted another loop to measure the input voltage to display continously on the front panel.

 

Is there any way to achieve this with LV8.6 & DAQmx?

I have tried creating a task and then creating and reading analog voltages in parallel - but it produced errors. (Resource is in use.)

I understand that the ADC can only do one read at a time but I would have thought it would  be possible for the read to block until a read had been performed elsewhere.

 

Can you please sugest a  way to achieve this or how to change the structure of my program to make it easier?

 

The attached files show what I was thinking for a structure. (I saved them for Version 8). Yes they are quick hacks but should give you the idea of what I am trying to do.

 

Thanks for your help.

 

Cheers Nick

 

0 Kudos
Message 1 of 12
(5,913 Views)

"I understand that the ADC can only do one read at a time"

 

So only do one read at a time but with multiple channels. A single task can have multiple channels and that is the only thing you can do.

Message 2 of 12
(5,903 Views)

Nick,

 

You are getting the error because you are trying to run two Analog Input Tasks at the same time.  The Task State Model will not allow that to happen.  You will need to create a task that with both AI channels in it at the top level and then pass that reference to the individual DAQmx reads.

Message Edited by centerbolt on 10-07-2008 09:38 AM
Message 3 of 12
(5,900 Views)

 

Thanks guys- got it now...

I have attached a working example for reference.

0 Kudos
Message 4 of 12
(5,849 Views)

Hi All,

 

Sorry to drag up an old(ish) thread. But the original poster was (I think) trying to do something similar to what I need to do... In Nick's case, he wanted one DAQ task with two channels which he wanted to read in parallel in separate parts of his code. 

 

First up, Nick said he'd solved his problem, but looking at the final example, I don't think it's technically correct - I think you're losing half of the data. The top loop reads 1000 values out of the buffer - but its reading both channels so the second channel data is effectively lost. The bottom loop then reads out the next 1000 values, again meaning that 1000 data points from channel 1 are essentially lost. I think for this to work correctly, you'd have to use the DAQmx read property node to select which channel to read from and the relative to and offset position (within each loop, prior to each DAQmx read), although quickly looking at that seems to indicate you can only do this if you have a global channel set up (I don't know anything about those yet)! But this leads me to my next problem:

 

The daq tasks and in particular the daqmx read property node doesn't appear to me to be "multithreading"... What I want to do (which differs slightly from the OP) is to have one DAQ task with a single channel acquisition, but read back from it "differently" in different parallel loops. I've attached an example to better show what I'm trying to do...

 

My code should configure the top loop to only read back the latest value from the buffer and the bottom loop to acquire 20 data points relative to the current read position (which is updated by the shift register). With a simulated DAQ device set up (USB6211), the analogue input returns a slowly varying sinusoid. So the top loop should reproduce that, whilst the bottom loop should also reproduce a sinusoid but one which appears on the indicator to progress more slowly than the top one (you can see why in the code - the bottom loop is limited to take a minimum of 30 ms, but only reading back 20 ms worth of data on each iteration). What actually happens is quite different! The top loop does show a sinusoid but with random "glitches" which turn out to be "cross talk" between the loops - the DAQmx Read VI uses the properties last written to the task, which may actually be the properties from the other loop (since there is still only one task!)! 

 

So, is there some way of "cloning" the task, or at least forcing each read vi to only accept the properties set within its loop?

Any help on this would be gratefully accepted!

 

Paul

0 Kudos
Message 5 of 12
(5,721 Views)

Well, you are correct about the final example. It's not correct to have a second loop at all.

 

Could you explain why you want two separate loops. Why is it that you can't simply acquire all of the single channel data in one loop?

0 Kudos
Message 6 of 12
(5,709 Views)

Basically, I have two different things I need to do with data from the daq task. I'm using the data to control a piece of kit (based on the most recently available sample only) and also to do a calculation and display on screen and log to disk (using all of the sampled data). I want the two tasks to run independantly since there is a time delay introduced during the control stage of the first task... And also since the calculation task only needs to be running when the user says so...

 

The way I see it, there are several possible ways to do this. One is, as you say, to use a single loop and maybe a case structure to enable/disable the logging section, but there's still the issue of the time delay introduced by the instrument control. Another way is to set up a producer/consumer architecture with all of the daq data being acquired in one loop and then passed to two other loops (via queues and notifiers) to perform the two tasks above. Finally, and I think this should be the better way (an neatest?), is to use the daqmx read property node to specify which data each of the two loops should read out of the buffer, as in my example VI. DAQmx is inherently multithreaded and the buffer doesn't care how many times you read the same bit of data, so this shouldn't be a problem. However, this doesn't appear to work!

 

The problem with this method is that you appear to need to "lock" the read property node to its associated read vi (I've managed this just now using semaphores)  otherwise, if you have two parallel loops, there is "cross talk" as the properties the read.vi uses will be dependent on the last settings anywhere in the app (which could easily be the settings corresponding to the other loop)...

 

What I'd really like is to do this without the need for semaphores (i.e. using DAQmx's much touted multithreadedness...) so if anyone can see a way to do that, I'd be grateful!

 

Cheers

 

Paul 

 

 

0 Kudos
Message 7 of 12
(5,701 Views)

The reason you are getting the errors without the use of semaphores is that because the loops operate independently you may at some points try to read or access the channel at the exact same time.  I don't believe that this is an issue of multi-threading but more an issue that you are attempting to read the same channel/task at exactly the same time which DAQmx does not allow you to do. It does however allow you to call different tasks at the same time independently

 

The use of semaphores will allow you to lock a given task and read the channel in different loops consistently without getting errors regarding to reserved resources - which I'm guessing is the error you were receiving before the use of semaphores.  Please bear in mind that once you fetch the data using the DAQmx read the data is no longer in the buffer.  My question to you then is why are you doing this? Couldn't you simply read all of the data and use some post-processing to access the necessary data that you need? If this is the case then you could simply use one daqmx read, read all the samples for each iterationof the loop,  and because you are simply sampling at 1kHz you could either use a producer/consumer loop or even include some post-processing inside of your daqmx read loop -- as long as it is simple, non computing intensive,  post-processing.

 

If you are still having problems please re-post. Thank you 

Charley Dahan

Global Account Manager
0 Kudos
Message 8 of 12
(5,681 Views)

Hi all, Ok, so it seems that you cannot read the DAQmx buffer from two "locations" within an application in parallel (i.e. simultaneously), which I suppose if fair enough, if a little annoying in this case! However... 

 

CharlesD wrote:It (DAQmx) does however allow you to call different tasks at the same time independently 

True, but not hugely useful in this case as you cannot use the same type of channel (i.e. AI, AO etc) in more than one task at a time (certainly not with the card I'm using - USB 6211 - anyway). So if you want to do two differently configured analogue inputs in parallel, you can't (at least not with one single device). Hence wanting to use one generic task and split the actual reading according to what I need the data for.  

 

CharlesD also wrote:Please bear in mind that once you fetch the data using the DAQmx read the data is no longer in the buffer. 

This statement is completely untrue (Although, admittedly, the default settings for DAQmx read do make it look like you can't read the same data more than once...)... Data is only "removed" from the buffer when it is over-written by new data (since DAQmx is using a circular buffer...). You can quite happily re-read samples as many times as you like (provided they don't get overwritten!) I've attached an example VI to show this. This is also why I thought it may have been possible to read from the buffer from two locations in parallel, which I now think is not strictly possible (it can however be approximated using the semaphore approach mentioned in the post above). 

 

Anyways, I can get around the issue of not being able to make multiple simultaneous reads of the DAQmx buffer, (using either the semaphores approach - for less loops, or the producer/consumer architecture). So I guess thats what I'll have to do! Thanks for your input everyone! (and to the OP, sorry for hijacking your thread, although I hope you read this and saw the error in your code...) 

 

Cheers Paul  

 

(Edited for layout)

Message Edited by psmorris on 02-24-2009 05:49 AM
0 Kudos
Message 9 of 12
(5,658 Views)

Hi Paul,

no problem. It has been interesting. 

Yes my solution is lossy. However for my applciation (reading mains voltage via a transducer and a couple of DC rails... it didn't matter if I lost a few samples).

But I can see how this can be a problem for some applications. (However all my applications so far have been lossy tolerent - it didn't matter if I lost some data).

 

So I didn't need to buffer the "lost" data for a later read. (Which would be pretty easy with an unitialised shift register to load the "other" channel data into and then prepend to data from a future read of the "other" channel. You would need a shift register per channel).

 

Nick

0 Kudos
Message 10 of 12
(5,642 Views)