Jump to content

Jarrod S

NI
  • Posts

    23
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Jarrod S

  1. You don't have to choose between classes and polymorphic VIs. You can get the inheritance you want, automatic function selection, and you can make it an edit-time error you choose the wrong read and task creation combination. Check out this example of dummy classes.

     

    Open example.vi attached here (saved in LV 2012) to get an idea of what I mean. We have done this in our classes before with great success. In fact this can work better than doing Dynamic Dispatch for your reads, because there is no run-time overhead for LabVIEW to determine what Read VI to call. But you still have the flexibility to define your OOP hierarchy.

    daq classes.zip

    • Like 1
  2. I realise what I asked is impossible, Friday afternoon wishful thinking.

    The number of rows the user will need is not known at build time hence the array. Perhaps there is another way of getting what I want.

    The standard way to fake this is to have a cluster hard-coded to contain a few entries with a custom scrollbar running down the side. The data you store is an array, but the front panel control is a cluster. Depending on the position of the custom scrollbar, you copy in the selected array subset into the cluster.

  3. Do note that generally drivers like NI-RIO are not available in the first Beta. Their beta versions usually arrive for the second Beta. So if you sign up now, you'll only be able to test out your host-side app to start with.

  4. I've run into a problem where I need to fetch the hWnd of a VI's front panel which has no title bar. Usually I just make a call to User32:FindWindow with a null class and the title bar string, but it seems if the title bar doesn't exist, FindWindow can't do it's job.

    I might be able to make the title bar visible, do the FindWindow call, then re-hide it, but I'm looking for something more elegant which won't introduce flicker, etc.

    Anyone have any ideas?

    There is a VI property to get the window handle. I think it's one of the super secret hidden property nodes. Not sure if scripting support turns it on.

    On a side note, beware of getting an hWnd by FP title! Danger lurks! We had a huge bug in Vista that all boiled down to this. The problem is that in Vista the little Aero preview windows that pop up when you hover your mouse over a TaskBar item have the same window title as the window they're previewing. This makes it possible to accidentally get an hWnd for the preview window for your VI instead of your VI itself if you call FindWindow when the preview is active. Nasty little bug took us forever to find. Win7 does not seem to have this issue. Stick with the property node.

  5. Assuming you mean a traditional Windows driver, you can't.

    You'll nee to use the Windows Device Development Kit and it uses some version of Visual Studio and write it C or C++, I forget which.

    On the other hand, if you make it with a USB interface and HID compliant you won't need to make a device driver. Windows (and just about every other modern OS) will recognize it and use a built in driver for it.

    There are many microcontroller products/projects out there that ship with a USB interface and HID compliant stack.

    You can't exactly create a LV driver, but you can use NI-VISA as the driver for a USB device, and then use VISA functions in LV to send USB-RAW communication to the endpoints. This would allow (very) low-level control of the device from LV, even though LV isn't technically the driver.

    Search VISA and USB-RAW for more info or see here or here to start.

  6. You can't register for events from controls in another application. That functionality doesn't exist.

    You would need to add code to the exe to facilitate getting this data out. You could do this in a similar way to the example below, which registers for User Events (rather than front panel events) across app boundaries.

    http://decibel.ni.com/content/docs/DOC-14216

    It will take some work, but the solution could be made fairly generic. The basic idea is to have the local app request that the remote app register a particular event on its behalf and forward it the data via some callback.

  7. I'm responding to user interface events using an event structure. However, some of those events are coming from a signaling property node. Is there any way from within the event structure to detect the difference between actual user generated events?

    You can't do this. However, instead of using Value Signaling property nodes you could use User Events. You can even create a User Event that can be registered in the exact same event case as a Value Change event. The trick is to make the User Event data be a cluster with the exact same event data from the original event type. Then, the Source terminal on the event structure could be used to tell if it was a UI event or User Event.

    Attached is an example (LV2010).

    More importantly, though, why do you want to know the difference?

    User Event Overloads.vi

    • Like 1
  8. QSM? That's not a LabVIEW feature. Also, there are many many different ways to do QSMs with many different advantages and disadvantages. If poorly developed, then yes, they are a pain. But nothing protects against bad code.

    Probe Window: Big yes. Terribly painful. Off the top of my head here are the biggest pain points:

    • It's a floating window, so it's forced to stay on top of other windows. Why?!? Don't force this behavior on me! Why is it shocking that I'd want to view other windows on top of the probe window?
    • Since it's floating and I can't put it behind other windows, I regularly minimize it. However, probing a new value does NOT restore it! Wrong wrong wrong.
    • Generic probes don't resize to fit the large amount of space they now have. This means that numeric and string probes only show a small fraction of the content, with no means of seeing it all (other than creating a new probe type).
    • The dialog remembers its last size, but gets confused if it was last maximized. It tries to set its new size to be the size of your monitor, but it is not in a maximized state. Wrong wrong wrong. This forces you to manually restore it to a normal size. I HATE this. Especially when it's so common that you want to maximize the probe window to get the most out of it.

    Shared Variables: Definitely agree. Now that you can dynamically read and write to them, why can't you programmatically create Shared Variables on the fly without the DSC module?

  9. Hi!!

    I've used VI server before for some simple tasks, and it has always worked as expected. However, for this task, it is becoming increasingly frustrating.

    What I'm Trying To Do:

    Look into any previously made executable in LV and get the memory information of the VIs internally. We're suspecting a memory leak in one or many of our named LV2 Globals within a range of our applications on the production line. Instead of painfully editing the EXEs on the production line, we want another EXE to go in and analyse the VIs we're interested in.

    What is Going Wrong:

    The tool I've created only sees the list of VIs within its own EXE and not the other!!! I'm connecting to port 2020 (set in the ini file of the EXE I'm trying to access) and set the port of the analyser to 2022, and it STILL somehow connects internally!!!!

    What I've Tried:

    • server.tcp.port=2020 in target exe
    • server.tcp.enabled=True in both
    • Simple "Open Application Reference" VI with the port number set to 2020
    • Read the "Srvr.Port" application attribute of the analyser to check it is set to 2022 (and it is)
    • Checked out this CONFUSING NI link http://digital.ni.co...62571DA005B896C The last option seems to suggest you can just go ahead as always.... I don't get itblink.gif

    I'm expecting at the very least to get an error when it tries to connect to port 2020 when it's not there, but it doesn't. It just somehow connects to itself and returns the list of VIs within itself.

    NOTE: The application is in LV8.5.1 and the Analyser is in 2009 SP1. I didn't think that would matter as the TCP layer should abstract all that right?

    I've compiled it in 8.5.1 now and still exactly the same result.....I'm fresh out of ideas now

    Any help would be greatly appreciated.

    Thanks in advance,

    Youngy

    Make sure to use a non-blank string for the IP Address. A blank string indicates the local application instance, regardless of the port specified. I've made that mistake, too. Instead use the string "localhost".

    • Like 1
  10. Howdy!

    Warning! - This may be stupid question (please bare with me tho) :)

    In a project, data (hierarchy of classes, which contain clusters) is saved to disk on the Real Time

    The file is read back on desktop PC.

    (This has worked fine for ages) What is now coming back is error 1527 on the unflatten from string primitive.

    Error 1527 occurred at an unidentified locationPossible reason(s):LabVIEW:  Attempted to read flattened data of a LabVIEW class that is not currently loaded into LabVIEW.

    As with the nature of Real Time, you need to save files before compiling down to the target.

    Therefore my questions are:

    1. Does the error relate to a class version mismatch (i.e. the Real Time has a newer version than the desktop PC)?
    2. Could the class version have been incremented in the compiling down to the target (but was never saved as the file was never checked out and subsequently everything is now out of whack)?
    3. Or could it be something else?

    Cheers

    -JG

    I have seen this error happen before for classes that belonged to a LV library. They would fail to be unflattened with this error even though the class was indeed in memory. I believe this bug was fixed in LV2009.

    • Like 1
  11. I see what you mean.

    But your "Class" example isn't exactly analogous to the VI example (just being picky :P ).

    If you inspect your middle VI, you will see there is a coercion dot. So the equivalent class implementation would be

    As you can see. this also has the same issue. The class example is really analogous to creating a polymorphic VI

    I think what is wanted is that there is not a coercion dot, because the coercion never happens. The type should be propagated across the subVI without changing.

  12. Is there any sort of LabVIEW voodoo that allows you to propagate type information for a refnum through a VI?

    This is sort of a non-answer, but it helps me and I think has merit. What I always do in this situation is not pass the refnum back out from the subVI. There is only a refnum input. This prevents the caller from accidentally doing the cast to a more generic class. It has the downside that the calling code is a little uglier, since it can't railroad the refnum wire through for multiple calls to such subVIs.

  13. Ah right. Forgot to mention that. Yes, the code is wrapped between a set of defer update property sets.

    Beware using Defer FP Updates continuously in a loop, such as for each update to the tree. It will disrupt right click menus and file menus. It will completely dismiss the menu. It will do this even in other VI FPs than the one being deferred, I believe.

    We have successfully delayed populating trees in terms of child items of parents that aren't expanded, but not items that are off the current scroll region. I would not recommend trying it much. On the other hand, I also wouldn't use a tree control to display anything that needs to be updated continuously. A listbox would be much more efficient because you can just use the Item Names[] property node to update a whole column of text. You can also simulate a hierarchy in a listbox by having a ring above it to select the current visible section, or perhaps a tree to the left where you can select the visible section(s).

  14. Is there any priority logic that gets applied to tasks that are blocked on a DVR refnum at an in place element structure?

    That is, consider two tasks which are both blocked while waiting for a refnum to become available. Is there any way to know which will be allowed to operate first? Does the priority of the containing VI affect this decision at all? Does the order in which the tasks blocked influence which will be signaled first? What about the phase of the moon?

    I bet it's the order that they arrive at the IPE structure. I really really doubt that VI priority plays any role. For instance, I know for a fact that VI priority does not seem to play a role for queues when two Dequeue operations are competing for the same queue reference. Granted, DVRs may be a little different, but I doubt they're that different.

  15. Hi Mikael,

    Take a look at Tomi Maila's presentation on recursion with classes. To achieve what you want, he uses a LabVIEW Object in his List.lvclass and takes care of the typecast in the methods. If you put A.lvclass as a member of A directly, that's illegal... but put a Generic Object in your A.lvclass and you're good to go.

    This is true. However, you don't have to use a generic Object. You can store any ancestor of an object in its private class data. So if there is some parent class that closely resembles the child class, it might be more useful to use that instead of an Object. But either will work fine.

  16. post-17242-127431517371_thumb.png

    In my case it is that the event structure that seems to get messed up. The frames have the right code. The event condition that they were originally associated with got switched or removed and replaced by an existing one. I am not sure what caused my remap. I originally thought it was because of the similar names. It may be related to this:

    http://lavag.org/top...dynamic-events/

    At the moment, in my large app, I do have an Event Structure where an event is listed in multiple cases and I know I did not do that. I have not fixed it yet as the project is idle at the moment.

    I am OK with ugly if it is the prettiest work around. Thanks!

    -kugr

    You can use the Bundle function to collect your events and give them custom names. There are two equivalent options here:

    Bundle the events going into the Register Events function so that you have a cluster with three user events. Give each event whatever custom names you want. Wire the whole cluster into the Register Events function.

    Register each event individually with three Register Event functions. Then wire the three registration refnums into a cluster. Give each registration refnum in the cluster a unique name. Wire the whole cluster directly into the Dynamic Events terminal of the Event Structure.

    In summary, you can bundle together both events and event registration refnums and everything pretty much just works. Pretty cool! Play around and let us know.

  17. Has anyone else noticed a significant increase in variant attribute performance in LV2009SP1 from LV8.6.1?

    In the past I had been using VA's for Current Value Table Implementations but reverted to using simple

    numeric arrays in LV8.6 since the array based implementation seemed to be faster. Now in LV2009SP1

    the opposite is true by a wide margin (40%).

    Yes, there was an improvement in LV2009 for Variant Attributes. You should see a notable performance improvement, and much better scaling adding or finding items in large sets.

  18. I'm just finally getting enough time on my hands that I can explore DVRs. I think I'm missing something with respect to error handling and I'm hoping someone can enlighten me. See below:

    post-11742-126892283135_thumb.png

    My first thought when I tried wiring this up was of the whiskey tango foxtrot variety, and well...it still is.

    The process of taking in a DVR, checking for an error, deserializing contained value, operating, then reversing the process is inherently...serial. Why is the error handling so discontinuous? Why doesn't anything have error in terminals which forces me to bundle 3 values together each time I need to operate on the DVR? This seems unnecessarily messy and inelegant. Am I missing something?

    I agree it's terrible usability. But I think the reasoning behind it may be functionality-related. Usually nodes that have an error passed in are a no-op. What happens if the left DVR node has an error passed into it? Does it dereference the value? Does it output a default value and leave the reference alone? Even more questionable is what happens if the right DVR node has an error passed into it. What happens then? Do we leave the DVR open, because the close operation doesn't happen? Is the value ignored?

    Ideally I would like these nodes to have error inputs, but they have no change in behavior when an error is passed in. From a usability and inplaceness perspective that is best. That, however, is completely different than any other function.

×
×
  • Create New...

Important Information

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