From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
11-23-2017 08:15 PM
@Blokk wrote:
If we keep OOP method VIs non-reentrant, there is always a danger that parallel executed same VIs, like a read method for two or more IDENTICAL hardware interfaces will block each other partially time by time, no?
Correct. But your methods should be fast enough it does not matter much.
Blokk wrote:
Ihave no idea how it works in case of inheritance, like if there are two SIMILAR hardware interfaces, and we use two differently inherited classes. I guess in this case the two inherited slightly different Read methods cannot block each other even if they are non-reentrant?
Methods from different classes will not block each other.
As I said before, the Shared Clone Reentrant is probably the way to go.
11-23-2017 09:02 PM
Hmm, actually it makes sense. Even if the two read method VIs would block each other, it does not make a big difference. Like there is RS232 communication with two identical units: if the two read actions will not happen strictly parallel, but in serial, who cares. Instead of 10 msec, it will take twice, which will not make any impact on a 1000 msec loop ...
But, as i imagine, if i need to communicate with tens of units with the same read method, each action taking for example ~100 msec, then i must go for shared clones...
11-27-2017 11:25 AM
Beware! My first class ever 🙂
Because the MKS PR4000 official driver is really *bleeep*, I thought I replace my existing lvlib using a wrapped up action engine with a class approach. So here I only use the class to wrap two data values: the VISA resource name, and the node number (-1 for RS232 and non-negative value for RS485).
Any comment is welcome, I did not finish the driver, I will need to add some more methods (like set flow rate, read actual setpoint, zero MFC, etc.). Besides, this is just a playground to play with Classes, of course a real driver to share with the community should have some more things and a bit different settings (like Tree VI, etc...).
There were lots of options when I needed to create the private and public VIs. I selected the "VI for data member access" options for the Read/Write private methods. For the public ones, I used the "VI from static dispatch template". However I have no idea if this is the "orthodox" way to setup such class 🙂
I attached a zip (LV2017), and some screenshots here:
11-27-2017 11:43 AM
Since your data member access functions are set to private, there is no need for them at all. Just use the Bundle By Name and Unbundle By Name in your methods.
As another trick, you can set the access scope by the project folder. Right-click on the Private folder and choose to make the scope private. Any VI you put in there will then be set to private access.
And those waits are not actually needed. The VISA Read will determine how long you actually need to wait.
11-27-2017 12:41 PM
@crossrulz wrote:
Since your data member access functions are set to private, there is no need for them at all. Just use the Bundle By Name and Unbundle By Name in your methods.
As another trick, you can set the access scope by the project folder. Right-click on the Private folder and choose to make the scope private. Any VI you put in there will then be set to private access.
And those waits are not actually needed. The VISA Read will determine how long you actually need to wait.
Thanks! For some strange reason I kind of "extrapolated" the schema what I used in the wrapped up action engine approach. Of course, I forgot that a class is like a cluster, but even better: only the member VIs can act on the wire, no one outside. So I just delete those private VIs, and use bundle/unbundle in the methods 🙂 Simple and easy!
ps: yes, those wait functions were in the official driver because the programmer there used the (in this case wrong, because we have the <CR> termination characters for request/response actions!) "Bytes at port" method. I delete the Waits too.
11-27-2017 12:54 PM
Question: if I need to access two identical PR4000 units, now I can easily do it, since the two class wires hold the two different VISA resource and Node data. However, i can imagine certain cases when I might mix up which Class wire goes where in the code. Is there a technique in OOP to change the name and graphical wire appearance? So using the same Class, but visualize in the block diagram that actually I "spawned" two separate class wires using the "Initialize.vi"...?
Thanks! 🙂
11-27-2017 01:15 PM
@Blokk wrote:
However, i can imagine certain cases when I might mix up which Class wire goes where in the code. Is there a technique in OOP to change the name and graphical wire appearance? So using the same Class, but visualize in the block diagram that actually I "spawned" two separate class wires using the "Initialize.vi"...?
The wire is still determined by the type. In the case of OOP, the wire appearance is determined by the class, not the object (instance of the class). Depending on how your code is architected, you could use a cluster to hold the two objects and then use Bundle By Name and Unbundle By Name. I have also used an AE to hold the classes and then use a string lookup go get a DVR of the class (Variant Attributes makes this simple). Otherwise, wire labels.
11-27-2017 01:20 PM
Thanks for the good hints! Or, if I just wanna keep the things in one place and easily expandable to N+1, I could just use arrays (but of course I need to be careful to keep track of the array element orders!):
11-27-2017 02:08 PM
When looking for a good place to start... look the same place you would for Re-use. Use the VI hierarchy screen to figure out what is at the bottom of the screen, with no or limited dependencies. Collect the related VIs and put them in a library if not already in one.
Re: Cluster
If I have read Stephen correctly no clusters jus the calss data is what you are after. If you are tempted to put a cluster in your class, data OR on the icon connector of a member of the class, stop and create a class to use as you would use the cluster.
Then bite the bullet, and use accessors to get/set all of the private data in the class.
It may seem like a pain at first (because it is) but in the long run, using accessors will let you go for the gusto with Over-Ride functions.
Another ear mark for a "LVOOP" candidate is like the description for jazz that I once heard...
"Variations on a theme"
If things are mostly the same but have some differences... think LVOOP.
Just my two cents,
Ben
11-27-2017 02:55 PM
@Ben wrote:
Re: Cluster
If I have read Stephen correctly no clusters jus the calss data is what you are after. If you are tempted to put a cluster in your class, data OR on the icon connector of a member of the class, stop and create a class to use as you would use the cluster.
Then bite the bullet, and use accessors to get/set all of the private data in the class.
Ben, I am not sure if I understood correct. Do you mean, I could create a second Class, which would hold the data? If so, how should I set up the relationship between the two classes? I am not sure if i follow you...