Jump to content

Modular LabVIEW Application Development


Recommended Posts

cross-post with http://decibel.ni.com/content/thread/2532 : NI Home > Communities > Groups > Large LabVIEW Application Development > Discussions

Dear All,

I am developing a medium-sized application. I've got a camera that detects a laser beam on a wall, a system that controls this beam and a switch to change between various beams. I used a modular architecture such that a separate program controls the camera (image acquisition and analysis), separate program to control the mentioned system, and a separate small program to control the switch. Each program can be run independently and can be build as a standalone application (used a consumer-producer architecture). Once I had those three small applications (let's call them sub-programs), I've written another application to control other apps. I implemented a common queue for all sub-programs and the main one to send 'telegrams' between all of them (cluster with two enums FROM,TO and two variants SUBJECT,MESSAGE). Each sub-program continuously checks the status of the 'telegram' queue and once the message is addressed to it, the queue element is dequeued and analyzed. The sub-program then does what it was asked to do and sends back an acknowledge telegram back to where it came from (the main application waits for this acknowledge). Then the main app access the data from the subprograms (functional global or reference to controls).. but it's a different story.

Basically it all works quite nicely, but it's not perfect, and I want to change it. I've got some ideas, but I was wondering if you have any suggestions, links to a good resources or ideas on how to develop such modular (is that a good word for it?) applications. Ideally with examples, and screenshots (or LabVIEW 7.1 compatible code).

BTW. I know about

http://zone.ni.com/devzone/cda/tut/p/id/7198 - Large Application Development in LabVIEW

http://zone.ni.com/wv/app/doc/p/id/wv-160 - Software Design Architectures in NI LabVIEW

http://zone.ni.com/devzone/cda/tut/p/id/3252 - Developing a Modular Software Architecture

but it's not really what I am looking for.

regards,

Jakub

Link to comment

What are you dissatisfied with? From what you describe you have a pretty decent architecture. About the only thing I would consider changing would be to make your queues network based which would give you more flexibility in deploying your individual control programs. This would require you to actually pass program data between applications as opposed to directly referencing them via functional globals or references. Beyond that I don't see where your design is necessarily falling short.

Link to comment

One thing I programmed recently was my own version of a model-view-controller architecture. It uses an action engine/producer consumer system which is certainly nothing new. Commands are sent to the model (the engine) with queues, and if the command wants a response it can supply a notifier.

So what is new (to me, at least) is that the model is in an lvclass, and the queue is private, so no other modules can access the action engine without using a method from the class. Similarly the event structure in the same VI as the model also uses those methods so the front panel button presses exercise the exact same code available to other modules. The VIs inside the action engine are mostly private scope, so no other routines can invoke them outside of the engine.

Once it's deployed, the front panel can remain hidden forever or else it can be shown if you want to give the end-user manual control of that system.

The lvclass just contains the message queue (which is basically the controller), and the status notifier (the view), which is different from the per-action response notifier which is optional for each control message. The status notifier is updated whenever the model changes, or it can be put in a timeout case to update constantly. Other modules can call a public method which gets the latest data out of the private status notifier.

post-1764-1238006025.png?width=400

post-1764-1238006624.png?width=400

Link to comment
  • 2 weeks later...

QUOTE (Mark Yedinak @ Mar 25 2009, 03:59 PM)

Hi Mark,

Thanks for reply and sorry for my delay in response. I foolishly believed that the forum will automatically notify me about reply, and simply forgot to check it :)

Firstly I should say that I am still working on this architecture, as I develop the main application, so all those things I am writing about might be solved within say weeks.

What I'm dissatisfied with is mainly the fact that all sub-programs are waiting for the telegram by querying the "inter-process" queue status in a while loop. This lows down the message handling, and even it's just a tiny delay, sending hundreds/thousands of commands may delay the whole program.

I still haven't worked out how to lock a subprogram from receiving any new telegrams (e.g. during initialisation).

