Jump to content

Jon Kokott

Members
  • Posts

    186
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Jon Kokott

  1. Networked shared variables are certainly easier to work with, and if they "work" then use them. That said, compared to straight up TCP (which is what they are built on anyway) crushes them. Its WAY more involved, and you're completely changing the architecture at that point. I take back that all shared variables are slow, its really just network shared (reading and writing a shared variable is pretty wicked fast).

    Publish-Subscribe shared variables is an approach that will definitely work. I really don't ever use them, but shared variables offer no mutexing (like a DVR or FG) if an atomic transaction is required, and need to be polled unlike a Queue. The publisher-subscriber approach with Shared Variables can be replaced by a Notifier. At the end of the day I prefer reference objects (like variables) to have their reference wired to them. Maybe its just personal preference.

    Aside from that, if you are dealing with same-application synchronization, which is my assumption based on the passing data to subpanels, Queues and DVRs are generally my bread and butter. If everything is in the same application space there is no reason to use a network shared variable (or any TCPing in general) as it will be unnecessary.

    Paul brings up a good point that Shared Variables are an effective way to do things and you yourself said you envision a solution using them. Sometimes its better to stick with what you know and get things done. If you are doing something simple like displaying a reading from a gauge, you'll be done in less time than it took to read this post! Without knowing the specifics of your application its difficult to know what the "best" solution is. I still like queues.

    Use the static VI reference, but "strictly" type it (right click on the static VI ref) then you can use an invoke node to insert that reference into a subpanel, then call by reference node to actually call the VI. This will allow you to wire the connector pane references that you may/may not need.

  2. I prefer message queues. Shared variables are... slow. You'll have problems with race conditions using them as well. I don't suggest using user events unless it is actually a user event. They are very similar to queues in performance but don't give you the same level of control (they only size unlimited, message can queue up badly in rare cases.) Your other options are LV2 globals (ugh, I don't like these, but they can be fast to program atleast.) and DVRs. With DVRs/LV2 you'll be polling in all likelyhood if thats the only mechanism you have for synchronization. Queues/User events will be all event based processing.

    This is a real challenge, and if you are new to these concepts, I would almost plan on writing your VI, taking a step back in a week or two, and re-doing the whole thing. Ultimately you'll understand how you're solving the problem better, and end up with something that doesn't look overly complicated to you anymore.

  3. OK this is a little more definitive.

    C:/Documents and Settings/All Users/Application Data/ = C:\ProgramData or C:Users\username\AppData\Roaming folder. I'm getting conflicting forum guidance on that detail.

    There is an NTFS Junction point linking those two folders. Win 7 supports symbolic links, so there must be a performance/usability advantage to using a junction instead (or maybe its just more proprietaryier <-lol.)

    at any rate, the username can create restrictions between users, use the "All Users" folder and it will be safer.

  4. In Windows XP:

    We use "C:/Documents and Settings/All Users/Application Data/<Application Name>"

    Supposedly that is guaranteed to give access to everyone.

    I'm on my home computer right now and the Program Data folder folder looks promising, I always like a shorter path. Should probably check the official Microsoft recommended stance on this, I know it changed from XP to Vista/7.

  5. Arg,

    Something is still not right about this.

    I'm updating an Xcontrol by directly wiring the terminal with a string extremely quickly. I don't actually need the control to update that fast, but its possible that it will get hammered like that every once in a while. The problem is that once execution stops, if it was recently "flooded" with data, the control keeps updating like crazy (like a queue, not an notifier) even after the VI is stopped. Once it finally catches up, its not always the most recent data. It would be nice to know that the last data value displayed is in fact the most recent. Is there any work around for this?

    Updating the value upon an execution change event does not work.

  6. I see what my problem is, updating the control is an asynchronous notify() operation, vrs using a property node is a synchronous operation. The documentation supports this, for some reason (because typical event structure behavior) I thought that updating the control value would be more like an enqueue() operation.

    I can see that there is a race condition if I modify the Xcontrol data during one of these notify() occurances. In fact, during rapid updates doing this is absolutely awful and results in out of date display very often.

    I'll have to rethink how to do this as modifying data in the Xcontrol can't happen fast enough to be practical.

  7. I've got an X-control which I am updating very quickly, but I noticed that even though the data is being sent to the X-control indicator, the data never gets to the facade.vi

    My x-control display then gets out of sync, i.e. if you read the data out (with a property node) immediately after writing it (by directly wiring the indicator), its wrong.

    Am I doing something wrong or is this a real bug?

    LV2011 No SP1

  8. Sometimes I've had success with the following on broken builds:

    In the advanced tab, enable debugging.

    In additional exclusions, uncheck removed polymorphic VI instances, uncheck remove unused members of project libraries.

    as already mentioned, include front panel/block diagram for suspect VIs.

    Also, if you launch any daemons, try including block diagrams/front panels for all of them. Sometimes the error for that problem doesn't show up quite right.

  9. One more thing, you are sending "N?\r\n" I'm gonna assume that this is using codes display. Your VISA Configure is adding a "\n" to all writes for you. It might be in your best interest to turn this off. The actual data on the line will be "<XON>N?\r\n\n<XOFF>" If you want additional control over the line (which I've done before to debug this exact situation) turn off flow control entirely, and manually put all the data on the line. If your xon char=0x11 and xoff=0x12, then your codes display to send for that message would be:

    /11N?/r/n/12

    In hex, the data would be:

    2F31 314E 3F2F 722F 6E2F 3132

    Hope this helps

    Arg, i put the slashes in the wrong direction

    Codes Display:

    \11N?\r\n\12

    Hex:

    114E 3F0D 0A12

    sorry about that

  10. Since you are using XON/XOFF flow control, perhaps the control character is not being set to the correct character. Check the documentation on your device for what the XON/XOFF characters are. You can change this setting by using a property node. It is in Serial settings -> XON flow control character, and Serial settings -> XOFF flow control character. Additionally you can manually set the flow control state to force it to something on your end, but since the read is failing, this probably wont help you.

  11. I don't use the NI build version, however,

    This is what I did on my last project:

    as a post build for the exe I create a file called <executablename>.exe.info

    this file is encrypted with the following contents:

    1. build date

    2. build version

    3. build author (I programatically retrieve the windows login info)

    4. 32 bit CRC of the file (my companies proprietary algorithm)

    5. Sha-1 hash

    6. String (for all the stuff I forgot)

    In the exe I decrypt the file (its just a hard coded password) and return those items. I find that the build date is far more useful than the build version, and it constantly gets out of sync anyway if you have multiple people making builds from a source repo. Additionally the exe is able to check that it has the correct version file as it can run a SHA-1 on itself since it was generated after the build.

    If the encrypted file doesn't exist, the executable simply returns (unreleased.) This is good while I test on production equipment so that operators don't accidently use something I left on a tester.

  12. I just put a constant down and wire it to the get default path primative. Its helpful to see where its being loaded from to make sure its using the ones compiled into the application.

    I've actually been messing around with this technique a little bit; I'm not sure its a great idea to be compiling 2 disk copies. It would be better to have a packed library with the child classes (although this introduces a whole new set of issues in maintenance and understand-ability) There really should only be one copy of the compiled code in the run time environment at a time.

  13. See this thread: http://lavag.org/topic/15369-packed-libraries-break-inheritance-relationships/

    Basically, my understanding is that the problem with loading a class at runtime in an exe is that the dependencies of the class (such as items in vi.lib, user.lib) are not available without the development environment. With the introduction of packed libraries, the class and all its dependencies are compiled into a binary avoiding this situation. The problem is, that packing all the dependencies not only packs the target plugin class, but also packs up the Parent. This means that your plugin architecture will be destroyed. The accompanying thread links to a ni thread which details a procedure from removing this behavior. (its really obtuse IMHO, that doesn't mean I wont do it, it just feels like a highly irregular and obfuscated way to code)

    Here is that link to the NI website:

    https://decibel.ni.c.../docs/DOC-19176

  14. I'm wondering if you can say at least a little bit more about this comment and the general idea that FGVs "...always end up..." as god instantiations, and I gather you mean some form of pantheism or polytheism.

    This is specific to AEs:

    the "typical" usage of an action engine is to use it as a SINGLETON and that the AE itself IS the API used (have fun scoping that without another abstraction layer.) Using it as a CBR node call destroys any ease of maintainability associated with AEs (typdefing the connector pane, re assigning etc.) the only alternative at this point is to make the input/output a variant to get around the octopus connector that results, performing to/from variant. I think if you are good enough to do that, you might as well just step up to classes and type-protect your inputs/outputs, and reap all the run time performance benefit of dispatching instead of case-to-variant steps.

    I think singletons are inherently not extensible and lead to "god functions." Using a by-ref pattern using SEQs or DVRs is a better way to go. If you really want to go completely nuts with software engineering and maintainability, use the actor framework or some other messaging system.

    FGs: I don't even consider them useful. Once again, they are a singleton; The only time I'd be happy with them is as a top level application object for immutable objects (config data?)

    Maybe this is because I'm always making something work with one unit, then down the road I end up testing 6 at a time, and all the FGs are completely useless.

×
×
  • Create New...

Important Information

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