I have several physical channels for DaqMX (three analog input channels and three digital output channels) that I would like the user to select upon initialization of the executable file, before the program begins to read from each channel. My plan is to use a "Value Change" event structure to do this, but I'm open to other ideas if there is a better way.
My issues is that I want the event structure to only perform the event if all six channels are selected. But the event structure executes only if one channel is selected: Select Channel 1 OR Select Channel 2 OR Select Channel 3 OR Select Channel 4 OR Select Channel 5 OR Select Channel 6. I would like the event only to take place if ALL of the channels are selected: Select Channel 1 AND Select Channel 2 AND Select Channel 3 AND Select Channel 4 AND Select Channel 5 AND Select Channel 6.
What is the best way to achieve this? I've attached my code for reference, and an image of the specific area that I am looking to do this. I also found an older thread below that is the exact question that I am asking, but I had a hard time interpreting the answer related to the shift register. If someone understands, would they be able to provide example code?
Solved! Go to Solution.
Create a button to apply the changes but set it so that the button is only active when all 6 channels have a value.
Event structures respond to events. A user changing a value is an event; changing all 6 values is 6 events, not one.
The most direct way to do this would be to put your event structure in a loop with a 6-element boolean shift register initialized to False. Each time the user changes a value, set the corresponding boolean to True, and loop again. After each loop, check if the whole array is True (use the "AND Array Elements" function). If the result of that is True, you can continue.
As far as the rest of your program goes, you have a few issues that won't be hard to fix:
-It's quite hard to read being one massive vi; you should look to placing re-used code into subVI's and striving to keep all block diagrams within one "screen".
-It's generally a bad idea to use sequence structures if you can avoid it. Use Error wires to enforce flow control of your initialization section.
-The 2 second wait isn't doing anything there- nothing is waiting on that to continue, and in this instance the panel won't move on until all subVI's or property nodes have executed.
-That whole structure is actually in *parallel* to the rest of the structure, and it'll execute at the same time as the rest of the code. Don't forget; just because it's to the left doesn't mean it executes first. If you need that to be done first, use Error wires to enforce flow control.
This won't get your "blocking" behavior you want but it shows an example of "do this before this other thing happens".
I would also use the a button to accept the configuration. When that button's value changes, just verify the channel selections are valid. If they are, stop your loop. If not, display an error message and loop back.
Thank you for the feedback.
Bert, thanks for the additional input as well. Firstly, I added the shift register technique that you described. I also added in the case structures for each shift register to ensure that the values would remained changed once a channel was selected. This seems to work, as when I use highlight execution, selecting all of the channels results in a "true" value going to the stop button in the while loop. For some reason, even with the true value going to the stop button in the while loop, the code does leave the while loop and does not continue to the daq mx tasks, do you know why this is happening based on my attached code?
To address all of your other points:
- subvis are a good idea to make the program more readable, I will plan to use them once I have this coded working as intended.
- I removed the sequence structure per your advice and use error wires. I passed the error wire through the while loop with the event structure to control the flow, this should flow to the daq mx controls once the while loop with the event structure is terminated correct?
- I removed the 2 second wait for now. The only reason I had that is because I plan to use this as an executable that automatically runs when the program is opened. The 2 second wait would allow the message from the "display message to user" to slightly delayed just for aesthetic purposes.
- point taken, I think the error wire flow I have now should control the flow well.
Looks like you're making some progress. The shift registers are a good way to do this but you don't need all of the case structures- just wire the shift registers through the Event structure. Better yet, use one Shift Register and an array.
Your issue with flow not happening is that you're reading the *previous* loop's iterations of the buttons; you need to build your array after the loop's "Read", currently you're doing it beforehand. Generating one more Value Change event causes your structure to work.
For continued discussion on the other points:
-SubVI's aren't just to make it readable, it's to make it *functional*. You should start with subVI's, not try to make it all work then try to convert it over. Trust me on this one.
-The error wires are now used properly, though there are a ton of them. This would be a good case for a single frame of a sequence structure with a single error wire flowing out; use the frame to enforce all of them firing before anything else happens, then the error wire takes over flow control.
-A 2 second aesthetic wait can be nice, but beware that your program will be unresponsive for 2 seconds without notifying the user of anything. This can be frustrating depending on how you implement things.
-I like to right click my terminals and unselect "View as Icon"- it makes things MUCH smaller.'
The other poster above had a good idea; instead of trying to make the user change each control before they start, have a single Start button that checks all of the values. If the values are all OK (maybe compare each to an empty string) then it lets you move on; if not, it tells you to fix things.
At any rate I have some code that shows how the array based shift register works and how you can make things much smaller, but I'd really suggest a "Start" button or some other way to initialize things rather than forcing the user to change values at program startup.
If you didn't know you can drag/drop this image into LabVIEW and it'll make it real code. It's called a "VI Snippet" and it's much easier than sharing whole VI's when you're just trying to debug parts of the code. You can highlight a section of code, then go to Edit-> Make VI Snippet to save a pic like this, then upload it as an image.