Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by MarkCG

  1. I like it. There's so many ways you can combine clusters, arrays, classes, and variant hashes.. I can recall at some time or another storing all sorts of data including classes inside variants for name lookup, iterating over arrays of classes containing arrays of classes, making arrays of clusters of arrays, many clustosauruses, etc etc etc etc. Having a generic solution is really useful and hopefully leads to cleaner / easier to interpret code.. What would be very useful too is a way to visit every element in the tree.
  2. Can't agree more with this. I find libraries full of VIs prefixed with the library name really annoying because the unnecessary duplication, and it makes it difficult to pick out the actual VI name when looking at the title bar. And if you are sticking members of different libraries in the exact same folder to where you NEED prefixes, may God help you...
  3. Get ready to have some "fun". IME building EXEs for MACOSx was very frustrating, with many build failures and even exes with broken run arrows! I did not know that that was even possible.
  4. What bothers me about this is that it seems to defeat parallelism somewhat. Two loops that really ought to just be sharing data via a the queue are now have to depend on a non-rentrant VI to get the queue. Say we have non-empty queue, and A is the producer loop and B is the consumer. If loop A is calling the LV2 global to get the queue to in order to enqueue data, B has to wait until the LV2 global is finished executing in order to dequeue data that is already available. I'm sure the performance hit is negligible, but it's the principle of the thing that bugs me. I like to pass queues into through front panel, in a cluster if need be.
  5. One of a TC's advantages is that they are cheap and have very low time constant, meaning you can measure rapid temperature variations. The bare TC tip is small and is easy to get into good thermal contact with the thing to be measured. RTDs are more expensive and physically bigger. In the HVAC industry they'd twist TC bare wires together, and solder it to copper tubing of the air conditioners. When test is over, you just cut the wire off near the tip.
  6. James, I am glad someone else shares my hunch on performance. I have given that a lot of thought to race consitions. I really hate and abhor "signaling globals" but have done the best I can to mitigate. All NSVs are in either a "control" library or an "Indicator" library. NSVs in the indicator library are only written to in one place in the target/cRIO code, and all elements at once. Control NSVs will be written in only one place in the HMI /host code. "Signaling" NSVs that need to set a setpoint consist of a cluster with a "set?" boolean and the numeric quantity that is the setpoint, to avoid race condition between the "set?" flag and the setpoint. Neil, I also share your distrust of NSV based on what I have heard. In the past I have used Network Streams and the Current Value Table and was pretty happy with the performance. I should probably give a little background as to my choice in using NSVs in the first place. The reason I am using them is that I have inherited one of the usual monsters (one giant block diagram, interloop communication via local variables) and my task is to port it to cRIO . The client does not want to re-write it from scratch yet due to number of reasons. (no spec exists, it was grown "organically" let us say). Fortunately they are very aware that it's a mess, I decided that at least modularizing, undoing some of the local variable mess, and using shared variables to get the data out is the best option, Flintstone, this does scare me. I have worked with NSVs running on PXI chassis, there where about 20 different machines, each with a library of say 50-60 NSVs. They seemed pretty easy to connect to via the Distributed System Manager. But then again that was PXI and not cRIO. I know NSVs had a whole lot of problems in the early days. It usually takes a few years to work out the bugs with any NI technology as far as I have noticed. Hopefully they are ok now...
  7. Hi all, I am working on a typical HMI+cRIO 9074 control system... porting over / lightly refactoring some code that was written to run on a PC. There are going to be quite a few variables to keep track of, but many of them are logically related and I would internally keep them in type -defed clusters. Instead of creating individual shared variables for every single boolean, floating point and string, I am thinking that grouping the variables into typedefed shared variables will be good for managing the information, and also improve performance (reduce CPU load on cRIO) by reducing the total number of shared variables. Is my hunch about performance correct or will this be immaterial?
  8. Thank you for the advice! I didn't want to call, and go through the process of explaining the whole thing/ waiting on phone. I'll definitely use the online service request, thank you for that pointer Antoine. I will post CAR # when I get it Mr Mike. And to Darin and AQ, it's not so much a proprietary thing as that I was advised that I should try to disclose in a responsible way given nature of bug.
  9. I discovered, by accident, a way to render a library or class corrupt, by doing a certain operation on it from within LabVIEW. Breaking the lvlib also breaks its member VIs, until they are unlinked. No, it does not involve munging the XML or raw text of the lvlib. I have demo VI but am a bit loathe to just put it out there for the world. What should I do? What's a good place to report it?
  10. Thank you Ned for the very nice Visitor pattern example! The data object of a given type has a do method, that takes in a visitor of whatever type , and executes a that visitor "Visit" method specific to that data type. (visitIntegerDataType eg) . I can see now how setting things up this way could be very useful. You have visitors that do all kind of different things, but you have to only write the iteration code once-- in this case it's just a for loop in DataItemCollection.lvclass, but I can see that if you had oh, binary trees or oct trees or graphs doing it that way would be awfully useful, since visiting every member there involves a bit more than dropping a for loop on the block diagram. Very cool.. glad I learned something today!
  11. I have looked at that example before as well, and I don't get it either. In my admittedly poor understanding, it involves a "visitor" class iterating through a collection of objects and performing some operation on each one. The collections could be something as simple as an array or something like a tree or graph of objects. The visitor "knows" how to get to (well, visit I suppose) every object in that collection, and then do whatever it's supposed to do to that object. So in your case, the "thing" to iterate over, is maybe an array of channel classes, each with an array of check classes. And the thing to do is to execute the check and take action if necessary. I see it like this-- here's some ASCII art: x's channel classes, o's are check classes x x x x x x x channel class array o o o o o o o c o o o o o h o o o e o c o k a r r a y s basically the visitor knows how go through the class array, and for each class array go through the check array. Basically nested for loops. AQ is this at all close?
  12. I recently did something pretty similar-- each channel represented by a class, with a variable number of different condition check objects stored in an array in each channel class, all configured via a spreadsheet file. I went the route of create a manager class that would iterate through all the channel object condition checks and at the end decide what action to take. My approach would have the condition checks classes send messages to "DO output" actor / loop. The DO output loop holds on to the actual DAQmx task, and it can decide when and how to set the digital outs. You could cause the DO object to set lines only every 100 ms or whatever, and then at that time determine what to do based on what messages it received in the last 100ms
  13. It does look like the OSX version of LV2012 doesn't have anything equivalent to "vi.libplatformfileVersionInfo.llbFileVersionInfo.vi" . Still though, I can see my app's version number under when I "Get Info" on it with Finder. There has got to be a way to get to it-- anyone any ideas?
  14. Why not make the CAN reference an input to whichever zone class methods will use it?
  15. Invariably, in most large projects I do, I end up needing to do one thing which I have not found a clean way to do yet. And that is handle messages between components differently based on state of the component / actor. Simple example of what I mean-- a machine that can be in an idle or running state. If machine is off/idle, a shutdown message to the actor or component representing the machine does nothing- the message is read but nothing happens, it is already off. If running, it goes through shutdown sequence, actually controlling physical hardware. Likewise, if running, a "Run message" has no effect. In the past, pre-oop, I handled by separating the messaging from the states. Essentially nesting your standard enum+variant dequeue + case structure INSIDE each case of the state machine. So inside the while loop, a case structure for each each state, and a case structure to handle messages inside each case of the state machine. This worked fine and was easy to debug, but it was cumbersome and one had to be very diligent about handling every message in every state correctly. Now I see I can apply the State Pattern to solve the above problem-- abstract methods in a parent class, with child "state" classes that have concrete implementations of those methods for each message where needed. However, there something about this that doesn't quite sit right with me. Let's see if I can explain it via some pseudo-code ParentState ----- method_1() {}; //abstract method ----- method_2() {}; //abstract method ConcreteState_A :: extends ParentState -----method_1() {do stuff;} // only method 1 is implemented in State A. Method 2 should do nothing. ConcreteState_B :: extends ParentState -----method_2() {do other stuff;}// only method 2 is implemented in State B. Method 1 should do nothing. ConcreteState_C :: extends ParentState ----method_1() {do stuff;}//same implementation as in ConcreteState_A ----method_2() {do other stuff;}//same implementation as in ConcreteState_B ConcreteState_A does only method 1, ConcreteState_B does only method 2, ConcreteState_C can do either, and the implementation is the exact same as in A and B respectively. Clearly I can move the concrete implementations of method_1 and method_2 up to the parent class. Sure. But in order to make ConcreteState_B do nothing when method_1 is called on it, I would have to override method_1 with an empty method!!! Otherwise the parent method_1 will get executed (dynamic dispatch), and something will happen when I don't want it to. Likewise for ConcreteState_A, I will have to override method_2() with and empty method. This seems like a backwards way of doing it. I could leave the ParentState methods abstract, and I could move all the method_1 functionality into a function and use method_1 as a wrapper, but I would have to still create overrides for each concrete state that needed to implement method_1, duplicating code. I Imagine that I had 20 classes, each needing to be able to implement / not implement a large combination of methods, things would get hairy with the above solutions. What is it that I am looking for here? Either of the above methods seems kludgey. Is there a way to explicitly say to a child class--- "I know the parent has concrete method implemented, but YOU are not allowed to execute it!" (do as I say, not as I do ) Are "Interfaces" what I am looking for??
  16. So jet velocity call it "u(x,y)", is in Z direction, is function of x and y, and you want to take the derivative uxx , uyy ,and uxy ? You might try to smooth the data with "2D interpolation scattered.vi" (look for example), found in math palette then take the derivative of the interpolating data/function. There are higher order stencils you can use to compute the derivatives and Laplacian as well--- they can be derivatived by Taylor series expansion. This will help in smoothing the derivative function also.
  17. Hi Darin, one little trick to get get around the typedef explosion is to wrap that constant in a subVI- new VI, drop the constant on the block diagram, create and wire it to an output. Make the VI icon look like a cluster constant or whatever you want. The typedef constant can remain in its exploded state and you can drop that subVI wherever you want.
  18. Right, can't do pop ups with remote panels. But why do you need to know if the remote panel has taken control?
  19. If its rs485, they probably use Modbus protocol. Read up on this. Get the NI modbus library. This will allow you to read modbus registers. Read the controller manual, find out where what the registers are. Read registers you need with modbus library vis. You will need to typecast those registers to the data type you need. For example, feedback temperature will probably be represented as 32-bit float. For example, a modbus 32-bit floating point is contained inside two registers. You need to read both those registers and typecast them to a single precision float.
  20. I am all signed up for the June 7 software engineering course in Austin Texas. Hopefully at least one more person will sign up for the class So it can take place .I'll let you guys know how it is.
  21. Ironically it's only in the United States that British thermal units are used in practical engineering.
  22. I just right now was making a serial comms VI library to talk to an instrument and for some reason the VISA line feed auto-append (termination character) didn't do it for me, although Hyperterminal will do the same thing and it worked. I just concatenated the "line feed constant" from the string palette with each of my commands when writing, then it worked fine.
  23. I feel your pain Alex. I need to sit down and DO as well. I'll probably never get time to implement anything OO on my current project, but hopefully my next gig will involve making a nice desktop VI from scratch and I can do it in an OO fashion right from the start. Meanwhile I'll do a CLD exercise or two using an OO framework, to give me something to do.
  24. Hi all, I've been putting remote panels to use recently as user interfaces for control applications running on real-time targets. Some here have said that remote panels should not really be used for anything other than diagnostic type programs, and that large panels with many controls and indicators is asking for trouble. Rather the better way is to run a GUI executable on your laptop /desktop and control the remote application via shared variables/ tcp-messaging schemes / network streams. You need the LV runtime engine to use remote panels. Does host / remote unit send a copy of the front panel to client/web browser upon connecting, then use the run time engine to detect button clicks and send the new control values to the host when changed? And, like wise, update the client front panel image every time an indicator changes? It seems like that's not too inefficient a scheme. So I'm curious exactly in what way can remote can go wrong. What gains would there be front writing a GUI VI to live on your desktop and send messages via a simple tcp/ip scheme or shared vars whenever a button is pressed to the host, and listen for host indicator changes. I'm not exactly sure exactly how much gain you get from all that work, and how it's any different from a remote panel. Unless you have lots of data to stream back and need to use network streams,, or want to share data across the whole network, and need to use shared vars. Seems to me a remote panel is exactly what you need for point-to-point, low update rate, remote user interface, So am I fooling myself here?
  • Create New...

Important Information

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