Jump to content

Mark Smith

Members
  • Posts

    330
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by Mark Smith

  1. QUOTE (Eugen Graf @ Jan 21 2009, 03:51 AM) LabVIEW has some real underlying issues with the namespaces (classes, lvlib) and building into an exe - just try building an app using a lot of the new plug and play instrument drivers that use the same VI names for things like Configure, Read, etc and differ only by location on disk (they all reside in different folders) and owning library. You'll get a built app that may have half a dozen folders deployed so that each VI can still have a unique name. It looks pretty ugly, but I'll give NI credit - it does work. Still, this doesn't look like a good long-term solution since a LVOOP app will be even worse - if you have a lot of override VIs in a large app, I can see where you could get hundreds of folders in a deployed app. So, it appears we have a LabVIEW dev environment that uses namespaces but a compiler/linker that really does not - as you pointed out, each VI name must be a unique path. You can achieve that by prepending something to the name, or you can just save your child classes in unique directories - then the complete path to the overridden VI is still unique. The app builder will maintain this unique path (even though it will report a name collision) but it will create as many deployment directories as you created for the child classes. Does anyone have any insight as to what the long term vision is for this issue? I'm curious. Mark
  2. QUOTE (Mourad @ Jan 20 2009, 11:58 PM) The first thing I noticed when I opened your file was that it is pointing to a LLB file in the instrument lib folder for the sub VIs - that means it must be pointing to an older version of the instrument driver - the latest version is a NI plug and play driver. Second I noticed that the resource name is an IVI typed control - this probably means that your version of the driver was converted from an IVI driver (which could be fine) but the first thing I would try is to replace the IVI driver with the LabVIEW plug and play driver. http://sine.ni.com/apps/utf8/niid_web_disp...?p_model_id=978 Third, the default value in the resource name is a GBIP address - are you using serial or GPIB? Next, does the instrument return the correct response string to the *IDN? query in the Initialize? If it does, then you are probably communicating correctly with the instrument - if not, then you first need to figure out how establish communication before you try to make a measurement. Try these things and let us know if it helps. Mark
  3. QUOTE (Michael_Aivaliotis @ Jan 19 2009, 03:06 PM) Thanks for the observation - that's the stuff I need to hear Mark
  4. QUOTE (gleichman @ Jan 19 2009, 01:09 PM) I spent about 3.5 hours on the project (4 hours on the clock but with interruptions) - There was certainly no intention on my part to be clever - I've just spent a lot of time lately with scalable architectures using reentrancy so that's the first architecture that came to mind that I was sure I could code start to finish. What took longer than I thought was re-acquainting myself with the LabVIEW FileI/O VIs to create the logger part of the problem . I just haven't used them in a while and they've changed! QUOTE (jcarmody @ Jan 19 2009, 01:39 PM) I was going to say that! I always get beaten to the punch... Also, and I don't know if it matters to the judges, but it's cleaner to label your wires with a System label. Good job! /Jim Thanks to both for this tip - it is a lot easier to read. And as far as system labels, I had to go google that to find out what it was (took me to the LAVA WIKI!) Mark
  5. QUOTE (Ton @ Jan 19 2009, 12:08 PM) I just ran out of time! So that is exactly what I would have had to submit and I guess I would have been dinged :thumbdown: QUOTE (Ton @ Jan 19 2009, 12:08 PM) Intermediate comment: Mix-up of system and labview GUI elements (BD color is dialog the rest is native LabVIEW) I often make the User Interface VIs the dialog color (even though they may not be dialogs) because 1) It looks more "native" to windows 2) And it helps me immediately identify the FPs the end users will see Is this considered poor style by the LV community? QUOTE (Ton @ Jan 19 2009, 12:08 PM) Advanced critique: I would use a VI-reference to load the reentrant VIs: I like that - it does seem cleaner - I'll have to remember this QUOTE (Ton @ Jan 19 2009, 12:08 PM) (As you can see the BD of this VI has no documentation.) Use the auto-clean up tool for simple VIs, your reentrant loader had a lot of white space, auto-cleanup eases things out. Good-luck, with such a solution you have to pass. Ton Thanks for the feedback - I've been doing LabVIEW a long time but one can never do too much prep for an exam. Mark
  6. Download File:post-1322-1232389172.zip Anyone have time to take a look at my Security System implementation (the sample CLD app)? I'm taking the CLD Thursday and would appreciate any comments. Thanks, Mark
  7. I can't help you with the zip file issue, but if you want to try a different base64 encoder/decoder and see how that works, you can get the ones that are part of the XML-RPC Server for LabVIEW in the Code Repository (http://forums.lavag.org/XML-RPC-Server-for-LabVIEW-file156.html). The XML-RPC standard must support base64 encoding/decoding so I wrote these implementations for that toolkit. Mark
  8. I avoid this problem by not including my installers or exe's in the source code repository. If you version the project (which includes all the build info for the exe/installer) then you should be able to rebuild that version of the exe/installer any time you need one. With that said, I still move my released installers to another directory, zip them up with version numbers in the file names, and then commit them. This insures I can quickly supply a new installer to a customer and avoids the hassles you have encountered. I do think this is a common problem - I've learned not to include any of the auto-generated stuff (all of the debug databases, object code, support files, etc) from my VS projects, either. If I did want to keep certain items, one way around this in VS is to include a post-build script that copies the files to a location where the compiler or install build won't touch them, and then version control that folder. Also, not including installers really helps my commit/update times when I'm at a remote site and on a slow connection! Mark
  9. QUOTE (Tim Erickson @ Jan 8 2009, 02:31 PM) Assuming you're on Windows, the Performance Monitor is a good start but to get more detailed info go to http://technet.microsoft.com/en-us/sysinte...s/bb896653.aspx and get the Process Explorer app - you can get detailed info on any process on your system including memory usage.
  10. John, I agree with jdunham - use named queues and notifiers. The overhead of getting/releasing references hasn't caused any problems for me (as long as I remember to close the ref nums - on a long running app you can leak a lot of memory a few bytes at a time ). I contributed some thoughts on this thread about why I like named queues. -they can really make your code very modular. http://forums.lavag.org/VI-communication-b...&hl=mesmith Mark
  11. John, It's been a while since I've used ADO.NET (and then I used it in a .NET application) but it performed seamlessly when connecting to a SQLServer database. Indeed, ADO.NET and SQLServer are both MS's latest technology and are behind a whole bunch of data-driven applications that seem to perform well. I don't know what the current development cycle is on ADO (the ActiveX one) but I doubt that it gets a whole lot of attention from MS these days - for example, this page http://support.microsoft.com/kb/183606 is almost two years old now and it looks like one of the latest MS support pages for ADO. But I think you seem to have narrowed down your problem to LabVIEW/.NET overhead, which I find reasonable given my experience. I don't think the .NET interface gets the attention from NI anymore that it used to now that Brian T's not there (I would be happy to be wrong about this!). But I have successfully solved similar problems by defining exactly what I expect .NET to do for me and using the most loosely coupled interface possible. This almost always requires writing a .NET DLL to reduce the calls to/from LabVIEW. In this case, I don't think I would access the ADO.NET namespace from LabVIEW, what I would do is just use some structure to pass the data to/from a method defined by my DLL that then uses all of the .NET magic to write to and read from the database and reduce the LabVIEW/.NET interaction to an absolute minimum. I also used (years ago!) Jeffrey Travis' LabSQL and it worked as advertised - they are wrappers around the ADO ActiveX objects so this would save you a lot of time since he's already exposed LabVIEW interfaces. You could create some quick and dirty tests and maybe decide if this would increase the performance of your app. Lastly, there's NI's Database Connectivity Toolkit. I don't have any experience with it or have any idea what's under the hood. Mark
  12. QUOTE (Jeff @ Dec 19 2008, 04:39 PM) The reason you can't cast a parent object to a child is because there's no way for the parent object to be created with all of the methods/properties any of its children may have. So, if you were to cast the parent object to the child and then call some method specific to the child (or try to access some property) it simply would not exist. That's not true of casting a child to a parent where you can always be sure the properties/methods of the parent do exist in the child. So in this case, it sounds like an approach would be to find the type of the parent and then just instantiate a child object of the correct type with the given S/N and then discard the parent (it did its job of carrying the S/N info). Mark
  13. QUOTE (Val Brown @ Dec 18 2008, 01:25 PM) Where I work one isn't a real programmer unless they do embedded development in C or VHDL! So every community has its bias. But I do fail to see where the OOP push in LabVIEW makes it less cross-platform compatible - is the LabVIEW OOP implementation (the native one) not supported on Mac and/or Linux? Mark
  14. QUOTE (shoneill @ Dec 18 2008, 10:17 AM) Here, I just meant that if the by-ref implementation were part of native LabVIEW, if you tried to use a class that used by-ref, you wouldn't have to worry about which third-party toolkit was being used and whether or not you had it installed. And you wouldn't have to try to figure out some hacker's (like mine ) home-grown implementation. Mark
  15. Like Ben, I have created my own "by-reference" functionality in LabVOOP since I found places where I really needed it - and I agree with Val that all of these versions make it more difficult to make portable code with OOP in LabVIEW. That's why I'm hoping that the next release of LabVIEW will support by-ref objects in LabVOOP. Then we'll have a complete and portable version. Mark QUOTE (Val Brown @ Dec 18 2008, 08:47 AM) QUOTE (neB @ Dec 18 2008, 08:04 AM) ...the "by-reference issue" (not built-in) is a non-issue for me since I just implemented my own version in LVOOP. Ben
  16. I learned how to do OOP using .NET (C# and C++/CLI) where all of the objects are passed by reference - and most everything is an object! I was an experienced LabVIEW developer when I started using .NET, so I was used to dataflow. The first time I passed in an object reference, copied that object into a new object, performed some operation on the new object, returned the new object from the function (or I thought it was a new object!), and saw my orginal object had been modified, I was surprised to say the least. I quickly learned what "deep copy" means in a by-reference context! With that said, once I learned how to properly handle objects in a by-reference context, I found this to be a powerful programming paradigm. Now, when I try to use the by-value objects in LabVOOP (native labview OOP tools), I feel like I'm fighting with one hand tied behind my back. But this may only be because to use by-value objects properly would probably require me to re-learn some design patterns and techniques. But I think my important point is that if you are a LabVIEW only developer, then it might make sense to learn the proper LabVOOP by-value techniques and patterns. Otherwise, I would choose one of the by-reference toolkits because what you learn there is more directly applicable to almost any other OOP development environment. But, I'm using LabVOOP right now on a project because I think it's important to learn how this toolkit works. In this project, I see a good use for inheritance so LabVOOP may prove its worth. I used the orginal Endevo toolkit (the one for LV6) on a previous project a few years ago and I did find it worked as advertised, but my opinion was that it's a lot of extra effort - and this version did not support any kind of inheritance. I'm counting on (hoping for?) NI to offer the option of by-reference objects in the next version of LV. Mark QUOTE (Val Brown @ Dec 17 2008, 10:58 PM)
  17. QUOTE (jenssona @ Dec 10 2008, 07:18 AM) Andrew, Sure sounds like the app builder is removing the front panel for the Print Report.vi. If it's not set as a Startup VI in the build specification, then it gets its panel removed. Go to the Source File Settings in the App Builder and disable the Remove Front Panel for this VI (the Print Report.vi) and rebuild. This might be all you have to do. Mark
  18. QUOTE (Phillip Brooks @ Dec 8 2008, 11:08 AM) I'm a little late to this thread, but I have to admit I did not know you could get the socket handle from a LabVIEW function (thanks for the info Philip!). My TCP IPv6 toolkit in the Code Repository already uses the socket handle as the connection ID, so one can use this LV function to get the socket handle and then connect to any of those VIs. I never thought about returning the socket properties until this thread, but it seems like it could be useful so I added the following (from the ReadMe for this toolkit) "GetType, Get Address, and GetPort functions - these functions take a socket handle and return the type (IPv4 or IPv6), the connected address, and the connected port. These may be used as part of this toolkit or can be used to return the same information from the native LabVIEW TCP/IP toolkit (Windows only). One needs to get the socket handle using the "TCP Get Raw Net Object.vi" found in "vi.lib\Utility\tcp.llb". Pass the Raw Net Object (socket handle) into these VIs." Mark
  19. QUOTE (Norm Kirchner @ Dec 9 2008, 01:37 PM) So maybe I didn't exactly answer the original question, but I think that named queues in LabVIEW are one of the more overlooked tools. I use these most anytime I need interthread communication inside LabVIEW. I even discovered that they make a reasonable way to create a functional global for sharing data among a single group of reentrant VIs - kind of like a private instance variable in a class so that methods of that instance can share data. But I digress... Anyway, I have explored the idea of creating queue managers (or something like that) inside LabVIEW but I think appropriate use of named queues makes it kind of redundant. LabVIEW is internally keeping track of the named queues - if I need to know if a queue ref is dead I only need to try to obtain that queue. If I manage the queues correctly - for instance, force destroy if I know I want the queue ref to die - I can always just 1) get all VI's in memory and 2) try to open their queues (if I expect them to have one). Then I effectively have a queue manager and I don't have to exert any effort to make sure I keep it up to date - LabVIEW gives me that for free :thumbup: . So now, all I have to do is have a consistent naming convention for my VIs with queues - maybe something like Queued_DoSomething.vi and consistent names inside those VIs for the queues - something like Input_Queued_DoSomething.vi and Output_Queued_DoSomething.vi. Also, keeping to your suggestion to keep everything strings (which I usually do), then any VI that needs to communicate can try to open the queue and if the queue exists, put something on it or take something off and new VIs are easy to introduce. Which brings us to the next issue with queues - queues don't broadcast to all registered listeners. Whoever gets there first consumes the data. This can be a real can of worms and kind of argues against a queue manager with unfettered access to anybody else's queue. It's all too easy to introduce problems when a new VI starts consuming data that you expected to have available for another VI. At any rate, it's good we can have these discussions because I'm always learning something! Mark
  20. QUOTE (Greg Hupp @ Dec 9 2008, 12:07 PM) Here's what I'm talking about (if you don't use reentrant VI's) - it's not specific to any target, it just shows how you might use a named queue to communicate with a dynamically launched VI. It has some advantages over using the Set Control Value methods since it's not sensitive to the control names on the dynamically launched VI. It does, however, have one drawback in that if the caller actually leaves memory before the callee gets the queue ref, the queue ref might get garbage collected before the callee can get a ref. If the dynamic launcher is, for instance, in a UI that stays in memory, that won't be a problem. Also, you could just leave the Create if not found True and avoid this problem. This also presumes that you're going to pass data to the slave from some VI other than launcher, but you could easily pass initial data from the launcher. Mark http://lavag.org/old_files/monthly_12_2008/post-1322-1228852101.png' target="_blank">
  21. QUOTE (ragglefrock @ Dec 9 2008, 11:01 AM) This is a good point - if you launch multiple copies of a reentrant clone, you have to make sure you communicate with the correct one. But one way to do this is when you launch the reentrant VI, get the VI Clone name - this is available thru the VI properties using the ref you just opened. Use this to build the Queue Name string (like InputQueue_%s formatted into string, which becomes something like InputQueue_My_VI:1). Then have the spawned VI get its own Clone name thru VI Properties and open the same queue. Then you have a unique one-to-one association without ever actually passing anything on a wire to the spawned VI. Mark
  22. Don't pass queue references at all - used named queues. The master creates the queues as named queues and then the slave can just get a reference to the queue using the Obtain Queue function. This completely removes any data flow dependency - that's good for asynchronous processes (threads) but one should always be careful because it's really easy to step on your ****. You can set the Create if Not Found in the slave to false if you want to make sure the Master has created the queue before the slave tries to access it. Also, make sure and close the queue reference in your slave when you exit or you will leak memory - the queue ref created here will remain in memory until all queue refs are closed unless you explicitly close it. Mark
  23. Move the DAQMx Write into the loop and then execute the loop as many times as required to recreate the complete waveform as many times as you want. If you start the task outside the loop, the device shouldn't reinitialize on every iteration (see the Start Task topic here http://zone.ni.com/devzone/cda/tut/p/id/2835#toc5). Stop the task outside the loop, and then clear. It may appear that the device is resetting depending on the end condition of your waveforms - are they continous if called back-to-back? If you've already tried this and it didn't work, to quote Emily Latella ( http://en.wikipedia.org/wiki/Emily_Litella ) "Never Mind" I don't actually have any hardware handy to try this so take this FWIW. Mark
  24. You can open a PDF file from LabVIEW (at least starting in 8.2, that's the first time I used it) using the "Open Acrobat Document.vi" in \vi.lib\Platform\browser.llb\. Look at that for an example of how to use DDE (http://zone.ni.com/devzone/cda/tut/p/id/4531) to communicate with external applications. You might be able to do something similar calling third party document conversion tools. Mark
  25. I second jcarmody - these are all good suggestions. This UI scheme that I frequently use demonstrates in more detail how the keep the current UI state up to date without locals or polling by using events and bundling or unbundling into a cluster. Mark Download File:post-1322-1228401271.zip
×
×
  • Create New...

Important Information

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