merlin Posted November 21, 2005 Report Share Posted November 21, 2005 Hi, i really don't know, if this can be understood as "Large Application", so i'm sorry, if not. I'm working together with another student on a control application. Each one of us has to control some signals. Both projects could run independently but we have to integrate them. What i've done so far: the io-parameters are stored as globals (so first question would be: is that the most wise thing to do?), inside the main-vi there should be at least four sub-vis running simultaniously: INPUT, OUTPUT, FORCE-Control (my part) and SPEED-Control (his part). My second question is concerning handling the interface: FIRST OPTION: Each Control (FORCE and SPEED) has it's own interface that covers half of the monitor. This way they are integrated within Subpanels. I should mention, that the user should be able to switch from automatic-control to manual control (for both controls). This would mean, that everyone of us, has to make two different sub-vis (auto and manual). SECOND OPTION: We build one vi, that controls all of the interface, but it has to rely on (again) global variables, that are being passed by each of our controls. That means, that the interface is being set every x msecs. I hope, that i made clear what the problem is and also hope, that some of you could give me some hints.. cya and thnx. merlin Quote Link to comment
DredPirate Posted November 21, 2005 Report Share Posted November 21, 2005 First, do not use global variables. They make maintenance and debugging a nightmare. Not to mention they are terrible on resources. If you have to use globals then look up LV2 style globals. If your program is structured correctly you should not need them except for a few special cases. Which brings me to number 2. Your main issue seems to be program structure (or lack of). Look up state machines. This is the best way to program in LV. Also make sure your file structure is well defined (do not use LLBs. They strip the file structure and offer nothing in return but bugs. There is a post on this subject.). Look at the program I've provided for an example of how to structure your code and files. Notice the parallel loop for your DAQ. I did this because of the fast update times (X ms) you require. GUI's can be slow especially when you add graphs. Running them in parallel loops can sometimes help keep your critical programs from locking on slower operations. However, try to limit the number of parellel loops in a program and make sure all of your loops stop with the exit button. (BTW Quote Link to comment
merlin Posted November 28, 2005 Author Report Share Posted November 28, 2005 Hi, First, do not use global variables. They make maintenance and debugging a nightmare. Not to mention they are terrible on resources. If you have to use globals then look up LV2 style globals. If your program is structured correctly you should not need them except for a few special cases. As you noticed my main problem is that READ - CONTROL and WRITE have to run completely independent. So i need all the data (both input and output) to be "global". I am still looking into that LV2-globals and i found these two pages about it: A small explanation: http://www.icon-tech.com.au/faq_blockdiagram.html#LV2Globals A small example: http://physics.wku.edu/phys318/notes/n07.html In the example-page i find: Built-in global variables (discussed below) are preferred over LV2 style global variables (in plain vanilla form like above) because they are faster and more efficient.Nevertheless, even if this is out to debate, i like the LV2-method because apparently i don't need any sznchroniyation (i.e. samphores..).But do i really have to build an LV2-global for each variable i need? Since some variables have to be read/written at the same time, is it "ok" to change the lv2-structure to something like this: ?Your main issue seems to be program structure (or lack of). Look up state machines. This is the best way to program in LV. I think i understand what a statemachine is, but i don't know where i should be using it in my special case. Mind you the iterations of READ, WRITE and CONTROL aren't the same iterations. Also make sure your file structure is well defined (do not use LLBs. They strip the file structure and offer nothing in return but bugs. There is a post on this subject.). Look at the program I've provided for an example of how to structure your code and files. I only got LV7.0, so i can't look into this file. Thank you very much. At least the LV2-globals will help me. If you got any more tips, please don't spare me. cya. merlin Quote Link to comment
PJM_labview Posted December 1, 2005 Report Share Posted December 1, 2005 Merlin, Attached is a simple, yet powerfull, Queue Message Handler "State Machine" template in LV 7.0 While it does not have parallel loop, it is very flexible and allows synchronous process servicing using the timeout frame of the event structure. In most case this is sufficient. You might want to search the following presentation on NI website: "Application Design Patterns in LabVIEW" to get you started in state machine and queue state machine. Good luck PJM Download File:post-121-1133453194.vit Quote Link to comment
merlin Posted December 12, 2005 Author Report Share Posted December 12, 2005 Hello everybody, i am still trying to rap my head around the idea of the state machine. My problem consists in that my "states" are neither sequential nor do they (normally) "know" what other state should follow them. would you please look over my structure "plan" and tell me especially if it's ok to (ab)use queues for determining the "next" state of the state machine in this way?? The small subvis at the bottom should set a queue item with a defined name, so that "DECIDE" can decide which state to go into next. Since the frequency with which DECIDE is executed is much higher than the frequency of the other states (100ms, 200ms, 500ms and 1s) this should ensure, that there isn't much delay between Queue setting and execution of desired state. In general i could use user events instead of queue and in that case i won't need DECIDE to run every x ms. By the way, what about the interface in this scenario, should each control handle the interface or is it wiser to let one extra state update the whole interface? Another question: what is better in this case using shift registers or LV2-Global variables to transport the variables (IO-acquired and to-write Data) between states?? And please do ask, if the grafic or the text isn't comprehendable. cya and thnx. merlin Quote Link to comment
WMassey Posted December 12, 2005 Report Share Posted December 12, 2005 Just some random quick thoughts... Are the four subVIs at the bottom driven by strictly by timers or by events? Does one have priority over another? Is there any race condition you need to watch out for? Have you thought about incorporating them directly into the idle state of the DECIDE structure so that there didn't need to be communication between them and DECIDE? If you do choose to go with queues, you don't need the DECIDE structure to loop - just make it hang on a queue read operation. As far as the control interface goes, it depends on its complexity and what you are trying to do. Go with whichever method is simpler and easier to understand. If there is no reason to use the data outside the DECIDE structure then definitely go with the shift registers. Quote Link to comment
merlin Posted December 13, 2005 Author Report Share Posted December 13, 2005 Are the four subVIs at the bottom driven by strictly by timers or by events? timers, but the timer frequency could change. Does one have priority over another?noIs there any race condition you need to watch out for? could you please explain? Or link to some ressource?? Have you thought about incorporating them directly into the idle state of the DECIDE structure so that there didn't need to be communication between them and DECIDE?I don't think this is possible, since the timer needs to be running all the time, even if another state is running.If you do choose to go with queues, you don't need the DECIDE structure to loop - just make it hang on a queue read operation. can i make a timeout to such an operation? I need this so i can check for "hanging" hardware (or software for that matter). As far as the control interface goes, it depends on its complexity and what you are trying to do. Go with whichever method is simpler and easier to understand.The interface consists of two or three graphs (!) and some controls (for pid-controller) and perhaps some numeric indicators.If there is no reason to use the data outside the DECIDE structure then definitely go with the shift registers. Thanks man. now at least i can start coding. cya. merlin Quote Link to comment
merlin Posted December 13, 2005 Author Report Share Posted December 13, 2005 I have yet another question: I'm trying to avoid the vi from stopping before i deinit all open io-sockets and write every ini-file and so on. To achieve that i created an "EXIT"-state, which should be queued, when the event "Application Exit?" is triggered. Though i linked "Discard?" to "False", the program is still stopping before "asking my permission". Could someone help please? merlin PS: Nevermind that you can't see the stop sign or that the subvi (which closes the sockets) hasn't got a nice icon, i'm still justing "testing". Quote Link to comment
WMassey Posted December 13, 2005 Report Share Posted December 13, 2005 Well, if the four external loops are strictly timer driven (no events) and if there is no priority associated with one over another then you may not need to worry about a race condition. A race condition is where you are expecting things to happen in a certain order but because of unexpected circumstances or very closely timed actions, something occasionally happens a bit out of order. If you don't ever care if one action just barely sneaks in and happens before some other action on an occasional basis then you don't need to worry about a race condition. Yes, the dequeue element (or preview queue element) function can have a timeout specified and will set a flag if a timeout occurs. One other thing that may help you to decide how you want to handle your GUI is the frequency that you need to read various controls and write to various indicators. Actually the reading of all the controls should be handled by an event structure (with a short timeout event of its own) that would be integral to your state machine. If all your indicators are to be all updated together then that may be a good reason from grouping all the updates in one or more contiguous states (more complex updates may deserve their own states). If on the other hand some of the indicators only need to be updated infrequently then that may be a good reason to handle the updates just whenever the associated data actually changes. You mentioned graphs. If you want the data displayed on all of them to grow together then update them all at once. If you want the data displayed to grow at a rate that makes sense for the individual data streams, update them independently as needed. Quote Link to comment
WMassey Posted December 13, 2005 Report Share Posted December 13, 2005 I have yet another question:I'm trying to avoid the vi from stopping before i deinit all open io-sockets and write every ini-file and so on. To achieve that i created an "EXIT"-state, which should be queued, when the event "Application Exit?" is triggered. Though i linked "Discard?" to "False" TRUE, the program is still stopping before "asking my permission". Well it kind of hard to tell what you are doing wrong if you don't include a working VI fragment that demonstrates the problem. The only thing wrong I can see from the screenshot you included is that there is no way to terminate the external loops and no way to recycle the event structure once you activate it the first time. Perhaps the pair of them is what is causing the behavior you are seeing. One click of the Terminate takes you out of the event structure (and is discarded) but doesn't stop the external loops and a second click of the Terminate then stops everything immediately because it is not discarded. See the attached VI for an example of something like I think you are trying to accomplish that seems to work. Download File:post-2800-1134513509.zip Quote Link to comment
merlin Posted December 27, 2005 Author Report Share Posted December 27, 2005 Well it kind of hard to tell what you are doing wrong if you don't include a working VI fragment that demonstrates the problem. The only thing wrong I can see from the screenshot you included is that there is no way to terminate the external loops and no way to recycle the event structure once you activate it the first time. Perhaps the pair of them is what is causing the behavior you are seeing. One click of the Terminate takes you out of the event structure (and is discarded) but doesn't stop the external loops and a second click of the Terminate then stops everything immediately because it is not discarded.See the attached VI for an example of something like I think you are trying to accomplish that seems to work. Hi Wmassey, first i would like to thank you for the example file. Very useful. I still have a problem: When the user clicks on the abort-button (or types Ctrl-[dot]), there is no question of wether he wants "really" to exit.. Doesn't that fire an event? I think i understood the strategy of deleting the queue and thereby declaring that the vi has to be closed. Nice. thnx. merlin. Quote Link to comment
WMassey Posted December 27, 2005 Report Share Posted December 27, 2005 Hi Wmassey,first i would like to thank you for the example file. Very useful. I still have a problem: When the user clicks on the abort-button (or types Ctrl-[dot]), there is no question of wether he wants "really" to exit.. Doesn't that fire an event? I think i understood the strategy of deleting the queue and thereby declaring that the vi has to be closed. Nice. thnx. merlin. No, the abort button/function does not have an event associated with it. FWIW this same topic was discussed over here. I think that the best you are going to be able to do is to hide the abort button if you don't want the user using it. You can do that either through the VI setup properties or a VI property node. Keep in mind that, before you hide the function, your VI needs to be bulletproof in the way it operates because you won't have a good way of stopping it (other than the three-finger salute [Ctrl/Alt/Del]) if it misbehaves. Quote Link to comment
merlin Posted January 3, 2006 Author Report Share Posted January 3, 2006 Hi, i have changed the position of the question (whether one wants to _really_ exit) so that it doesn't interrupt the statemachine. i am including a zip file with the vis this far. Thanks for the advice and a happy new year. merlin Download File:post-1543-1136301974.zip Quote Link to comment
Michael Aivaliotis Posted January 10, 2006 Report Share Posted January 10, 2006 No, the abort button/function does not have an event associated with it.No, the button does not have an event however for us developers who like to use Ctrl+Period, there is still a way to have your cake and eat it too. You can hide the button bar and trap the Ctrl+Period event. This allows you to terminate gracefully even though you are a hardcore Ctrl+Period user. Another nice perk about this feature is that when built into an exe, the APP_STOP menu event goes away automatically. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.