Jump to content

Recommended Posts

I have some old VIs to which I need to give some love. All the error clusters were unwired, so I am working on that... 

I am wondering what would be the best practice when it comes to DVR. The IPE structure gives an error cluster on both the left and the right data node. The attached picture shows all the error handling I can think of, but I wonder if it's not an overkill. Here is the breakdown:

1) Outer case structure: If there is an error before going inside the IPE, it just skips the IPE altogether and propagate the error cluster.

2) IPE left data node: I don't need to merge it with any incoming cluster since we are in the "no error" case (what about warning? am I speaking too quickly?).

3) Inner case structure: as long as the code inside it knows how to deal with the error (likely skipping its own code and propagating the error), I probably don't need this structure. What do you think?

4) IPE right data node: in what scenario would it actually give en error? If the DVR is bad, the left data node will take care of generating the error... Is it there is case the DVR becomes bad during the IPE execution? If I wire the right data node, then I need to merge it with the error cluster coming from the code inside the IPE...

Any comment more than welcome!

Capture.PNG

Link to post
Share on other sites

The secret is that the incoming error is always the same as the outgoing error. Grab it where it's more convenient but you don't need both. If you need the warning, and I never do, you can merge it at the top on your rightmost merge.

Reference: https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Can-we-have-an-error-in-terminal-on-the-in-place-element/idi-p/2008551

Edited by infinitenothing
Link to post
Share on other sites

I typically take the left node error, merge with error in, then inside the IPE structure I'll either wire that merged result into the VI or into a case structure as you have it. I ignore the output error.

I also don't put so many error structures as you have (for the same reasons as #1 here: https://decibel.ni.com/content/docs/DOC-47123). Obviously this is case by case, which is harder to manage if you're going through an entire project retroactively.

What does the mark as modifier do for DVRs?

Link to post
Share on other sites

http://zone.ni.com/reference/en-XX/help/371361H-01/glang/in_place_element_structure/

If I remember what aristos told me about the lvoop comment, the mark as modifier would really only do anything for dynamic dispatch. He said something about how if the parent class just passes the data through without modification but you know most children will modify the data, this cues the compiler to know hey, you're going to need a copy of this data you can't pretend this section of code is read-only. With a DVR, you always lock the value and I would assume operate in place, so I can't imagine why this would do anything for DVRs.

Edit: lol

Also on the original DVR subject, aristos' comments here may also help: 
https://decibel.ni.com/content/docs/DOC-40468

Edited by smithd
  • Like 1
Link to post
Share on other sites

No, the other way around. Let's say you have some data that passes through a dynamic dispatch VI (that is, there is an input and a corresponding output of the same type). The parent method passes the data through unchanged, so LabVIEW expects that it can reuse the input buffer for the output buffer. Now you override that method in a child, and you do modify the data. At compile time, LabVIEW uses the parent class (it can't know about all the possible child overrides) to determine whether it can expect to reuse the buffer. At runtime, when the child class runs, LabVIEW discovers that it needs to create a copy (to accommodate the modified data) and so it needs to allocate an additional buffer.

Now, if instead you put an in-place element structure in the parent, and marked the terminal as a modifier, at compile time LabVIEW will pre-allocate a buffer for the output, even though it's not necessary in the parent, which will allow the child that modifies the data to execute a tiny bit faster.

I'm not sure why this would ever be a useful option for a DVR.

  • Like 1
Link to post
Share on other sites

Oh so it has nothing to do with the DVR node of the IPE? So you're talking about putting an IPE with the simple In Place In/Out node?

Capture.PNG

Edited by Manudelavega
Added screenshot
Link to post
Share on other sites

