Jump to content

hooovahh

Moderators
  • Posts

    3,392
  • Joined

  • Last visited

  • Days Won

    284

Everything posted by hooovahh

  1. So you can use the initialize array, providing the data type (double) and the maximum size. Then wire that to a while loop, turning the tunnel into a shift register. This keeps data between loop iterations. Wire it to the right, and the next while loop iteration will use that new data on the left. So now you can use the replace array subset, replacing the index specified and the value. You might be able to use the iteration terminal (i) of the FOR or WHILE loops if each iteration you replace the next value.
  2. Wow this is entirely too complicated. How do you even stop this? You have a false making sure your VI never stops running. What's with the random 10ms waits all over, and the key focus? And the 100ms loop which does nothing for you. Your enums aren't typed. Your controls aren't labeled well (there is a boolean output named true). Controls aren't on the root of the BD in subVIs. You have multiple controls named the same in a single VI, your Panel Close should always discard, so you can perform cleanup by stopping the loop. You should not exit LabVIEW like you are when in the development environment No need to validate the values again when you start, if you are validating them when they have the value changed. As I mentioned before just use the value change event on the control, no need for that top loop or all those local variables at all, or the functional global variable. Attached is an updated version with some of these changes but man you know what would make this code even easier? If you you use the control to coerce the entered value to have the range you want, then there would be no need to perform a validation because you'll know the values are correct. Lucky for you someone has already posted this solution for you Test_Pane Hooovahh Edit.zip
  3. You do know this is the exact reason why the event structure was invented right? It meets all of your needs other than the one that states you can't use it. This also would fix your loop being late issue since each event is handled in the order it was received and works like a queue. But if you must insist there is a slightly easier method. You can use the Data Changed subVI from OpenG. Wire anything to it and it tells you if the data has changed since the last time it was called. Still crappy, and you can still click the button twice quickly and not detect a change. I don't know your situation, but when I was in similar circumstances I forced myself to do the right thing, and use the right tools, despite the pain involved.
  4. Wow so I don't own a Pi but this makes me want to get one to see what it can do. Just like with the Arduino discussion before it was released, can you give any more details on things like the current limitations? Should we assume similar cost schemes to the Arduino? You mentioned seeing LabVIEW windows, does that mean the event structure is supported? Or is this more like the Linux HMI for basic interactions with polling?
  5. I agree with this, but would also like to add, from NI's perspective this would be a larger task than users may think. Just adding something like a Windows magnifier isn't good enough. First the graphics won't scale well. NI developed LabVIEW in the 80s before there was much of a standard in vector based graphics for images. Scaling an image to an arbitrary size would really need sets of images that scale well, and not just icons, but wires and other graphical objects as well. Also if I move a wire one pixel with an arrow key, how would that operation be changed if I'm zoomed way in? or zoomed way out? Does it still move by some 1 pixel standard? So if I'm zoomed in moving on pixel with the arrow key would move multiple pixels on the screen, or when zoomed out it might not look like it moved at all. Oh and I think this is the idea that got the most attention on zoom. http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Add-a-zoom-function-yes-I-said-zoom-So-sue-me/idi-p/918306
  6. Perform the mouse down event on the control not the pane. This will generate one event when there is a mouse down. But a better solution would be to use the value change on the control, because I can change the value using the keyboard, with things like tab, which then wouldn't be caught using your mouse down event. Also post your code if you can so it can be made more clear what you are trying to do.
  7. Which was by design. If you have a pop-up for every control being out of range your users are going to get quite annoyed. What's wrong with the built in feature of setting the control range? It meets the requirements in a cleaner, more scale-able, more modular, more reusable, and more user friendly way. I can think of very few benefits of prompting the user every time. Still if that is what you really want my code can be modified quite easily as ThomasGutzler showed.
  8. First, did you really just put your phone number in a post on the internet? Beyond that here is a method that doesn't need any validation. It sets the max and min of the control to the range based on the drop down selected. It then normalizes in Hz and GHz. No need to write code checking if the range is valid, you make the control only accept the valid range. Freq validation Hooovahh Edit.vi
  9. Software design has many questions that need answering, and this is one of them. I've seen some software written where each dialog in the application was its own separate VI running a while loop in parallel with the other ones. Each VI and loop had a messaging scheme to show and hide the dialog. This mean there were something like 10 parallel while loops just handling dialogs. This goes too far. I've also seen applications that have one while loop, where DAQ data logging, report generation, sequencing, communication, database control, and UI were all in a single loop. This didn't go far enough. In the end it is up to you to decide how it should be designed, and personally I don't mind adding parallel loops as long as the functionality and responsibility of the loop is well defined, and encapsulated. Performance-wise it might become a problem. An atom is not a powerful PC, and if each loop is doing lots of work in timeout cases you will have a problem eventually. But if most of the time, most of the loops are truly idle, not polling anything, then I wouldn't worry too much about it.
  10. @ShaunR You make very good points, I think all of which I agree with (is that a first ). Bloat in the LabVIEW can be a very big problem, many massive class and libraries loading all members, and polymorphic VIs loading all members is an issue for sure. In a post on my Variant Repository XNode I mentioned something to this affect, where the polymorphic version has a couple hundred VIs in a couple polymorphic VIs. I certainly wouldn't use this wrapper code for every FGV in my code, it would add unneeded bloat with little (in any) benefit. But there are times when it can make an API easier for the developer to use and understand, by breaking up the possible many functions of an action engine, into easier to understand chunks. Like you said, pros and cons, like with many design choices in software.
  11. Interesting, I never thought of doing it this way. Now there are a few draw backs, as you mentioned first you don't have just some central core VI that you could probe to see how everything is doing and the last states executed. There are also times when I have more than one shift register, so that would mean either more DVRs or more practically, a cluster of the things I want. Oh and you'll have an extra step you need to remember to close the DVR reference where a VIG is fine to just go idle. For me action engines are so damn convenient. I can make one is literally seconds, okay I have a template for a read/write VIG as a starting point so maybe that's cheating but still. Probing is simple, execution is simple, developers of all experience levels can understand it (as long as they understand the concept of a uninitialized shift register), and adding it to a library can have some level of access protection. I'm not saying classes aren't a more elegant solution for the same problem. Oh and I love scripting by the way. Yesterday I spent most of the my day writing scripting code, that auto generates accessing VIs, messaging VIs, and type defs for a Web Service someone wrote. It would have taken me probably all week to do it all by hand, and there would have been lots of errors. Now when new code is written I run my script again and all the new VIs and controls are generated.
  12. This is good, but I don't think it will work for everyone. I've seen some cases where there is only one input and it is a cluster, and then it will unbundle that and only use some elements of it in each case. I can't remember a time I've done that so your version is perfect for what I've done. We could try to get crazy and look into unbundleing and seeing what elements are used in each case too.
  13. Oh thank you, I was trying to perform the action on the Library item, not he library itself. Attached is an updated version which now makes a library, adds the core, the polymorphic VI, and the polymorphic instances, and sets the core to private. It should probably be put in a virtual folder for Public and Private, but I was just happy to get this working, feel free to improve on it. Main Generate VIG Wrappers With Library 2014.zip
  14. Oh this is a good idea too. I added code to create a library and add all the members. This works just fine but I couldn't find a way to set the access scope through scripting. Is there a method for that?
  15. That is a fantastic addition. As you can see from the disabled code on the right I was trying to make a unique icon for each wrapper because I didn't like that every VI had the same icon. I didn't quite get it working so I gave up, but with a polymorphic VI you can see the VI Selector which tells you which instance it is using. As for the cluster idea, yeah each VI that is made can have the cluster elements it actually uses be exposed on the palette of that unique value of the method. So if you have a cluster with a path to load and a string to write, in your Init VI just have the path be on the front panel not the cluster, then in the VI bundle that into the cluster that goes into the FGV core VI. In this way the Init VI only has the things that are important to it on the connector pane, and it makes it easier to understand how the user is supposed to use the API, rather than throwing a bunch of controls that will be ignored on the FP. Using more scripting I think you could choose which data is important for each instance, or even detect it in some cases, but that would be a ton of work. I'd suggest just doing that manually.
  16. Saved in 2011 FGV Wrapper Maker 2011.zip
  17. So here is a fun little nugget I worked on over the weekend. At our local user group there was discussions about action engines, and functional global variables. People talked about how a Action Engine, that has several cases like, Init, Read, Write, Close, will have inputs and outputs that just aren't relevant to every method of that VI. So people said how they some times write wrappers to their FGV where each VI is a unique value for their enum. This allows them to delete the unneeded controls and indicators, making for an easier to understand API, where only the important inputs for that method are exposed. So I wrote some code to demonstrate how to accomplish this with scripting. I figured this function might be useful to others. Included in the zip is an example VIG that can be used to demonstrate how it works. FGV Wrapper Maker.zip
  18. Well there isn't a single solution. It sounds like what you want is a combination of tools, and will likely need something custom to meet your needs. It sounds like some of what you want can be understood with the VI Analyzer which is used to scan code for specific rule like no more than N local variables in a VI. There are several installed tests, and many extras online others have made. The code that runs these tests are in an LLB and you can probably copy it away and use it in your own scripting code. The project has several scripting functions, like getting all dependencies, and all dependencies that are of a specific type. (class, VI, etc). And the code complexity metric is an property node on a VI for Compiled.Code Complexity. I've used these tools in the past to generate pie charts showing how much code in a project comes from OpenG, or vi.lib or is written from scratch.
  19. Without an XNode license creating a list of available properties and methods of the XNode and XNode Library classes is difficult. It is similar to having private methods. If you have a private property on the BD it works just fine and you can copy it and use it in other VIs. Luckily NI has scripting functions for doing things like setting property nodes and finding what properties are valid for a specific class. So with the help and collaboration with Jack Dunaway I've made a tool for getting the list of available property and invoke nodes for the XNode and XNode Library classes, and allow you to make those objects. Now not all of the functions will work without a XNode License but I suspect most do. Several abilities in an XNode return a XRef which is a reference to the XNode and is where these properties and methods could come in handy. Also attached is a VI that just has all of the properties and methods for LabVIEW 2013 SP1, but the tool should be able to make any new ones in newer versions as well. But all along we had the power to make these using native LabVIEW tools. Quick Drop has the class browser function, with it you can set the class of objects and the properties of property nodes. So following these steps will create an XNode property: Drop a new property node on the BD. Select the property node. Invoke QD Type "XNode" (without quotes) Press CTRL+B Select the property node Invoke QD Type "State" (without quotes) Press CTRL+Shift+B And lastly this is all very experimental. Using undocumented XNode technology, along with private functions can lead to unexpected crashing and strangeness. But for the most part these properties and methods have some level of documentation just don't be surprised if they don't work right, or don't do what you expect. Create Methods Properties for XNodes.vi All Methods and Properties.vi
  20. The previous solution is probably better than mine, but I can think of an alternate way. Fonts are installed in Windows in the following path %windir%\fonts You can probably perform a list files finding all installed fonts there. I'm not sure if fonts can be installed into a location other than that, and if it can then that is a reason the .Net method might be preferred.
  21. Obligatory free training links. NI Learning Center NI Getting Started -Hardware Basics -MyRIO Project Essentials Guide (lots of good simple circuits with links to youtube demonstrations) -LabVEW Basics -DAQ Application Tutorials -cRIO Developer's Guide Learn NI Training Resource Videos 3 Hour LabVIEW Introduction 6 Hour LabVIEW Introduction Self Paced training for students Self Paced training beginner to advanced, SSP Required LabVIEW Wiki on Training
  22. I just tested the progress bar and it doesn't work for me. On Windows 7 x64 LabVIEW 2014 SP1 32-bit, the progress window comes up, but the progress bar doesn't move forward. And closing the dialog hangs LabVIEW. I looked into it and for me an error is generated in the Get ProcessIDsOfWindows.vi, and the while loop never stops executing. It should probably stop on error.
  23. Wow really? I haven't had a chance to try it yet but I sorta agree with Shaun, even though this is a feature I could see myself using. Lots of cool features in this but we need some stability. I mean the structure and file layout alone has changed probably 3 or 4 times since discussions started. And the code could still use some much needed attention in the form of interface, icons, and documentation.
×
×
  • Create New...

Important Information

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