Jump to content

Kurt Friday

Members
  • Posts

    253
  • Joined

  • Last visited

  • Days Won

    12

Posts posted by Kurt Friday

  1. However, one thing that makes me uneasy about putting the DVR inside the object (as your example does) is that each level of the inheritance hierarchy has it's own DVR and is locked/unlocked separately. I worry that this could cause some nasty race conditions or deadlock -- have you thought about this? And, an attempt to remedy this issue takes us back to where we have a lot of framework/support VIs for each class.

    Cheers,

    Hey Jim

    That's a good point that I haven't explored deeply. My first thought is that class Bike has its own DVR to it's datamembers and the child Racer has its own so they are separate and shouldn't interfere with each other. I'll do some tests and see what is involved in breaking it or causing it to lock.

  2. I have set the .ini file of the launcher sothat it runs multiple instances (AllowMultipleInstances=True)...thatway people can open multiple files in one go.

    Nice!!

    ActiveX could be an option...as DDE really is a very old technology and might get phased out soon.

    I don't think you can communicate between LabVIEW exe's with ActiveX as this would involve writing your own ActiveX server.

  3. Dear All,

    360 Samples that to per channel or 360 Samples per 8 channels?

    Hi Bujjin

    Just looking through the cFP-AI-100 manual on page 10 it mentions

    Update rate (all channels) ................. 360 Hz (2.8 ms)

    So it looks like you can read all 8 channels at 360Hz

    The best place to go with this type of query is to call your local NI rep, they would be more than happy to help you, they know their hardware inside and out and would be able to help you with your system design.

  4. Thanks for your response.

    As you say, perhaps I could register a separate application (App2) to my custom file extension with command line arguments enabled.

    When a custom file is double-clicked App2 would need to either:

    1. If App1 is not running - Open App1 and pass the filename with custom extension; or

    2. If App1 is already running - Send the filename. An event would need to be triggered in App1.

    I like the sounds of TCP/IP as opposed to DDE. How would this work? How would an event be triggered in the event structure upon receiving TCP/IP data (i.e. filename)?

    Nice thinking.

    Cheers,

    Battler.

    Take a look at some of the TCP client/server examples, that should point you in the right direction. In your main which will also a TCP server have a loop that listens for a connection. When a connection is found and message received poke it into a user event which is registered to your event structure.

  5. I had a poke around and found some info on implementing DDE into your LabVIEW application. I had a little play with it and you can create a simple DDE server and a client to pass data to each other.

    I dont know if this is the best way to tackle the problem but one solution might be to create one executable that is a DDE client that is registered to your file extension, as per your article. The client messages the file path to the DDE server which is your main application. If the client can't connect to the DDE server then it assumes that the server is not open so it opens it using the command line, once open it can message into it.

    You could also achieve the same using TCP.

    Again there may be a better way of doing this.

  6. I looked at your example. My understanding of Object References is different. See Images.

    post-2-12506341062_thumb.png

    post-2-125063425577_thumb.png

    One issue to resolve with this method is dynamic dispatching. It seems that you can't do dynamic dispatching using Data Value reference terminals. Hopefully this will be added in a future LabVIEW release. In the meantime you will probably have to do dynamic dispatching inside the In Place Element Structure.

    Yeah, I saw something similar when I was looking around at how to implement by ref objects using the DVR, I took a look at the xCE code from NI that Jon pointed to and saw that the way that by ref objects are achieved is by getting a ref to the object, but to achieve dynamic dispatch you have to wrap your methods in an in place structure and use DVR R/W on the object reference. It works, but it’s a lot of work to implement and what I don’t like is that you are requiring your layer above your object to manage that objects by reference capability, which as developers we intuitively don’t expect to have to do. I like my objects to manage their own by ref capability.

    So I thought that if the class just holds the DVR of the datamembers then I get dynamic dispatch without any fuss and I have a reference to my datamembers giving in effect a object that has by ref characteristics.

    I agree that the class should wrap a DVR to a cluster, but rather the DVR should wrap the class.

    However, I'm not sure that I agree that we need dynamic dispatching of reference terminals. I think that I would prefer to be able to pass an object reference into a by value method and have LabVIEW automagically dereference and re-reference the object behind the scenes -- almost list wrapping the by value method in a IPE Structure on the block diagram of the caller that is using an object reference.

    Yes, I like this idea.

  7. Your request/issue for Read Only is inline with Jim's above. Maybe an idea for the exchange forum?

    Yes, I like Jim's idea, especially the unbundle concept so that you only make a copy of the element.

    Also, it would be nice if you could wire a DVR LVOOP object into a Bundle by Name and Unbundle by Name and have LabVIEW automagically dereference/rereference the data behind the scenes. Right now, when you want to just get a value of an element of a DVR LVOOP object, you have to use an Unbundle by Name inside an In Place Element Structure. This is too much work for the programmer and makes the code look unnecessarily sloppy. The programmer's tendency will be to create a non-locking Get/Preview data method, but this isn't a great idea, because it makes a complete copy of the data -- by using an IPE Structure with an Unbundle by Name inside, you only copy the element.

    I'm pretty sure that one of the main design goals for DVRs was to eliminate data copies caused by the feature. Forcing the user to have a read-write pair guarantees that at least (although the user can still cause copies inside the IPE structure). If we had the ability to read the value, a copy would have to be made. It might also require some additional mutexes, because presumably you don't want to read the value in the middle of the IPE structure changing it, but you also don't want to wait until it releases the lock.

    P.S. That's not to say I object. At times I might accept read-only access (which would ideally not be affected by the lock) at the cost of an allocation. I don't know for sure that I would, though.

    You are right, it would make a complete copy of the data, which isn't a great idea especially if you are just going to pick out one element from a cluster, but if Jim's idea were implemented it would make coding a bit simpler, and more efficient.

    Perhaps all bundle and unbundle on an uninterrupted DVR wire are equivalent to R/W In Place.

  8. Please do!

    Hey Kurt

    I missed your posts on this thread so I have just downloaded your code. The code you posted is quite cool. And very similar to a current project I am working on - I have/had to model a furnace for a client and decided to go with an Active Object - the client runs from source (don't get me started) in LV8.2 so I couldn't use any licensed toolkits when hacking his system. But I basically used your Active Object from Endevo as the template with a LVOOP-SEQ framework and it is working really well. It seems that the DVR would slightly simplify this process.

    I implemented the process.vi using the JKI State Machine which worked really well, so instead of having a finite State Machine, I had a queued State Machine that could except arguments using a syntax that I am familiar with. I used dynamic registration for the messages coming back. It worked nicely - so good job on the Endevo AO stuff. :beer_mug:

    I actually have to give a user group presentation on this DVRs and stuff, so I have been playing with them all day today. They seem robust, I guess I have to keep using them to figure out how to do this stuff the best. But if anyone else can keep posting up what cool stuff they are doing with them that would be awesome.

    Hi Jon

    Cool, I'm glad you like it. Its basically the same philosophy that I put into the Endevo design pattern, DVR really does simplify the object management that had to be done with SEQ, but in the end as I understand it DVR is a SEQ at its core.

    As I'm playing with it there is one thing I would really like, as with a queue you can preview the element, I'd like to see the same with DVR. At the moment all your methods have to employ a DVR Read/Write within an inplace structure. If I want a method that is just read only it will be locked until the current operating method completes, this is going to bog down a system that uses read only methods.

    One thing I did pick up -and correct me if I am wrong - it seems that the reference goes out ofmemory along with the owning VI. I had a launcher.vi that created theLVOOP-DVR refnum and then passed this to the launched VIs. By thereference seemed to die when the launcher stopped running. I don't havethis issue with SEQs.

    LabVIEW performs cleanup on any references that were created within a VI that is no longer executing. So you need a way to keep your Launcher in memory until all your spawned vi's are closed. Possibly What I would do is feed each Spawned VI a queue ref that they can use to message back to the launcher when they are closed. When all spawned vi's have been closed then you can close the launcher. Perhaps a rendezvous may also work.

    The Endevo SEQ avoids cleanup when the caller is no longer executing is because I think you must be running in debug mode. In debug mode the object references are kept alive by a background process, as I understand it.

  9. Hi again Kurt,

    I've been away from the project for little while, and now i'm back. And i need some help again, if you can of course.

    I've tested the last attach you posted here, and it seems to work very good, except the fact that the ramp looked more like a step. I think the temp. controller isn't assuming its rate and its skiping from setpoints as quick as it can. Other question i have is about how to do the step mode on this controller? Is it by a similar process to this 1 that you've done?

    For last, i'm having trouble configuring the VI Package Manager, since it is not communicating with the labview, it opens the labview but it always says time exceded. I have formated the laptop, and i'm doing it like i did the 1st time and it worked.

    Thanks in advance for your help.

    Hi Mate

    I've never played with this temp controller so I'm just working on assumptions and wrapped the driver in a script engine that will perform the series of operations that you need.

    Sounds like its not implementing ramp so each setpoint change drives it as fast as it can to that temp. I'll have a forage around and see what I find. Also check that when it hits temp_rampcheck that it polls an checks if the ramp is done before the script moves on.

  10. Hi,

    I'm using vi scripting to generate code for a user. I was wondering how I can annotate the code in the block diagram and front panel so the user understands it better.

    Thanks.

    Hi

    Take a look at the attached code it places a free label in the BD in the bottom left corner out of the way of all objects. You could easily modify it for the FP.

    Script.AddBDComments.vi

  11. Just keeping this thread alive.

    I was wondering if anyone had any feedback on the LVOOP frameworks I was playing with, or had a different approach? I think there is a lot to explore here with DVR and LVOOP and I'd love to hear what everyone is doing. There is a lot of potential here that I think I have only just started to scratch the surface of.

    Also are there any pitfalls with regards to storing the DVR of the data members as object data? It seems to work well, inheritance is fine and I can access the parent members if I want. Getting and setting the datamembers inside a method using the inplace structure works well also, but I want to check I'm not walking into something silly before I start using these frameworks in a project.

  12. Because my prof asked me to do it in LabView :|

    The best place to start looking is the examples that ship with LabVIEW. Go to the help menu and select Example Finder. In the search tab search on spreadsheet. Take a look at the Read from Text File.vi and Write to Text File.vi they are good examples to show you how to read data from a tab delimited spreadsheet file and plot the results. Also take a look at some of the Graphs examples.

    If it's an Excel file that you need to read and not a tab delimited spreadsheet file then take a look at the NI Report Generation Toolkit. There are some free alternatives out there to read Excel files if you do a bit of searching.

  13. I've been playing some more with LVOOP 2009

    I've been working on implementing active objects into the framework I posted earlier. An active object has its own process which is spawned when its instantiated. Active objects are useful if you want your object to have time dependent characteristics such as a pump controller. You can imagine that with an ordinary pump you can turn it on or off, but what about PumpVolume? You wouldn't want your PumpVolume method to hold execution while it turns the pump on, waits and then turns it off, instead a better way is if your PumpVolume method messaged to a process that handled this operation.

    Attached is a demo that instantiates two pumps to demonstrate Active Objects and that each instance has its own process.

    LVOOP2009_ActiveObj.zip

    • Like 1
×
×
  • Create New...

Important Information

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