Our online shopping is experiencing intermittent service disruptions.

Support teams are actively working on the resolution.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Data value reference (DVR): how to write and read without using IPE?

Solved!
Go to solution

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:

Lchar_0-1702833377075.png

 

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":

Lchar_1-1702833875402.png

 

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

0 Kudos
Message 1 of 7
(3,555 Views)

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)…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 7
(3,506 Views)

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.

0 Kudos
Message 3 of 7
(3,489 Views)
Solution
Accepted by topic author Lchar

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:

 

Lchar_0-1702893506793.png

 

 

 

0 Kudos
Message 4 of 7
(3,485 Views)

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:

raphschru_0-1702906855271.png

 

Write Value:

raphschru_1-1702906875105.png

 

Read Value:

raphschru_3-1702907482214.png

 

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.

Message 5 of 7
(3,446 Views)

Forgot to attach the code.

 

EDIT: About the solution you found, creating a DVR per element does not solve the blocking issue in itself, and it will quickly become a nightmare to manage them all.

0 Kudos
Message 6 of 7
(3,435 Views)

@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...

Message 7 of 7
(3,347 Views)