Yeah thats right, that option is available on all ipe nodes but it sounds like its only a good idea to use it in exactly one situation, so the usage you showed above is probably not a good idea.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By Axelwlt
      Hi
      I am reading big TDMS files (~1GB) and I try to minimize memory usage.
      I read a signal once and I want to keep it for later usage, so I tried to write it to a DVR in the hope that I have only one instance of the data in memory.

      However the task manager tells me that uses 2 times more memory than it should.
      I think the problem is that the array is not deallocated although I don't need it after writing it to the DVR.
      Is there a solution to make sure I don't have copies of data?
    • By Ram Prakash
      Can anyone please tell what a DVR [ Data value reference ] is ? I want to know at what situation it will be used and what are the advantages we get by using DVR. I am really confused in this topic . If someone has any code in which they have worked with DVRs. kindly share it to me.
       
      Thank you.
    • By Zyl
      Hi everybody,
       
      I'm running into something I don't really understand. Maybe you can help me here !
      I've got a LVLIB that is used as an 'Interface': it exposes public VIs which wrap around public functions of a private class (see code attached) . The class is private because I want to force the users to use the 'interface' functions.
      In one of my interface VI, I create a DVR on the private class (Interface_init). The DVR is stored into a typedef (FClass_DVR.ctl) and this typedef is the 'reference' that link all the interface public functions.
      In TestCode.vi (which is not part of the lvlib and illustrates the standard code that a user can create to use my driver), I can call my public interface functions and link them without any problem.

      But as soon as I create an indicator on that reference (to create a state-machine-context-cluster for example), my TestCode VI breaks !

      The error returned is : This VI cannot use the LabVIEW class control because of library access scope. The LabVIEW class is a private library item and can only be accessed from inside the same library or libraries contained in that library.
      I understand that the class is private. But the DVR is contained into a public control. Using an In Place structure on that DVR into TestCode would not work, since the class is private. So why is the DVR control problematic at that point ? Creating it do not breaks any access protection...
      Am I missing something ?
      DVR Private POC.zip
    • By IpsoFacto
      I've got some weird stuff going on with a cRIO project I'm working on wanted to get some opinions on it. The basic architecture is a set of classes that do some process. That process registers with a server. The internal data of the process is held in a DVR and the server get's access to that DVR. Clients use TCP to ask the server to do something, the server makes a call against the classes DVR and returns a response to the client.
      To simplify the issues I'm seeing I created a class that internally just increments an integer every 500ms. The client asks the server what's the current count, the server asks the Counter class and returns the answer to the client. This works perfectly fine when running the VI in the IDE. When built it connects, will get the JSON message back, but always gets a default value from the DVR call (zero, in this case). As soon as I open a remote debug panel to the cRIO, everything is working. The count is correct, the client calls work, just like normal. As soon as I right-click, close debug, it goes back to zero. Open debug works, close debug, back to zero. I know the DVR isn't getting dropped because the count continues to increment while not in debug, the process is still running happily with no issues.
      Here's a few screenshots of the code;
      Count Class process (get the count, increment, write it back to the DVR) - Counter Class process
      You can see the DVR vi's are actually vim's using a cast. I can't imagine that's the issue.
      Server Side call - Server Side calls
      All this does is get the count from the DVR (same as above) and wraps it in JSON and passes it back to the client as a JSON string.
      I also implemented an Echo class that ignores the process and DVR's, it just takes whatever string you sent form the client to the server and passes it back with a prepended "@echo". This works when running as an executable with the debug turned off so I know the client, server, and the server/class calls are all working as expected.
      Any thoughts here would be welcome, thanks.
      edit: I added the any possible errors coming from the variant cast to the JSON reply. When the debug is open there are no errors, when the debugger is closed it throws error 91, but the in-place element structure reading the DVR does not throw any errors. How can a variant not exist until a debugger is opened and than it magically exists?
      edit: the internal data dictionary is a wrapper around a variant attribute, I wired out the "found?" terminal all the way out to the JSON reply and if the debugger is open the attribute is found, but not if the debugger is closed. Anyone have issues with Variant Attributes in Real-Time?
    • By the_mitten
      The introduction of parallel, read-only access for DVRs in LabVIEW 2017 adds a great deal of flexibility to using DVRs to monitor values in parallel executions of code. Fo\The downside of this, of course, is the necessity of using the In Place Element (IPE) throughout your code simply to read the value. Having IPEs throughout your code just to read a value both takes up block diagram real estate and also takes more clicks than desirable to insert.
      Similarly, though less frequently, there are times when you only need to update the value within a DVR without actually performing any logic inside of the IPE.  This situation is less frequent, at least for me, as I am usually using arrays or classes with DVRs such that I actually need to modify the existing data rather than simply replacing it.
      A more preferable solution to the above situations would be to have Read/Get and Write/Set VIs for the DVRs to simplify the process of working with them. This way, and IPE on the block diagram would only be needed when you were actually modifying the existing data within the DVR, rather than simply overwriting or returning the current value.
      Thanks to the power of malleable VIs and the type specialization structure that is now officially released in LabVIEW 2018, a better solution is now available. I’ve created two malleable VIs, Read  DVR Value (Parallel) and Write DVR Value that allow you to perform a write and a parallel read on any DVR data type.
       Now, you can use a single VI that you can insert via Quick Drop to read or to write DVR values.  
      Download the attached ZIP file to access the two malleable VIs and example code, and please let me know your thoughts in the comments!
       


      DVR Read and Write VIs 1.0.0.zip
×
×
  • Create New...

Important Information

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