09-03-2013 01:47 PM
Hi,
I have a tough problem that I hope LabView would allow me to solve easily:
I have an n-channel data acquisition stage where each of the channels could be one of the several possible types of signals. Let's say we have two types of signals - A and B - and that we have 8 channels each of which could be of type A or B as configurable by user. I want a FOR loop looping over all the signals and depending on their name (A or B) going into a case structure and doing stuff, like this:
Now, imagine that "DO SOMETHING" is a subVI - "vi_A" for type A and "vi_B" for type B and that it needs to filter the signal.
Here I have a problem: the LabView cannot know that (for example) signal 1 being of type A and signal 6 being of the same type A are actually two different signals and the same instance of "vi_A" with the same instance of filter will be called. I need to be able to tell LabView to allocate a different instance of "vi_A" for different channel numbers above!
Is there a way of achieving this? Could I, for example, preallocate 8 instances of "vi_A" and "vi_B" and use those preallocated instances by reference or something like that?
Thanks a lot in advance!
09-03-2013 01:55 PM
You will want to go into the properties of the VI and set preallocated clone reentrant execution, under the Execution Properties category. Then, you can use uninitialized shift registers to store your data buffer between calls.
09-03-2013 02:07 PM
@for(imstuck) wrote:
You will want to go into the properties of the VI and set preallocated clone reentrant execution, under the Execution Properties category. Then, you can use uninitialized shift registers to store your data buffer between calls.
Thank you. Preallocated clone reentrant execution doesn't help, to the best of my understanding: because the entrance to the subVI "vi_A" happens in the same place on the block diagram, LabView doesn't know that it need to allocate a new instance of vi_A for channel 8 separate from the instance already allocated for channel 1. I actually tested this, which is why I am pretty sure about this. LabView will use the same clone it created the first time.
Maybe I am not understanding your solution fully. Not sure, for example, why I would need shift registers. As far as I understand, a filter has its own buffer where it stores the coming signal. Are you suggesting for me to replace this with my own buffering?
09-03-2013 02:16 PM
Please attach a copy of your VI so we can understand your problem.
Cameron
09-03-2013 02:30 PM - edited 09-03-2013 02:31 PM
Here you go:
And attached.
I want the "output array" to contain 8 (or however many channels I have) distinct signals. As I understand it, currently the filter will be mixing/confusing all the signals of type A and all the signals of type B.
Thanks in advance!
09-03-2013 02:41 PM
OK, I have to assume here that your input contains N separate waveforms, each with its own ChannelName and type (attribute) A or B?
Just move your output outside of the for loop, make sure indexing is on, and you'll have N separate filtered waveforms, without having to clone anything.
Cameron
09-03-2013 02:48 PM
@camerond wrote:
OK, I have to assume here that your input contains N separate waveforms, each with its own ChannelName and type (attribute) A or B?
Just move your output outside of the for loop, make sure indexing is on, and you'll have N separate filtered waveforms, without having to clone anything.
Cameron
Correct on your first assumption.
But I am pretty sure you are incorrect stating that I will have N separate filtered waveforms, even if I move my filter outside. Filter has a buffer, and in my tests (on a larger and more complicated VI) LabView will create only 2 instances of the filter and each time you call case A it will be the same filter it used for case A last time. So, yes, I will get 8 waveforms, but they will be junk, because the filter mixes pieces of different channels of the same type.
Now, if instead of the filter I had a subVI that is preallocated clone-reentrant, then you'd see that each time a case "A" is called the same clone is opened and each time case "B" is called a separate clone - but the same for all "B" cases - is opened. This is the problem I am talking about. Filter is just an example - I need the clones to be distinct for each channel, not for each type of channel.
09-03-2013 03:17 PM
Could you throw me some data so I could make sure of just what you mean?
Cameron
09-03-2013 03:21 PM
Let me see if I can create a dummy VI quickly enough. Right now I am exploring a possible solution I stumbled upon, so, it takes most of my time now. If I have a moment, I will put something up.
Thanks a lot for the help!
09-03-2013 06:30 PM
You cannot do this as easily as you'd like. The solutions that come to mind are:
1) Pull apart the filter (or whatever) VI so that you can pass in the state, then save that state in a shift register.
2) Actually allocate a new copy of the filter VI and call it dynamically, using Open VI Reference.
Neither of these approaches will work with the Filter Express VI that you show in your image; they'll both require digging into more LabVIEW programming.
It would be better to use a shift register around the for loop, instead of a local variable. It's likely that you don't even need the replace array subset at all, and you could just use auto-indexing on the border of the for loop (wire the output of the case structure directly to the for loop border) and then put the indicator outside the loop.