Jump to content

LogMAN

Members
  • Posts

    656
  • Joined

  • Last visited

  • Days Won

    70

Posts posted by LogMAN

  1. You should be able to view the code of the toolkit. All VIs are basically wrapper around an ADODB Connection. The function you use to receive parameters does that on purpose (using ADODB functions!), but only if the database supports that (pros & cons are listed in that VI too). There is a whitepaper from NI that describes the DCT:

    http://www.ni.com/white-paper/3563/en/

     

    One statement says:

     

    The Database Connectivity Toolkit can connect to any database with an ADO-compliant OLE DB provider or ODBC driver.

     

    Now if there is a native way to receive a list of stored procedures using 'ADO-compilant OLE DB provider or ODBC driver', you could write an idea in the Idea Exchange.

  2. Do you use strict-typedefs for your properties?

    Did you try to replace the VIs by their properties after saving for previous version?

     

    Some month ago I ran into various problems related to property nodes. In LV2011 the IDE got very slow and almost unresponsive... No problem without properties... Anyways, I reached a point where the entire IDE would just crash at load time for class private data! So I upgraded that particular project to LV2013 where I realized an odd behavior (that has been there even in LV2011, but did not catch my eye until then):

     

    If you wire a strict typedef from a property-node to a VI with the same typedef, a coercion dot will occur once you change a font in that typedef, or anything that is only available for strict-typedef. In LV2013 you get an explaination for the connected data types in the context help. The source is presented as type of 'error in' or some other non-related type... Once you place the VI instead of the property node, everything is fine. According to NI that has something to do with the way LabVIEW updates the typedef. I did not get much details, but basically the property node remains with an 'old' or rather 'partial-new' version of the typedef, since a property has no FP, while the VI is updated with the entire 'new' typedef, thus leaving the IDE with "two" typedef revisions at the same time...

     

    See the picture and notice that there is a coercion dot and the Main-VI is not broken, even though the context help makes me :( ... :blink: ... :wacko: ...  :frusty: ! (this is LV2013)

    Also notice, that the same implementation without property-node has no coercion dot! Not to mention that the terminal data type according to the context help is of type 'error in', but correctly named 'Strict1' and the connected wire data type represents the correct type <there is no emote to display how I feel about this, maybe if LavaG had something... exploding... no?>

     

    post-17453-0-45665200-1391814256_thumb.p

     

    This is (according to NI and my experience so far) just a IDE issue and has no known effect to the build exe (code is not even broken). NI is informed of course, but there will not be an update to this until LV2014 or later. Anyways, I wonder if what you experience might be related (LV2010 could have even more issues with this than LV2011). From what you've written, it kind of fits.

  3. One follow on I'd like to ask is how you guys handle naming of methods when public/private have the same name. For instance, I may have a public method called "Read Device" which really just sticks a message in a queue, and then a private "read device" method that does the actual work. But if I name them the same they can't be in the same directory on disk. So now this gets into directory hierarchies on disk which may be a whole different animal. Thoughts?

     

    The easiest solution would be to rename the private method to "PrivateReadDevice.vi", as the private interface can still be changed anytime without side effects on implementations (like linking issues).

     

    However your example should be two seperate classes in my opinion:

    One for serialized access (i.e. the implementation of a driver) and a second class for access in terms of a messaging system to an async. state-machine/process which implements the driver.

    • Like 1
  4. One major thing is simply to have a convention and write it down...

     

    shoneill is right, having a convention is a very important thing. ( I used to change my 'convention' because of various, situational and sometimes stupid reasons, so code got messy or time run out :unsure: )

     

    There are some things to consider, this is what I could guess of (speaking in general, not specifically for libraries or classes):

     

    Prefixes -> Use libraries/classes instead (you'll get a namespace 'Library.lvlib::Member.vi'), how would that look with prefixes: 'prefix_Library.lvlib::prefix_Member.vi' ( :nono: )... You have to organize the files on disk to prevent name conflicts though. If there is a need to prefix everything, just change the library/class name (linking issues are conveniantly easy to solve this way in my experience).

    Spaces -> One of the most obvious things that make LabVIEW different to languages like C. Good for starters and easy to read. However if you build DLL files (or enable ActiveX afaik), spaces are a problem.

    CamelCase -> Sometimes hard to read and maintain, but in combination with libraries the most flexible one in my opinion. Makes it easier to reason with people from the other side.

     

    CamelCase in combination with libraries/classes is what I actually use, even though it is sometimes painfull to stick to ( ever batch-created accessor VIs to class members? I'm always having fun renaming all of them :wacko: ).

     

    As you're asking for libraries & classes specifically, I don't use prefixes (they tend to change on my end...) and I have trouble to write well-named VIs including spaces (would you write 'Write to Disk' or 'Write To Disk'? Therefore CamelCase is a good solution for me ( 'WriteToDisk' ). I also no longer create subfolders on disk to organize class files, but virtual folders in the project only (how I hated to move files because they are in a different category for some stupid reason...). Also libraries (*.lvlib) and class (*.lvclass) files are within their particular subfolder on disk. If I now move a library/class to a different section, I just have to drag the entire folder. This handles quite well in SVN too.

     

    Would be interesting to see how everybody else handles such things...

     

    EDIT: Error in database, but still posted? :angry:

    Sorry for this tripple-post.

  5. I have never implemented this function with a remote target, so I can only reason with the little information I have:

    Telling from the help, your solution should work fine. However, it says:

     

    vi path accepts a string containing the name of the VI...

     

    and furthermore

     

    Note If you specify a remote application instance with application reference, the path is interpreted on the remote machine in the context of the remote file system...

     

    It explicitly says path and not string or path, so I'm not sure if your problem is the expected behavior, or a bug (I could argument for either of them). Anyways, in my opinion the application instance perfectly identifies the target and there should be no problem with either a string or a path.

  6. The last time I had such an issue, it was related to the 'Seperate Compiled Code' option in combination with revision control: I reverted one of my components in SVN and for some reason it has not been recompiled automatically (broken-unbroken issue)... After hours of searching, an NI engineer suggested to clear the compiled object cache, which solved the problem entirely.

    Not sure if that's related.

  7. Ah, a terminology problem then; this code actually has nothing to do with the Actor Framework.  Rather, both take the "actor" terminology is from the Actor Model, which is used by a large number of frameworks for many languages.

     

    I may have got confused. So this is basically a different implementation of the actor model? The only one I've ever used up till now is the "Actor Framework" that is now also shipped with LabVIEW.

     

    :frusty:http://lavag.org/files/file/220-messenging/ Never mind. Memo to myself: Actor Framework != Only possible way & RTFM.

     

    I used the JKI because that's the QMH template I've used for years.  Perhaps I should adapt the QMH used by the NI example.  I don't really like it because it's a "send messages to myself" style which I think is potentially problematic.  

     

    It's fine, I too often consider more advanced implementations over the ones which are "recommended". It is just harder to learn multiple specialized modules over a single one for beginner (like me for this one). The NI version does everything, using standard tools that are shipped with LabVIEW (even though it is far away from being "easy to understand for beginner"). I favor your implementation of asynchronous calls for scalability. The NI version is good, but 3 or 4 parallel loops in a single VI are to much for me to stay calm ( always trying to find a "better" solution :) ).

     

    You could share references, but the idea behind the Actor Model is that such sharing becomes more and more problematic as a program scales up in complexity.  

     

    My "actors" are actually nothing but single asynchronous VI's sitting behind a message receiving mechanism.  

     

    I was trying to say the exact same thing, however my initial statement has become irrelevant for this matter. You are not bypassing actor messages with your message system, it's just a different implementation of the actor model. I was comparing apples with oranges and got confused about something that was missing... Thinking about it from the new point of view, your implementation might be less complex than the "Actor Framework" I was talking about earlier.

     

    Was that by Allen Smith?  I saw his talk at the European CLA summit.  If I may criticise the Actor Framework, that is just too complicated.  Even bending the "actor" rules for the "flexible UI" is too complicated.  

     

    The name sounds familiar and I think he is the one (big guy with full beard). It's too long ago for me to be sure though. I just remembered a warning about bypassing the actor messaging using any kind of secondary system, since that would eliminate the idea behind the actor framework model. But that was completely related to the "Actor Framework" and some crazy complex project (and yes, it was way to complicated).

     

    Now I'm getting excited to try the Messaging package... So many things I want to know, but no time at all :unsure:

  8. I tested it and it works fine. One dependency was missing, but this is easy to solve: http://lavag.org/files/file/235-cyclic-table-probes/

     

    Like neil, my time is limited right now and this is also not my specialty. I'll give my opinions anyways (notice, I had like 10min for this):

     

    I think your code is much easier to extend (while maintaining readability that is) than the NI version, but the complexity is on a much higher level (Actor Framework, JKI State Machine, Messaging Library). Anyways, there is one thing bothering me regarding the coupling of your actors. An actor is defined by its messages. You could bypass that by sharing references or reference-like objects that allow direct access to actor-specific data or functions, thus eliminating the need to use any actor message furthermore.

     

    If I understand your code correctly, the actor messaging system is bypassed by the the messaging library. Now would it make any difference if you call an asynchronous VI instead of the actors?

     

    There has been a webcast about a big project that has been solved using the actor framework, but I can't recall the name or find it... It involved a flexible UI where some actors are bypassed, as well as sharing actor objects with realtime targets and network sharing. The presenter did a very good job to reason about the downside of some stuff they did.

    Does somebody know which webcast I mean? (NI Week?)

     

    I hope my explaination is understandable. Maybe some actor framework guru could give his opinions. Feel free to correct me.

  9. I think could be called "the more popular implementation of ByRef LVOOP"   or TMPIOBL, it just rolls so easily off the tongue

     

    Yes, give me a tongue twister :lol:

    My guess would be: "Data Value Reference Paced Object Oriented Programming" short: DVRPOOP

     

    I am not sure what the name is for this type of implementation.

     

    Trying to get back on topic: It's just a ByRef implementation of OOP, so no popular or super fancy name to it. The standard implementation would be ByVal.

  10. I don't see any obvious reason why the data should be loss, however from these pictures it is hard to get many clues.

     

    Did you check if there is any awkward call to your "Destroy" VI, that could lead to your situation? -> Check any parallel thread.

    How does your "copy" function work? -> I assume you are building an entire new DVR.

    What is the scope of the queue you want to add the element? -> As far as I know, a DVR is valid until no VI makes use of it anymore. Check if the references are valid and at which time they become invalid.

    Last but not least: This is not standard LabVIEW OOP, as it would be impossible to wire a DVR directly to a class method. Are you using GOOP?

     

    Could you provide a code sample, so we would be able to confirm that behaviour?

  11. I too experience a memory leak of seemingly 4 - 16KB/s on a XP machine with LabVIEW 2013 RT. The leak will cause a very slow application after several hours (after approx. 5-6h), even though the memory is far away from full (still more than 2GB left). I remember something about queues allocating memory whenever you try to access them by name, about 4Bytes for each time or so?...

     

    Found it: http://digital.ni.com/public.nsf/allkb/1EBEA74610577B8A86257156006985CB

     

    Searching the internet further shows interesting topics (didn't try anything yet). AQ gave an interesting answer here: http://forums.ni.com/t5/LabVIEW/Obtain-Queue-memory-leak/m-p/1644744#M590534

     

    Question is: Do we rapidly obtain queues by name without releasing them?

    Also: As Semaphores are using queues internally they too are worth checking.

     

    I'm just throwing my thoughts in here, but maybe you are experiencing a similar or even the same issue.

  12. Interesting task, some VIs are missing though (from your user.lib), but I get the critical part now.

     

    As far as I know there is no way to pass a delegate from LabVIEW to a function (as there are no raw delegates in LabVIEW). Also, even though the parameter is called 'asyncCallback', it is not an event callback, but just a parameter you could pass (any?) delegate to. The delegate could be registered as an event by the caller. I searched the internet and found a similar topic:

    http://forums.ni.com/t5/LabVIEW/How-do-I-configure-NET-SOAPSender-AsyncCallback-in-LabVIEW/td-p/284364

     

    The first answer states:

     

    LabVIEW 8 introduced support for .NET events but we don't have support for raw delegates (the AsyncCallback parameter)...

     

    I think this is still true. The only option I see for this is to write your own wrapper that internally handles the delegate and provides an event for LabVIEW to register to. Of course you would also have to wrap the method you want to call in order to provide a method without the delegate parameter.

     

    I'm quite sure I've seen a similar topic here before... I guess...

    • Like 1
  13. I can't give a solution for your specific problem, but .net callbacks are easy to understand:

    - Place the Register Event Callback node from the .NET palette into your VI

    - Wire the .NET class reference to the Event input (the third connector from top-left! not the first!) -> Now you can select an event from the drop-down box where all available Events are listed

    - Once you've selected your event, rightclick the VI Ref terminal and select Create Callback VI

    - Do whatever you want in the callback VI (like trigger a LabVIEW event)

     

    Now whenever the event is fired, your callback VI is called... Try it with a message window ;)

     

    Hint: Wire some data to the User Parameter input of the Register Event Callback node and re-create the callback VI. This is how you could send a LabVIEW event refnum (or any type of data) into a callback VI.

     

    Hope that helps. Upload your VI if you need help for your specific solution.

     

    EDIT:

    Ehem, I hate to post links but:


    http://zone.ni.com/reference/en-XX/help/371361J-01/lvcomm/reg_event_callback/

    https://decibel.ni.com/content/docs/DOC-9161

     

    :shifty:

    • Like 1
  14. hi to all,

     

    thanks 4 the answers. iam sorry for choosing german as language. 

    in the future i will write in english.

     

    Thanks a lot for the further informations, i will try to get support from keyence!

     

    Best regards

     

    :lol:  I just figgured you must be able to read English in order to understand my original post in the first place!  LOL, and I go through the trouble translating everything... :lol:

     

    Hahaha thanks, you made my day :beer_mug:

  15. Hi log man, wo bekomme ich den labview support bei keyence für den mdv9900? Ich benutze das gerät auch und möchte aber vom marking Builder weg hin zu labview. Kannst du mir tips geben oder gar die vi`s? Danke Greets tmc

     

    Let me translate this properly:

     

    Hi LogMAN where can I get LabVIEW support for MDV9900 from Keyence? I use the device too, but want to swap from the Marking Builder to LabVIEW. Can you give me tips or even the VIs? Thanks greetings tmc

     

    GERMAN: (translation below)

    teeemzeh, auch wenn dies ein englisches Forum ist, antworte ich ausnahmnsweise auf deutsch: Nach meinen Informationen hat Keyence keine fertigen LabVIEW-Treiber, sondern verwendet allgemeinere Protokolle, meistens ASCII-Basierend. Der Support von Keyence ist immer der richtige Ansprechpartner, also einfach anrufen und nachfragen. Die Kontaktdaten sind hier zu finden: Keyence Support. Übrigens sind die Vertriebler häufig die besten Techniker und helfen auch bei der Inbetriebnahme und fast allen Fragen. Ich habe damals über den Support die entsprechenden Protokolldateien, sowie einen technischen Ansprechpartner erhalten und mit dem Vertriebstechniker die Inbetriebnahme durchgeführt. Der Marking Builder ist zudem zwansweise erforderlich, um den Laser zu parametrieren! Ansonsten verwendest du das DIO-Interface (Programmwahl, Sicherheitskreis, etc...) und sendest einfache Strings (Datenblock & Daten)... Wenn ich mich richtig erinnere hatte der Laser einen RS232-Port, der in LabVIEW sehr einfach anzusprechen ist. Leider habe ich keine VIs, weil meine Lösung nicht in LabVIEW umgesetzt wurde.

     

    Ich empfehle zukünftig für Anfragen auf deutsch lieber bei ni.com/community/d, oder labviewforum.de anzufragen.

     

     

    ENGLISH:

    teeemzeh, even though this is an English forum, I'll once answer in German: Keyence does not provide ready-to-use LabVIEW driver as far as my information go, instead they make use of more generic protocols, mainly ASCII based. Contacting the Keyence support is the best option you have, so just call them. Contact details can be found here: Keyence Support. The sales guys are most likely the best technicians you could ask for and they will guide you through commissioning and almost any question. Back then I received the protocol files from the support as well as contact to a technician and I did the commissioning together with the sales technician. By the way, the Marking Builder is required to parametrize the Laser! For anything else you use the DIO interface (program selection, safety circuit, etc... ) or send plain Strings (Data block & Data)... If I remember correctly, the Laser had a RS232 port which is very easy to use in LabVIEW. Unfortunately I don't have any VIs, since my solution was not implemented in LabVIEW.

     

    I suggest writing German question on ni.com/community/d, or labviewforum.de in the future.

  16. Reading all the posts, it seems that many people used multiple event structures on one block diagram at some point in their life. In fact I did so too, however this has either been because of bad design decisions (use Sub-VIs instead!) or because I didn't know better (wait what? :angry:). It would be no problem for me to limit the number of event structures to one, or rather I would like to see one event registered only once in the same VI (maybe thats already limited in a more recent version than LV2011?). There have been very strange behavior in my VIs ages ago (4-5 years) as I tried to catch the same event on a prallel event structure :frusty: (never got it working properly)

     

    In my optionion parallel event structures are like global variables, you could use them and it might seem easier, but the maintainability gets worse and worse the more you use them and you must be very strict to the limitations of their usage. So don't use them at all!

     

    The only reason I could accept so far is the one of Darin (because they are strictly seperated by their scope):

     

    There are many situations where I like to have unrelated events handled by separate event structures.  Sometimes it is user events and app generated events.  Often it starts out with mulitple event loops and eventually it morphs into multiple subVIs.

     

    However even this should have and has been solved in sub-VIs.

  17. I can only guess based on the help, since I generally use pure SQL syntax... The update statement will try to update all columns in your table which is impossible as you need a primary key (a column that is the unique identifier). This would be 'speedo_ok' in your example I guess. You could now either update element-by-element using the condition input WHILE speedo_ok={speedometer values.select} where you have to replace {speedometer values.select} with the actual value of the particular element. The second option is to present a new primary key to your table that is set to auto-increment; and always define the column names for your cluster whenever you use the cluster to insert / update / etc...

     

    The update statement with all cluster elements makes no sense as far as I understand, as this would cause all rows to carry the exact same information for each column. As I mentioned before, you need a primary key that is unique. Try to update a certain element of your cluster using the condition I mentioned before.

     

    Maybe someone else could give an actual example how to solve this based on the DB VIs?

     

    Sorry I really didn`t get the theme of the description described in help menu.

     

    No problem, I had to learn all that stuff too :rolleyes:

    A good source for SQL has always been http://www.w3schools.com/sql/ or MSDN of course for MSSQL.

     

     

    Just for my own satisfaction :wub: , but this would be the SQL syntax (I did not test it, but it should work): You have to replace all elements in {} by their representatives in the cluster. Green would be valid, red is what you try to do (I still assume speedo_ok is your primary key):

     

    UPDATE speedometer SET speed={max speed}, frequency={speedo max freq}, amplitude={speedo amplitude}, pulse_rev_n={speedo pulse/rev}, ratio={speedo ratio}, pulse_type={pulse type} WHERE speedo_ok={select};

    UPDATE speedometer SET speedo_ok={select}, speed={max speed}, frequency={speedo max freq}, amplitude={speedo amplitude}, pulse_rev_n={speedo pulse/rev}, ratio={speedo ratio}, pulse_type={pulse type};

     

    I hope that helps.

    • Like 1
  18. The condition terminal is well described in the help:

     

    condition specifies an SQL clause that this VI uses to filter the selection criteria. This VI appends this clause to the end of an update statement. For example, where (col1 > 10). If you do not specify a value for this input or if the input is an empty string, this VI updates all rows in table.

     

    EDIT: Should describe anyways:

    Let's say your table consists of a pair of ID + name ( 0 | bill, 1 | john, 2 | pa_l, etc..) now you want to update the name of the row in which the ID is 2 ('pa_l' should be 'paul'), your condition would be 'WHERE ID = 2'.

     

    Your current data is of variant type. What data are you trying to send: cluster, string, numeric, ...? -> I guess you get the error because the data terminal is not correctly wired.

     

    The table input specifies the table name and if your table has for example three columns (id, owner, description) and you only want to update the description, you should set the first element of the columns terminal to 'description'. (And only provide the new value of description to the data terminal!)

     

    Could you provide some more information about your actual data type & table layout?

  19. As mentioned in the NI forum, the Database Connectivity Toolkit is essentially a wrapper around an ADO ActiveX object. ADO uses an ODBC connection internally and there are syntax differences when using ODBC compared to using MS SQLServer directly: @variable declarations are not supported via ODBC.

     

    This is very interesting. Do you know any particular page we could look up for that kind of stuff (like a comparison between MS-SQL vs. ODBC vs. ...)? My main source is MSDN as well as various pages I could find over Google.

  20. Update: My computer finally decided to take a rest, so I decided to restart LabVIEW and try that a third time. The environment does run just fine without any disturbing disk activity. Am I seeing stuff ? :wacko:?  -> Restart again, as third fourth time's the charm, now waiting for 30min... New VI as before, constructor and... nothing! :throwpc:

     

    So obviously the MsMpEng.exe did not relate to the issue at hand and was randomly scanning my computer twice just as I placed the constructor. Thanks Bill!

  21. A small update to this. Our project contains 2000+ VI's. With trial and error I have tracked down that it is one specific VI that has been causing our delay in the project. The VI in question uses Hash functionality as shown here:

    http://lavag.org/index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=2583

     

    Deleting this code from the VI fixes all problems in my project. I have passed this information to NI. Interestingly, commenting out the code is not enough, it really does have to be deleted.

     

    Let me share my experience based on your example:

     

    As soon as I load the constructor, my system shows heavy disk operations. So I close LV (eventually killed the process)... Restart the system in order to try again... Wait for 15min, until no process does anything anymore, take a look into the resources monitor -> everything is fine. Now again starting LV -> create new VI -> insert the constructor, wait approx. 5s... System overflowing with disk activity (100%).

     

    The load is caused by MsMpEng.exe which is part of Microsoft Security Essentials. For some reason it will start scanning the entire computer!? (The highest load is given to the MFT). Of course LabVIEW is now very slow as many other programs that rely on disk activity.

     

    All caused just by putting the SHA256Managed constructor in a blank VI!

    Tested in LabVIEW 2013 (32bit) on Windows 7 (64bit)

     

    Maybe somebody else can confirm this behavior?

    Hint: The constructor is located at: mscorlib->System.Security.Cryptography->SHA256Managed

×
×
  • Create New...

Important Information

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