Jump to content

Rolf Kalbermatter

Members
  • Posts

    3,903
  • Joined

  • Last visited

  • Days Won

    269

Everything posted by Rolf Kalbermatter

  1. I have the same stance and in fact I wouldn't even notice that bug . I always intiliase tab controls explicitedly in my constructor state of my state machines. Don't ask me why, it just feels better. Rolf Kalbermatter
  2. The thread swapping is only one aspect of difference. A Value property always operates synchronously. That means it will wait until the new data has been drawn in the UI (quite logical since it already swapped to the UI thread and incurred that overhead anyhow, just do the drawing as well). A local variable will behave mostly like a terminal. Yes there is an additional copy involved but the worst thing about locals (and globals and property values) is that you can easily create race conditions and those funnies can be very hard to debug, since the fact of debugging can chance the execution order and create or avoid such race conditions randomly. And as long as the according control is set to not operate synchronously, updating a local or terminal will NOT wait until the new value is updated on screen. It will simply drop the new value into a buffer of that control and go on. The UI thread periodically will check for such controls that need an update and redraw them. This has the advantage that a control that gets updated in a loop will not slow down that loop very much. You can make a small experiment: Create a loop that executes 10000 times and just creates some random value. In one case wire that random number inside the loop to a terminal or local not set to be synchronous (the default). In the other case wire it to a terminal or control set to be synchronous or a value property. You should see the asynchronous terminal executing fastest directly followed by the asynchronous local. Then far slower the synchronous terminal and local (really little difference here) and last but not least the value property which will be the slowest by far. The reason is that updating a control takes a long time in comparison to computing numbers and shuffling data around in memory. So in asynchronous mode the loop iterates many 1000 times per second, while only maybe 60 of those values are really shown on the frontpanel and if someone now says: what? LabVIEW does not show me all values! Then think again. You can't even see those 60 values as they change way to fast for the human eye so why try to update more than that? In synchronous mode, and the value property is inherently synchronous with no way to avoid that, the loop will only iterate in the 100ds per second as for each new value, the control has to be redrawn completely. Rolf Kalbermatter
  3. Because this Browse for Folder is really useless on older Windows platforms. Before XP it is simply a non-resizable mini dialog that is no use at all for serious Browse for Folder work. Also because anything like this they do on Windows they have to port somehow to Linux and Mac too. Mac probably has such a thing but I doubt you find such a native dialog specifically for Folders on Linux. And why it doesn't work with anything but the desktop for the PIDL is logical. A PIDL is not an enum but a binary data structure with private content that describes a path in terms of the shell name space. If you select desktop this is NULL so BrowseForFolder interprets this as a NULL PIDL which happens to be the Desktop too. But in all other cases it interprets the value as a pointer (oops pointer to address 1 is a surprise that it didn't immediately crash). To create PIDLs you have specific shell32 APIs that take a path and return the according PIDL to it such as SHParseDisplayName(). Or you could use SHGetSpecialFolderLocation() which probably could translate your enum directly into a pidl, though I didn't check if the CSIDL enum of that function matches with your enum. Rolf Kalbermatter
  4. ILFree() was an undocumented shell32 function since Win95 and Microsoft documented it after the big monopilist case they got into, which was I believe after Win 2000 was released. Those undocumented functions were exported by shell32 but not by name but only by ordinal instead. The ordinal number for ILFree is 155. And now the nice part: The Call Library node supports importing by ordinal. Just enter the number into the library name field. PS: ILFree is indeed just a wrapper around CoTaskMemFree even on older platforms. Rolf Kalbermatter
  5. We probably did . Well there is another solution although it is in fact in a sense a global too. And your original solution with the IMAQ ref already goes a long way into that direction. Make that VI an Action Engine or as I call them an intelligent Global with a method selector. Calling the Init method from the pre-sequence where it does the opening of the resources (and that deamon stays in memory polling the same or another Intelligent Global for the stop event). Then the Execute method or methods do whatever needs to be done on those resources and the Close method is called from the post-sequence step and closes all resources as well as sets the quit event for the deamon. Rolf Kalbermatter
  6. Well but that is about the VI refnum itself. However this does not solve the issue with other refnums opened inside that VI once that VI goes idle (even when the autodispose is set to ture when opening the VI ref and that VI does not close its refnum itself) and in TestStand this is the most simple way to open common resources, by opening them in a pre-sequence step. However that step simply runs and then stops. The only way to circumvent that is to keep the VI you are launching in the pre-sequence step running as a deamon and then shut it down in the post-sequence step. Rolf Kalbermatter
  7. Aaah well that clears up a lot. It sounded a bit like you wanted to try to tell everybody on LAVA how to do things . And that is something doomed to fail, because after all we are LabVIEW Advanced Virtual Architects and no advanced guy/gal accepts someone else trying to tell him/her how to do things the right way. In your situation even if you are in a position where you have the powers to force people into doing something, the best thing would be education. Try to establish some training sessions. Nothing fancy or to formal but something like half an hour each week where you get all the people together and then show them some means to get well organized. Get it interactive, and let them workout the solutions you want them to learn. Make from a group of individual fighters a real team. And most important don't expect this to change everything in two weeks. Be persistent but without being notorious. It will not change after the first time, and only slightly after the 5th. But there will be change over time and as people see that it is more effective to do the things in a somewhat more organized way it will without doubt have an impact. Rolf Kalbermatter
  8. Up to 8.6 I do not have any beep when doing that. I'm using the old style icon editor though. Rolf Kalbermatter
  9. No! Once the Top level VI, in whose hierarchy the Open/Create/Obtain LabVIEW refnum was executed, closes, that refnum is disposed without mercy. VISA is a notable exception since you can change in the LabVIEW options that VISA sessions should not be autodisposed. Rolf Kalbermatter
  10. Somehow I can't follow you. First you say that the property node is terribly slow, although the reasoning for that is only partly right. Yes it operates in synchronous mode so it will force an update of the control on each iteration before going to the next iteration, but there is also additional overhead because the property node (any VI server property node at that not just the value one) has to run in the UI thread so there are also always two context switches involved. And then you say one should always use the property Node for a tab control. I always use a local for that and had not any problems so far. I think we had established that the problem here was the "parallel" execution of the string property node (and only for an element contained on the tab control) when updating the tab control through a local variable. So replacing the string property node with a local variable seems to me the better solution. Rolf Kalbermatter
  11. DirectX is a technology from Microsoft. It can do zillion things and one. What is it you want to do? Most likely you are talking about the DirectX interface to access Webcams or other image acquisition devices. In that case there are virtually 100ds of threads in this forum that go about that. Doing a search here and read through them all, while being a very time consuming process, will give you likely more information than you have bargained for, and still be more effective than any crash course we can come up with. Rolf Kalbermatter
  12. Well you can save a VI with removed diagram. But this has the aforementioned drawbacks. It contains only the compiled code for the LabVIEW version that created the VI and also only for that platform. Some of your user is likely to have not the same version of LabVIEW or wanting to use it on the Mac or Linux instead which requires LabVIEW to recompile the diagram. But wait there is no diagram, so the VI is broken and the user has no way to fix it in anyway. So what does that mean? You will have to support whatever LabVIEW version your users have or state this VI will only run in LabVIEW x.y on platform Z. Such a limit is likely to make the acceptance of your library to go so low that you can just as well stop distributing it at all, since nobody is bothering with it. It is already hard to get people to bother about VIs that are not protected and free of charge if they do not come from NI, so any extra hurdle, even the password protection alone, makes that only harder. Also since you have no way to go from the "protected" VI back to the unprotected VI you do need to maintain backup copies of the unprotected ones. An error where you accidentally overwrite your unprotected VI with the "protected" one happens so easily, believe me I can guarantee you that this will happen to you! Rolf Kalbermatter
  13. Look, a LabVIEW byte array (string) is like this: typedef struct { int32 len; uInt8 elm[]; } **LStrHandle; So you hav a number of problems to pass this as a C String pointer. 1) The actual character array starts with an offset into the real memory area. 2) The LabVIEW string is a handle (pointer to pointer) 3) Last but not least LabVIEW data can be "hyperdynamic". This last one is very important! LabVIEW reserves the right to manage its memory in anyway that makes sense to it. So if you create a string containing a set of characters, then run some magic like memcpy() (I prefer the LabVIEW manger call MoveBlock() for this) through a Call Library Node to get at the pointer that points to the actual string and try to pass that pointer to another Call Library Node to your API, LabVIEW might have reused, resized, or deallocated the original string already at the time your API is called. This in the best case could mean a simple Access Violation or crash or if you are unlucky a much less noticeable effect such as strange interactions with other parts of your code that operate with the reused memory, where your API now tries to write something into (or the other function reusing that memory writes something in and your API reads suddenly gibberish). There are tricks such as making sure the original string wire runs through the diagram without any branching to some place that due to dataflow dependency will execute after the call to your CLN API, to hopefully make LabVIEW retain that string memory until after your API executes. However while this did work in older versions, there is always the chance that by new and improved optimization strategies in newer LabVIEW versions, this suddenly might fail. The reason this works until now is that LabVIEW does not usually do diagram optimizations across structure boundaries, so if you run your string wire to a sequence structure border that depends on your CLN being called and finished too, you are nowadays safe. But if you just wire that string wire to the border without using it, there is a good chance that a newer LabVIEW version with an improved optimization algorithme might realize that this string is never used after your memcpy() hokuspokus call and suddenly the string is gone anyhow, at the time your API call tries to access the pointer that you retrieved with so much virtue from the LabVIEW string handle. Rolf Kalbermatter
  14. You can not pass LabVIEW clusters containing variable sized elements such as strings or arrays to a C function. LabVIEW stores its arrays (and strings which are in fact just byte arrays too) very differently than what a C API function expects. So the best apparoach is usually to write a wrapper DLL with a function that takes the elements in the cluster as individual parameters and constructs the C structure to pass to the real API. There is in principle also a way to do it all in LabVIEW, but to be able to do that you need to know a lot more about C programming and its datatypes than you will need to write a wrapper DLL in C. Rolf Kalbermatter
  15. What has this to do with VI scripting? This is a very simple starter question and the answer is to look through the zillions of examples that come with LabVIEW and the various drivers/toolkits. The Example finder in the Help menu is a great tool for that! Rolf Kalbermatter
  16. What is wrong about password protection? It's by far the best method, unless you want to hide your code from NI, who theoretically have the ability to look at that code anyhow with ease. Anything else has only a lot of drawbacks. It consists basically of removing the diagram code entirely from the VI that you give to the customer. The drawbacks are: - The VI will not work on any other version or platform of LabVIEW since LabVIEW can't recompile it. - Maintenance of two VI versions, one without diagram and one with is more complicated. Rolf Kalbermatter
  17. I would actually rather have changed the string value property to a local variable instead. It is a noble attempt to avoid locals as much as possible, but using the value property instead is in fact fighting the devil with the beelzebub. Rolf Kalbermatter
  18. I believe IPv6 has some inherent capability for such load balancing (it is somehow done by assigning addresses from a specifically reserved address range to the interfaces, although I'm not sure how that would have to be setup) but with IPv4 this is a lot of hassle. You basically have to program those three links as independent communication channels and do the load balancing yourself somehow. So three listen sockets bound to the correct interface card address on one side acting as individual servers and three client connections. The client will have to load the data into memory and split it up and add some sequencing information into a header and the server will have to accept those data and resequence the packages into a continuous stream. A bit like reimplementing TCP/IP on top of TCP/IP. Rolf Kalbermatter
  19. A good historical database can easily top those 900 data samples per second and the querying of data is also quite a bit easier since the indexing over the sensor ID is not necessary. With a historical database where each channel is in fact its own table with a timestamp, value and status column (and no need to have relational humbug and such, so this can be highly optimized too) the organization is much more straightforward and the logging of data is very fast. The only difficulty here is the querying of combined data, as you need to do a similar thing to a join statement when wanting to query multiple channels at the same time, but that is a task that can be overseen fairly well since the structure of the tables is very simple. With your approach querying does only get more complicated as far as the database engine is concerned although for you as user you will not see much of a difference. Adding a new channel in a historical database is simply adding a new table and that has no influence whatsoever on the other already logged data. For the end user it won't make a big difference other than that a historical database can be much more optimized for the task at hand than solving this with a generic super duper relational, object oriented and whatever else database engine. And yes the select statement will look a little different . Rolf Kalbermatter
  20. Why should it do that? The decision what display precision to use is done at the moment the constant changes from non-float to float but is not changed if you change between float representations. Should it do that? It's IMHO highly discutable. I would not like it to change display precision when changing to a different float type after I have changed it to a specific display precision. So this would mean LabVIEW would have to store an additional attribute to the display precision, indicating if that precision has been user changed in some ways or is some automatic default value. Possible to do but most likely not worth the trouble as this would not just be a simple line of code to add but go deep through the entire datatype handling of LabVIEW. Rolf Kalbermatter
  21. As others have said you can do that for yourself and your team (if you have any decision power there) but trying to get other people to follow your ideas is very surely doomed. This is a problem in any programming environment and one there is no real solution other than restricting your desire to standardize to the group of people you have power to tell what they have to do. In standard programming languages this starts for instance at indention, bracket styles, UpPeR/LoWeRcAsE, naming conventions, etc and goes further over what types of elements are allowed respectively required. Most Open Source projects try to have a more or less strongly recommended style but seldom enforce it very strictly unless in those projects where committing power is restricted to one or two "benevolent" dictators. So in short, discussion is fine, but accept that everybody who has been working in LabVIEW for a while, has his own style and is very unlikely to be convinced that someone elses style is better. Rolf Kalbermatter
  22. That is likely to work but has probably not the intended effect since the tab is now changed all the time independent of the event that occurred (or you have to make sure to wire out the correct (current) tab control value in all other event cases, for a real application!). Using a value property for the tab control (or preferably a local for the string) seems a more logical solution here and since that executes in the UI thread it involves a context switch and is sure to avoid the optimization race condition that seems to be in place here otherwise. Rolf Kalbermatter
  23. Most likely the patch is really limited to fixing just that single issue and nothing else. So if your computer is not using WMPs you can probably ignore that patch. More fixes would make testing of the fix more involved and I'm sure they are saving their developer and tester time for the LabVIEW 2009SP1 release that is expected somewhere in the begin of next year. Rolf Kalbermatter
  24. The exclusive access of serial resources in VISA from different applications is not a VISA "feature" but a Windows OS feature. Once an application has a serial port driver open, Windows will under normal conditions not allow another application to open that port again. As to why there is a Lock and Unlock. You can have applications that communicate from different locations through the same communication port. VISA supports that but obviously it can not know about the communication protocol so if location A writes a command and then location B writes another command (to possibly a different subdevice on that communication link) it is random who will read the response to the A command and who will read the response to the B command. Resource locking solves that problem reliably in that A locks the resource, writes the command and receives the response before unlocking. Rolf Kalbermatter
×
×
  • Create New...

Important Information

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