12-17-2023 11:50 AM
Hello everyone,
I have created a class "MonirtorVoltage" which starts a DAQmx measurement and monitor that the static voltage is within expected limits.
Then I have created a "wrapper" class "MonitorVoltageRef" which handles "MonitorVoltage" within a DVR.
You can find my code attached. You can open the library and the class can be tested with "TestWithEventRef.vi"
My "Start Measurement.vi" is a blocking VI as it doesn't end as long as the voltage measured is inside the limits:
Basically, while "Start Measurement.vi" is running, I want in parallel to read "average voltage" (via "Read averageValue.vi") which is a value updated continuously by "Start Measurement.vi":
My issue is that the IPE for this "Read averageValue.VI" is blocked by the on going "Start Measurement.vi", but I wouldn't mind that both run in parallel.
I would even like to write sometimes in parallel on this DVR, because "Start Measurement.vi" could be running, and I could write to some other data member of my class DVR, which would not impact the "Start Measurement.vi".
Is it possible to somehow read/write to the DVR without the protection of this IPE structure?
My end goal would be to run "Start Measurement.vi" from TestStand, and once in a while to use "Read averageValue.vi" to check the value of the last voltage measurement or use "Check Error.vi" to see if any error (= voltage outside the limits) has happened. And, if I can write in parallel, I also want to use "End Measurement.vi" to interrupt the "Start Measurement.vi" from TestStand.
Best regards,
Ludovic
Solved! Go to Solution.
12-18-2023 01:08 AM
Hi Lchar,
@Lchar wrote:
My issue is that the IPE for this "Read averageValue.VI" is blocked by the on going "Start Measurement.vi", but I wouldn't mind that both run in parallel.
I would even like to write sometimes in parallel on this DVR, because "Start Measurement.vi" could be running, and I could write to some other data member of my class DVR, which would not impact the "Start Measurement.vi".
Is it possible to somehow read/write to the DVR without the protection of this IPE structure?
The DVR blocks parallel access to its memory by design, so you cannot access the data in parallel!
You cannot read/write the DVR memory without using the IPE structure (or without deleting the DVR reference)…
12-18-2023 03:51 AM
Use a single element queue, do lossy enqueues to write and peeks to read...
There's your by wire by reference global...
Of course a global will work too, as long as you write only one thing in only one place.
12-18-2023 03:59 AM
Thank you for your advises, actually I have found another solution.
Instead of using a "reference wrapper" around my class, I define all my private data of my original class as DVR.
So that I am not locking the whole DVR with start measurement. I only individually lock the private data when I update them.
In order for this solution to work, it is very important to create all DVR before forking the class wire, so that all copy of the class will point to the same DVRs.
I mean this kind of class constructor:
12-18-2023 08:02 AM
Hi Lchar,
Blocking functions (like your "Start Measurement") should not be put inside an IPE structure that accesses data from the DVR.
I would advise you to only access the DVR data punctually when reading or writing class private data:
Start Measurement:
Write Value:
Read Value:
If you are interested in a design pattern that goes further (inheritance, composition with the class itself, asynchronous processes…) I would advise you to give "GOOP" a try. It is a package available on VIPM that allows you to easily create by-reference classes.
Regards,
Raphaël.
12-18-2023 09:12 AM - edited 12-18-2023 09:27 AM
12-19-2023 04:32 AM
@Lchar wrote:
Thank you for your advises, actually I have found another solution.
Instead of using a "reference wrapper" around my class, I define all my private data of my original class as DVR.
So that I am not locking the whole DVR with start measurement. I only individually lock the private data when I update them.
In order for this solution to work, it is very important to create all DVR before forking the class wire, so that all copy of the class will point to the same DVRs.
I mean this kind of class constructor:
I hope you are aware of the downsides of DVRs, or anything (incl. queues) by reference:
+ no debugging data in probes,
+ the reference is gone once the main stops (so no debugging subVIs)
+ managing the type of the reference can be painful.
+ anything by reference has risks of race conditions (IPES only prevent this when used in a specific way).
I go through great lengths to make everything by wire and by value if at all possible (it usually is). Exceptions are external entities (file references for instance are by reference by nature).
Working by reference solve data distribution but cause concurrent data access problems.
Working by value avoids concurrent data access problems but you have to solve data distribution in another way (on another level).
Just be warned...