05-08-2019 01:31 PM
Hello all. I am very new to LV, so bear with me. I know I can probably clean a lot of this up with Arrays, etc., but I will improve as I get it working.
So, I have a program to control a 4 channel power supply, and by clicking a button, I want to be able to record the Voltage and Current on each of the channels at a regular interval, and simultaneously write the values to a .csv or .txt file.
So, where I currently am, I can start the recording, but then it seems that I get caught in some sort of loop, as I am unable to stop the recording. If I hit Stop and restart the program, then it won't start recording the next time, but if I click on the Abort button, then it will start recording, but then never stop. I initially had my recording loop within my case structure, but read that is not doable. I looked into various state machines and the producer/consumer method, but not sure if this is what I need.
Can someone give me insight on what I am doing wrong?
Thanks,
Mike
05-08-2019 04:16 PM
Wow! Your Block Diagram takes 12 monitors (four across and three down) to see all at once! No wonder you can't "do it right". Here are some (important) suggestions:
Bob Schor
05-08-2019 04:39 PM
@Bob_Schor wrote:
- Get rid of all local Variables.
... and don't replace them with value property nodes to make things even worse. (look at the "start logging" value property node, in the lower left, for example. Not good! 🐵
(You can potentially keep some local variables to maintain data between parallel loops, but often there are better ways.)
05-08-2019 04:47 PM
@Bob,
Thank you for your reply. I will start working on that now. Based on the functionality I am looking for, would I be leaning my research towards the Master Slave design pattern? I was thinking State Machine, but then the more I read about it, it doesn't seem to fit.
I will report back with cleaner code soon... Assuming I don't break something. 🙂
Thanks again,
Mike
05-08-2019 05:11 PM
@BOB,
So, I get the wiring for the power with Shift Registers now, but if I just run a Boolean False to the necessary places, I see how that will send the value where needed, but how to I change the state of each of the Power buttons without leaving the Local Variable (write) to each one in place or using Property Nodes?
Thanks again,
Mike
05-08-2019 09:41 PM
I'm thinking State Machine, myself. Note that an Event Structure can be in one State, particularly if you give it a short TimeOut (say 1 msec) so if there is no "Real" Event pending (to send it to the State to process the Event), it can go to the "No Event To Process" State (if you have such a thing).
Or you can use the Queued Message Handler, which the Purists will (probably rightly) say is Not a State Machine, but if you are not sloppy about it, sure can be made to act like one. If you do this, you can have the Event Loop running in parallel with the QMH and without a TimeOut, so it only sends a Do This Now message when there is something it needs to do. [You need to think how to safely Stop the Event Loop -- I suggest User Events).
Bob "I Do It With Channel Wires" Schor
05-16-2019 07:48 AM - edited 05-16-2019 07:50 AM
Ok, so I consolidated the code a little (fewer screens) . I ended up going with notifiers (because I found an easy to follow tutorial). Everything seems to be working fine, although I am having an issue when I hit the Stop button, that I am getting the following error (and the VI never stops):
Error 1 occurred at Release Notifier in PS_Control_v2.vi
Possible reason(s):
LabVIEW: (Hex 0x1) An input parameter is invalid. For example if the input is a path, the path might contain a character not allowed by the OS such as ? or @.
=========================
Command requires GPIB Controller to be Controller-In-Charge.
I am assuming that I am shutting things down in the wrong order, or something. Any suggestions? Also, please excuse all the random Indicators; using them to try and see what is going on. 🙂 Also, I don't know how to get rid of the local variables, when I am trying to use them to read the state of various items.
Thanks,
Mike
05-16-2019 08:21 AM
Yes. You actually have 2 problems.
1. You failed to wire your notifier reference through all your cases and used a "Use default if unwired" tunnel. Change that. When your stop button runs, that case in particular is missing the reference wire, so you wind up getting a default empty reference that throws the error when you try to release the notifier.
2. That Release notifier shouldn't be right after you main loop. The problem is that if you had the tunnels wired properly, you'd release the notifier, but the loops waiting on the notifier would throw errors when the reference goes invalid. You should only release notifiers after ALL loops have completed execution.
05-16-2019 09:33 AM
Thank you so much for the reply. I fixed the tunnel issues. Learn something new every day. 🙂 Now the VI stops.
In reference to the Release Notifier (No. 2), I am not sure where it would need to be moved to. I tried moving it after the second loop, but then the program just hangs again when I press Stop. I moved it back to the first, rearranged some of the error handling, e.g. running the Wait On Notification error out to the While Loop Stop on the second loop. I got it going, although I am sure that I am missing some error catching opportunities. I need to work on that flow next. FYI, I was trying to use this page as my reference... https://forums.ni.com/t5/Example-Programs/Master-Slave-Architecture-Using-Notifiers-With-Two-Slave-L...
Attached is the updated VI.
Thanks again,
Mike
05-16-2019 03:04 PM - edited 05-16-2019 03:11 PM
Your VI still shows the Release Notifier after your event structure loop.
I truly don't understand how you are using the Notifier. I see you create it and pass the references to both loops. In your event structure loop, you never use the reference. So nothing ever changes. Your notifier is based on strings, but you don't ever send any strings.
I your slave loop with the state machine, your notifier is set with an infinite timeout, so if it never gets a new notifier, your loop will stall there. The only thing that keeps your loop from stalling in what you have now is that when you end the master loop, you release the queue, that kills the reference. The slave loop throws an error and stops its loop causing the code inside to only iterate one time. And that will be the empty default case because you never sent a string notification.
Try running your code with highlight execution turned on so you can see how it executes. Then go back and look at the examples for notifiers again. I"m not sure you even want a notifier, Perhaps you want a queue. Perhaps you don't need either.
Also, your VI is very large. It takes up a lot of screen space that could be greatly reduced by combining segments of code into subVI's. In one section where you configure something, you have a string of a dozen of the same VI called with slightly different parameters. You could put that in a For Loop and auto-index over an array of values and inputs. Less functions, less wire, a lot less screen space.