Jump to content

coordinating interfaces


merlin

Recommended Posts

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).

post-1543-1132579968.jpg?width=400

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

Link to comment

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

Link to comment

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:

post-1543-1133185627.jpg?width=400

?
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

Link to comment

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

Link to comment
  • 2 weeks later...

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??

post-1543-1134395619.jpg?width=400

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

Link to comment

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.

Link to comment
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?
no
Is 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

Link to comment

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".

post-1543-1134486991.jpg?width=400

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".

Link to comment

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.

Link to comment
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

Link to comment
  • 2 weeks later...
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.

Link to comment
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.

Link to comment
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.

post-2-1136884541.gif?width=400

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.