-
Posts
1,969 -
Joined
-
Last visited
-
Days Won
172
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by drjdpowell
-
-
Remember this conversation? Those examples I gave use a TCP client-server. They should work with multiple copies of the client.
-
1. No Polling. Seems like there will always be a need to poll the connection. If nothing else then to be able to respond to internal shutdown messages.
2. Robust connections. How do you re-establish the connection from the server side due to your flaky network dropping it if the client does not have a unique machine name and port to connect to?
It seems like I would run into the same issues and would have to design a very complex solution from the ground up.
You can cross (1) off at least, as there is no need to poll a TCP connection. Just have one loop sit waiting for incoming messages, with a second loop to do sending in parallel. TCP is bi-directional and the two directions don’t interfere with each other, just like a pair of Network Streams. But being bi-directional, you don’t need to establish a second connection from server back to client, and thus don’t need to know the client name. If the client can reach the server you are done. And the TCP Listener is exactly what you asked for as far as a server handling incoming connections. To me, TCP seems much simpler than what you described.
Re (2), I don’t have experience in unreliable networks. But I have always been confused by Network Streams, as TCP is already a robust network protocol that resends lost packets; what is Network Streams able to do that TCP can’t?
— James
-
Not to distract from the question but I’m interested in why you aren’t using TCP directly. I haven’t had a multi-machine project in ages, but TCP Listeners and bi-directional TCP Connections seem intended for exactly this kind of problem.
-
Are you trying to measure volume? With a bright light wall behind, the meniscus should be visible.
In this image the level (of a petroleum product) is very clear because of a layer of bubbles (white bubbles, but they appear black against the light wall), but even without bubbles one can pick out the level.
-
I am reminded of this Eyes on VIs video, and how it matters whether or not one closes the VI reference when using Run VI. Don’t know if this helps.
-
@drjdpowell,
Edit: The Open Vi Reference followed by "Auto Dispose" TRUE only seems to work if I wire in a strict VI Reference constant with the correct connector pane. If I do a generic "VI Open" without the VI Type being specified, the VI will still auto-abort when leaving the sub panel even if "Autodispose" is set to TRUE.
That’s surprising to me, but then I haven’t used the Run VI method in years. I only use ACBR, which always required a strict reference.
-
This can be a bit surprising when you come accross it the first time (and I still think it's not ideal behaviour to be honest). You have to babysit that original reference until the VI has left the subpanel, had its FP set to not closed and then and only then can you close that VI reference.
For async VIs** I use ACBR with option 0x80, which, like Run VI with Auto Dispose Ref = TRUE, means the VI never aborts like this.
**We don’t seem to be talking about synchronous subVI calls here, but for those I just use a static reference (which cannot be closed).
-
If I run it with the panel hidden and then close the panel to insert it into the subpanel, that's going to reset all the values to default values, isn't it?
(that's what it seems to be doing for me... maybe I've still got something wrong.)
Does it? Closing isn’t the same as unloading. Is your VI reserved-for-execution? If it is, I don’t think closing the FP unloads it or resets anything.
-
Or does a VI have to already be running before it goes into a subpanel?
If you executed it, then it must be reserved for running, so the “nasty transition†Neil mentions doesn’t apply.
Do I have to close the panel before I put it into the subpanel?
Yes. I put Close Front Panel before Insert VI (I ignore any error from the Close, thrown when it was already closed).
PS: After I put the panel into the subpanel, can I close the reference or do I have to keep it open so that the VI stays in the subpanel? If I don't close it and then put a different panel into the subpanel, will the subpanel close the reference for me?
You can close the reference. The subpanel doesn’t (I don’t think) ever close the reference itself.
-
For example: Log button becoming true sends "Start Logging" command, Log button becoming false send "Stop Logging" command.
The thing I like about this is that I can handle fiddly "stateful" control logic inside XControls. The Xcontrol has an enum value and I can register a particular enum value to a command specific command message.
For example, a "tape deck " type control with play, pause, resume and stop / abort buttons. Three button, four messages "Play" "Pause" "Resume" and "Stop". The X control logic wraps the "button logic" up nicely without having to smear it over 4 cases of you main UI's event structure.
I solve this issue a different way, by making my messages all "control-likeâ€: a label and a value. So I would have messages:
“Set Loggingâ€, a boolean that is True or False
“Set Play Stateâ€, a string (or possibly enum) with values "Play" "Pause" "Resume" or "Stop"
-
Attached is the demo project developed over the Actor to Actor communication and Controller-Model-View videos. LabVIEW 2015.
- 1
-
I tried having call-backs that called methods on a LVOOP object inside a DVR. It worked, except that occasionally two events happening at about the same time caused the UI to freeze, possibly due to some kind of lock-up involving the DVR and the UI thread in which the callbacks run. This was near impossible to debug, and I abandoned callbacks in favor of an asynchronous VI that handled events with an Event Structure (calling the same LVOOP object held in a shift register).
-
Your code was not attached, but I often use variants, dynamic registration of arrays of control references, and control labels that encode the message that needs to be sent, as illustrated in this old post. I also done similar things connecting multiple controls with Camera Attributes or DAQmx channels.
- 1
-
In the end I sidestepped the bug by turning off "Advanced>>Auto Adjust Scales†on all my graphs.
- 1
-
I was more responding to: "It is my understanding I have one of two choices at this point: A.. and B.." I gave an option C.
-
Are we actually disagreeing? Your pointing out a way for calling code, that explicitly knows what a "dog" is, to call subVIs that only deal in "animals". If the calling code has reason to explicitly be written for "dogs", then that's good. But if you want the calling code to be generic and work with any animal (what's that? an "animal-abstraction layer") you can still support special functions if you define the right methods. Writing code where, if you click on a dog, you get a button marked "bark", doesn't require that code to explicitly work with anything other than animals.
-
Another option is to push greater responsibility down into the specific classes and have the application-specific code continue to deal in parent-class methods. For example, your power supply with a special feature probably needs a way for the User to configure that feature and observe the results. The application code could call methods like “Has special features.viâ€, “Show Configuration window.viâ€, “Get text description of status.viâ€. If the power supply has special features then show a description of the status of those features and show a button that lets the User open the Configuration window (possibly in a subpanel).
- 2
-
Hi Thanks for the reply.
I'm not sure i understand your point 2a. completely. Where does the case structure go? Does that end up inside event loop and inside the event case to actually trigger the message?
Yes, inside the event case. Show your dialog only on events where the button goes True.
-
Re 1) The Event Structure has a Timeout, which you can set to zero if you want.
Re 2a) Use a Case Structure to do things only on True.
Re 2b) the “Value Changed†event is somewhat misnamed as it really is a “new value†event; there is no filtering out of where the new value is the same as the old value. The Event has the old value as well as new value so you could do this yourself, but a far better solution would be using a case structure and only trigger an event on True.
-
So as an example: If my Actor acquires some data and provides it for the outside world, it might have its own visual representation and maybe you can control it (so basically MVC in one Actor). On the other hand I require multiple visual representations to fit the data on different screen resolutions (pure VC units). There are boundaries I have to define. I can either have a 'default' resolution in my core Actor with additional VC Units, or the core Actor is never shown and all resolutions are from separate Actors as VC units.
You can also treat the core Actor’s Front Panel as the “debug†UI, since it is easy to add a lot of indicators.
Personally, I usually have a lot of actors that are MVC-in-one-actor for their own part of the application. So ‘temperature control’ actor probably has control/view of the SetPoint, PID and other parameters, and can be inserted into a subpanel in the main app. Then additional Views or Control can come from elsewhere (a summary screen of many temperature controllers, say) but these VC tend to deal with smaller subsets of “Model†(such as just the SetPoint).
- 1
-
Most of the web references to MVC is about frameworks and architecture, where the M, V, and C are distinct and clearly separable things. I’m less interested in how to define boundaries between things than in flow. Directions and arrows. The User exerts control on the state of the application. The User views the state of the application.
Here’s the Wikipedia diagram for MVC
If you search, you’ll be confused by seemingly different diagrams, which divide up Controller and View differently, but they all have the key flows between User and Model. I follow the principle, rather than trying to have specific application layers identified as M, V, or C.
— James
PS> a link to the video referenced.
- 1
-
I’m more going for SER, Signal-to-Effort Ratio, at the moment as I have limited time to spend on things like editing. Something is better than nothing. And a programming instructional video that doesn’t drag is a pretty high bar (not sure I’ve seen many of those!).
- 2
-
If I were looking at improving an old program I would first look for and refactor any natural ‘objects’, bits of data and actions on that data. You, for example, might have a ‘Camera’ object for taking images, or a “Sample Positioner’ object. Only after this would I ask if some of these objects should exist in separate loops so they can do things in parallel.
Re the various QMH designs, I gave a talk recently about some of the issues (main point: don’t use the NI QMH template; use something like the JKI template).
-
- Popular Post
- Popular Post
I've started to make some instructional videos on YouTube for my Messenger Library. I was inspired by Delacor's nice videos on their new DQMH framework and also by Steve Watts' CSLUG channel. Any feedback appreciated.
James
- 6
Client-Server network message transport options
in Remote Control, Monitoring and the Internet
Posted
For anyone listening, here is how to send messages (or any other data type) via a TCP connection. Basically, one just puts a message length at front and reads that first. TCP handles making sure you never miss a byte, so there is no need to identify data boundaries.