Jump to content

ned

Members
  • Posts

    571
  • Joined

  • Last visited

  • Days Won

    14

Everything posted by ned

  1. Minor style point: straight wires look nicer than ones with lots of bends. I suspect that you could eliminate the ~100hz signal on the chart by wrapping the chart terminal in a case structure so that it only writes new data to the chart when the frequency is above some minimal value.
  2. Sorry, I don't have a generic template at the moment, and I'm a bit on the busy side right now, but I'll post something if I can find time to put it together.
  3. What do you mean by "send it to the RT Task"? Can you show how this is used in your larger project? Generally I wouldn't recommend writing it that way; it's better not to put indicators inside structures if they are connected to subVI outputs. A somewhat simpler approach would be this: That said, I don't actually see a logic problem with your original approach, so I suspect the problem may be further up.
  4. I'm not familiar with LapDog so I don't know if this is useful, but I've been using the approach shown below. Inside the Fire VI (this application controls a system that fires droplets of ink) you can have a state machine where each iteration of the main while loop executes only a single iteration of the state machine. It's easy to interrupt but because all the actions are inside one VI, it can't be interrupted at the wrong time (as can happen when you queue your states). You could trivially add a "Cleanup" VI that would run on the class stored in the shift register whenever the dequeue did not time out and the previous action was not yet Done. I do use this code for sweeping various parameters. The class hierarchy has a simple Fire action at the top. One child of Fire is Stop. Another child is a Measure class which takes a single measurement. Below that is a Measure with Sweep class that can sweep through various parameters, executing the parent Measure method at each step. When the parent Measure object is Done, the sweep moves to the next parameter.
  5. If you distribute code with the diagram removed, you're locking the users into that version of LabVIEW. I don't think I'd buy a toolkit that I couldn't use with a newer version of LabVIEW, or couldn't move to a different LabVIEW platform than the one for which it was compiled. At the very least that would be a significant limitation. If the password protection makes it possible for companies to sell toolkits and be comfortable that their IP is sufficiently secure without removing the block diagrams, I'm fine with it.
  6. To improve my own understanding, what is one way to obtain a reference to a control in a local VI (not accessed remotely through VI server) that returns a valid value other than the "this" reference?
  7. There's nothing special about the refs obtained from the Controls[] property that makes them different than a regular control reference. Each control has a unique refnum which will be returned whenever that control is referenced, regardless of how that refnum is obtained (direct reference, controls[] property, etc). As a result, no need to close those references. As an example, see the code below (note that you can create a direct reference to a control within a cluster).
  8. I don't think there's anything wrong with your approach. Personally I wouldn't wrap the entire contents of the state in a VI, because I'd rather have some idea what's going on in the state without needing to open another VI. Instead I'd expand the loop and put more of the code directly inside it, using subVIs to wrap individual processing sections that make sense as independent subVIs (either because you might be able to reuse that bit of processing, or because you can understand the overall goal of the state without seeing the details of that particular operation).
  9. I'm pretty sure a waveform is just a specialized cluster with a unique wire appearance, like an error cluster. Although it's not definitive proof of this, the help for flattened data says "LabVIEW flattens waveforms like clusters." I'd use the waveform data type if it's convenient, but I doubt that performance will be different than using an equivalent cluster.
  10. Back on this topic again, a few months later. I have a design that I like, but one part of it (shown below) looks a bit ugly to me, and I'm wondering if others would take the same approach or would arrange the data differently. My system dispenses droplets of liquid and measures them. There are a number of parameters that affect the droplet volume and velocity. The user can configure the system to vary any number of those parameters across a range, and the system tests every combination. At the top level I have Dispense class that starts the system dispensing liquid with a fixed set of parameters. Then I have a Measure class which inherits from it. Measure contains an array of Sweeps, one for each parameter that the user wants to vary. My issue is that each element of the Sweep array modifies a parameter that is part of the Dispense class. As you can see in the image, what I'm currently doing is pulling the individual Sweep out of the Measure class, feeding the Measure class to a Sweep method that updates the appropriate parameter, taking the updated Measure class value (which has now become the parent Dispense type due to inheritance rules) and forcing it back to a Measure class, then putting the updated Sweep back into the Measure object. Is there some better way to give an individual Sweep inside the Measure object access to the Measure object's parent data? The code that's shown iterates through each Sweep until it reaches a Sweep that hasn't finished yet. The "Done?" method increments the appropriate parameter, and returns True when that parameter reaches the end of the range, which then causes that Sweep to reset to the beginning. This allows the code to test every parameter combination within the user-determined ranges.
  11. I realize it's not completely analogous, but I think by-name tethering is reasonable since it's consistent with other (text-based) languages that require that functions which override each other have the same name.
  12. Try the In Place Element Structure to modify a single element of an array efficient. Array Subset and Replace Array Subset can also be efficient when used correctly. An array of strings in LabVIEW is basically an array of pointers to strings; since strings are not fixed-size they cannot be stored in the array itself and so the array stores pointers to strings instead. String manipulation is often slow because the string may need to be reallocated as it grows.
  13. I love this trick. Related to this, Variant to Data will also convert a variant that contains an array into an array of variants, which is sometimes useful. Personally I think the compiler should infer (or propagate) types as much as possible, so I don't see it as a bug. There's always a risk of passing an incompatible type when using variants - it's the price of using a non-specified type in a strongly-typed language - and it's the programmer's responsibilty to manage that risk. This doesn't prevent you from wiring the type input, if you want that check at compile-time, it just makes it optional for those situations where you don't need it and don't want extra constants on the block diagram.
  14. Just to confirm, you're not trying to edit the LabVIEW.ini file while LabVIEW is running, right?
  15. I don't have 2012 installed and don't have time to recreate your VI in 2011 so I haven't actually run your snippet, but my guess is that this is a copy-on-write situation. That is, there's only one copy of the event data, and both mailboxes get pointers to that data. A copy is made only when the mailbox reader needs to modify the data. So long as the reader reads the data but does not to write it, there's no need for a separate copy.
  16. There's no problem posting to multiple forums, but when you do so it's polite to note that you've posted it elsewhere. That way you avoid being asked the same questions in multiple places, and people trying to help you can read the related forums before they duplicate work that was already done elsewhere.
  17. Note: crossposted to the NI forums forums.ni.com/t5/LabVIEW/Open-subvi-into-subpanel-and-handle-events/m-p/2158254
  18. Post photos of your most recent outside-of-work project and we'll let you know if it's cool enough. Or, bribe the leadership with .
  19. I think you've misunderstood something slightly. Accepting multiple connections on a single port is the same regardless of whether the connections originate from a single IP address or different addresses. Outgoing connections are assigned ports (usually automatically), and so long as the port/IP address combination is unique, there should be no problem. To accept multiple connections you need to understand the difference between a listener and a connection. In newer versions of LabVIEW (2011, haven't checked 2010), TCP Listen has a listener output. In older versions (LabVIEW 2009, maybe 2010) you need to use TCP Create Listener and Wait on Listener yourself. When Wait on Listener returns a new connection, you need to handle that new connection and continue listening on the listener for more connections. There are a couple of ways to handle this; the common ones I know of are 1) dynamically launch a VI to handle the new connection, or 2) add the new connection to an array of connections in a separate loop, and iterate through the connections continuously, sending or receiving data as appropriate on each one. You may find this thread about listeners and connections helpful. It also explains why you should not open and close the listener for every connection, in case you're doing that. http://forums.ni.com/t5/LabVIEW/TCP-IP-feature-or-bug/td-p/832692
  20. I've never seen or heard of this. In fact, just this morning I just saved some code from 2011 back to 2009 with no problems.
  21. No polling necessary. The DLL installs a hook that gets called when LabVIEW receives a Windows message. If the user registered for that message, it generates an occurrence (as currently written). What I was suggesting - and what I understand Rolf to be offering to implement - is to replace the occurrence with a user event. When the window receives a message through the Windows message queue, it will fire off a user event that will look to your LabVIEW code exactly like a user event generated by Generate User Event.
  22. Are you comfortable coding in C? If so, you can modify the code for the Windows message queue DLL to call PostLVUserEvent(). It's been a while since I looked at the Windows Message Queue library, but if I remember correctly, it uses an occurrence. I do not think it would be too difficult for someone with some C experience to change it to use a LabVIEW user event instead.
  23. What are you trying to protect, and from whom? If there's an attacker who can read arbitrary memory locations or get access through VI server, seems to me they'd just install a keylogger and get your passwords for everything, not just the LabVIEW application.
  24. The fact that the array contains objects does not change that it's just an array. Seems like you want the array to be something more. If that's the case, are you sure an array is the appropriate structure for collecting your commands?
  25. I disagree that indexing out an individual command "breaks" OO. You have an array of objects and you want to modify one of them, so you pull that particular item out of the array, make a change to it, and put it back in the array. Seems clean and simple to me, much more so than your proposed "solution." Let's say you were going to set the parameter before initializing: then you wouldn't even bother putting it in the array until after you had set the parameter, right? But you'd still be modifying an individual element of an array, you'd just be doing it before it was inserted into the array. I don't see indexing out after building the array as any different. You could, of course, assign unique identifiers to each instance, then set the parameter on every element in the array with an additional identifier input, and only change the elements that have a matching identifier, but that seems excessively complicated for no gain.
×
×
  • Create New...

Important Information

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