And finally at the moment the telegrams are one-directional only - the only response from any subprogram is the acknowledgement that it finished what it was asked to do. So that for me the telegram is only a message related to some sort of action (e.g. grab image from camera), and the result of this action (i.e. image) is then stored in a functional global which is accessible from main program.

The main idea I had was to create a bunch of main programs that would pretend to be a real-hardware-devices. So then I could simply implement some sort of protocol, define commands and talk to each sub-program as it was a real device. For instance to grab an image from a camera, I could then add a command to a queue (in exterme version SCPI-like command) :camera:image:snap, and only camera interface would run this command returning ACK.

I am curious if there is anyone who came up with similar approach. At the moment I am trying to work out in details LabVIEW Queued State Machine Architecture by expressionflow.com : http://expressionflow.com/2007/10/01/labvi...e-architecture/

Below some screenshots of my implementation:

Telegram queue (from,to,subject,message) :

post-3288-1239118830.gif?width=400

Telegram send & wait for ack

post-3288-1239118840.gif?width=400

Receive mechanism in a subprogram:

post-3288-1239118849.gif?width=400

Jakub

Link to comment

Are you using a single queue to communicate with all of your spawned tasks? If so, I would recommend that you use a separate queue to send commands to each subtask and then a single queue which all subtasks use to send information back to the main controller. If you do this you will eliminate the need to poll your queues since any message received will be for that task. Using this approach will mean that everything will be event driven and you will not require polling. When a task waits on a queue nothing happens until a message gets posted. If you need to communicate directly between two tasks you can have a message that the subtasks use to request the queue name for the desired task and your main application could then return this information to the subtask.

Also, queued state machines are very powerful and we use them quite extensively in all of our applications. They are well worth your time to learn.

Link to comment

QUOTE (jcz @ Apr 7 2009, 07:41 AM)

If you use a separate queue for each object, then you don't need to poll the queue status.

QUOTE (jcz @ Apr 7 2009, 07:41 AM)

I still haven't worked out how to lock a subprogram from receiving any new telegrams (e.g. during initialisation).

If you use a separate queue for each object, each subprogram (object) will not process subsequent queue messages while any other message is being processed. This includes the initialization message. By using separate queues, each subprogram can be initializing itself in parallel.

QUOTE (jcz @ Apr 7 2009, 07:41 AM)

If you include a notifier in your message cluster, that gives a mechanism by which the subprogram can return an acknowledgment, along with any data. The caller creates a new unnamed notifier, bundles it into the message, send the message, and waits for the notifier. The subprogram checks the notifier refnum and if it's valid, sends the response, and if invalid, just ignores it (not all queued commands need a response).

QUOTE (jcz @ Apr 7 2009, 07:41 AM)

The main idea I had was to create a bunch of main programs that would pretend to be a real-hardware-devices. So then I could simply implement some sort of protocol, define commands and talk to each sub-program as it was a real device. For instance to grab an image from a camera, I could then add a command to a queue (in exterme version SCPI-like command) :camera:image:snap, and only camera interface would run this command returning ACK.

If you use a separate queue for each object, and a separate enum of commands specific to that object (subprogram), then your subprograms are all totally reusable. In fact I would wrap each bit of queue-sending code into a VI and then those VIs are the public methods of your subprogram.

In case I was too subtle, I think it's a mistake to use the same queue for all of your hardware components. Each object should be its own independent queued state machine which can accept commands and do stuff. Otherwise I think you are on the right track.

Jason

Link to comment
  • 1 year later...

Thanks guys for all suggestions. They are very useful for me. As soon as I get to the coding again I will implement your suggestions.

Jakub

Dear Jakub,

Did you ultimate came out with some better solution?

I too was finding myself in similar type of situation :-)

Dear jdunham,

Can you please provide a small working example of your suggested MVC model?

Shourya

Edited by ssingh1
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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.