Jump to content

Mark Smith

Members
  • Posts

    330
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by Mark Smith

  1. I've used both the XML's that Paul suggested and conventional .ini style files. The ini version is better if you really expect users to make changes - XML is fine if you just want human readable for troubleshooting or such. I also think Daklu's suggestion to use individual config files for unique devices is a good one since changes to any one device don't affect others and it's just really easy to grab the config you need where you need it. I do use clusters in the class private data to faclitate the read/write. And I would suggest you check out the Read/Write anything VIs (http://www.mooregood...abViewStuff.htm) since these are efficient and easy to use. Also, use the Get System Directory VI from the File Constants palette to put the files into a folder for your app in the Public Application Data directory. This makes management relatively easy and safe. For ini files, I'll use the Get LV Class Path VI and strip the name to use for naming the ini file. This makes the ini files effectively self-naming and easy to manage. I also have reuse code that will look for a config file and if it doesn't find it, create one for that class. That helps because I don't have to distribute config files with the source but they're still relatively easy to deploy with the executable.

    Mark

    Mark

    • Like 1
  2. The UI lock is indeed weird.

    After you unregister an event registration refnum, I'm not sure if you're supposed to be able to reuse it. I'm under the impression the way one usually handles dynamically registering/unregistering events is by using null refnums for unregistration:

    post-11742-0-18460700-1323876184_thumb.p

    Dynamic Registration LV10.vi

    I just ran into this issue with some code I wrote in LV10 and then tried to run in LV11. This thread proved most useful as MJE's solution worked exactly as advertised, so a big thanks and kudos! But I have to ask, the idea of NOT using a function called unregister for events and instead using null refs to ... you guessed it ... unregister for events seems like some pretty arcane knowledge. Where did you get this tidbit of information?

    Thanks,

    Mark

  3. I did some development that used the LuaVIEW toolkit for my previous employer. For the particular application we had, a scriptable executable was a perfect fit and the LuaVIEW interface was very valuable. Now, the guys at the old place have a new application that would also benefit from LuaVIEW but they've been unable to get any attention from the LuaVIEW owners. Also, the last release of LuaVIEW was for LabVIEW 2009. So, it appears that future development and support may be dead. If anyone knows any different, please chime in!

    I'm just hoping someone with knowledge of the situation will see this and provide some insight.

    Thanks!

    Mark

  4. Yair,

    Thanks for the info - so I'm expecting more from the function that it's designed to do - I guess the function name explains it if I read carefully :). Still, would it be useful to have a function that could convert (actually deep copy) a parent to a child and preserve the parent's data since it seems that would always be a safe thing to do? As far as I can tell, the To More Specific class VI would do the same thing as the Preserve Run Time Class - that is, fail and return a default instance of the child.

    Thanks,

    Mark

  5. I'm using the preserve run time class function to cast an incoming object like this.

    When I pass a parent class object into the EventMessage in, the current value of the parent class property is not preserved on the output. When I pass in a child class, the parent property is preserved. It's like a new default instance of the child class is created when I pass in the parent rather than a child class instance that has the incoming parent's properties preserved and defaults for the undefined child class properties. I expected the preserve run time class function to take the instance of the parent and "deep-copy" it a new child instance if the parent was on the wire. Apparently, I'm wrong about that. But I have to ask why this behavior? I can't think of why one wouldn't want to preserve the parent's properties as part of a cast (it seems that's a safe cast, like casting a 16 bit int to a 32). What am I missing?

    Thanks,

    Mark

    post-1322-0-39539300-1315923258_thumb.pn

  6. There are a couple of things that come to mind. One is to transfer ownership of the ref from the VI that launches a dynamic VI in a new thread to the dynamic VI. Then it doesn't matter if the caller goes out of scope. This happens with the arguments to the Run method from the invoke node (LV 2010 and earlier) - LV 2011 has the new Async VI call primitive and it can do the same thing by setting the arguments to the VI Ref open method. There's a recent thread here on LAVA that has much info about that (http://lavag.org/top...nchronous-call/). The other method that might work is to create a functional global that is a "reference pool". Call this FGV by something (like the main panel) that never gets unloaded and store create all of your refs in there. The FGV should never go out of scope and the refs should not be destroyed. In this case, do not transfer ownership of the ref to the called VI. This might work for you.

    Mark

  7. Many of the contracts we see require our company to carry liability insurance or we won't even be considered. And we just do software consulting. And we're in the USA. So that means we do it or we don't work.

    It is an interesting argument that AQ makes that it doesn't seem anyone sues MS for the BSOD. But, IIRC, there were no end of lawsuits against Toyota when their software/firmware was suspected (wrongly, it seems) of causing unintended acceleration. And I can't imagine Boeing wouldn't be liable if a 737 took a nosedive when the flight controller failed. At any rate, this is why I write LV - it's infinitely more understandable (and logical) than the law.

    Mark

  8. One common problem that can cause this sort of thing is that a VI that is loaded dynamically might need its front panel (like when you need to set the control value thru VI Server). If you enable debugging for the built app and all of a sudden it works, this might be the problem since the debug build will retain the FP's where the standard build removes all except the Top Level VIs. Wait - I see you load the subVI as a source distribution - that makes this unlikely.

    Probably, this is because the dynamically called VI can't find one of it's dependencies. Sometimes I just give up and include everything but the kitchen sink in the build dependencies just to get it to run and then start removing components until it fails. Not very much fun but it usually works.

    But I feel your pain - this is one of the biggest PITAs that I encounter. You get a broken app and absolutely no help from the error message.

    Mark

  9. We've got one of those - you wanna buy it? :D

    I'm working on a vision system that measures the characterisitcs of intra-ocuplar lens implants, a grand communications test framework/architecture for PDHC devices, and a suite of testers for personal automated medicators.

    I wanna buy a personal automated medicator :) Lifting the beer mug manually is such old school...

  10. I also have LV 8.6.1 on my Win7 64 bit machine - I'll run your VI's and report back, although it won't be until tomorrow that I expect to be able to do this - I'm traveling today and I can't keep my machine on that long.

    Also, I'm starting to understand your constraints, I think. So effectively the C program is a data server? It listens for requests for data and then writes it to the client. And it doesn't maintain the connection once it finishes the initial write. You might try using the toolkit at

    http://lavag.org/fil...ls-for-labview/

    I don't really know if this might help since the cause of this behavior is so hard to identify, but since it's a different implementation it might either work or at least return an error message that might throw some light on the subject. If the Windows Socket error isn't recognized and converted to a LabVIEW error code,, it will return the winsock error code which might be useful. It will work as a direct replacement for the TCP/IP functions with the caveat that you always have to supply an IP address (no lookups).

    Mark

  11. OK - I may have found out something useful here - here's the timeline.

    I loaded the LV read and write VIs (using LV 2011 - downloaded it here at NI Week!). The first time, it ran until my computer went to sleep (about one hour). Then, it would pretty consistently fail between 2 and 40 minutes. So I started poking around and looking into the error code and who failed first. That lead me to suspect a timeout problem. I set the timeouts on both the read and write TCP functions to -1 (wait forever) and started it up last night. It was still running this morning (8+ hours). So, this is only a single data point, but it may be useful. Also, you have the writer listening for the reader. Although I think there's no reason while this is wrong, it seems to me that it's more typical for the data consumer to invoke the listener (most LV written server examples use this, I think). I also can't think of why you wouldn't want the reader/writer to wait for data up to forever as long as they have a valid connection - if the connection dies, the functions will stop blocking and return the error (not just lock up the system).

    I hope this helps,

    Mark

    • Like 1
  12. This is one of those places where using the DAQ Assistant (on the LabVIEW Function Palette) is sort of useful. If you drop the assistant on block diagram, it will guide you through creating a simple DaqMx VI using your new card. You can then convert the assistant to code and see what had to happen to open and talk to your card. A caveat: The DAQ Assistant (imho) does not make code that should be used in anything that remotely resembles production code. Just use it as a learning tool and then re-write the DaqMx code to fit your particular application.

    Mark

  13. If you're deploying to Windows 7, the UAC stuff should work for you. If you drop the protected config information in the Program Data folder, then it's automatically protected for write access to only users logged in with administrator privileges. You can use the shell32 call MJE pointed out to set properties on your program depending on detected user privileges. And if you need to modify files you can do that while the standard user is logged on by using the UAC dialog that will allow the write if the user can supply administrator credentials.

    Mark

  14. I have two loops. One for data taking and logging, one for loading a parameter file. I notice that when I click the "browse" button on the "load file" field, the data taking and logging loop freezes.

    Attached is an example which demonstrates the problem.

    Thank you in advance!

    Raymond

    So I found a couple of interesting things. First, I downloaded your VI and opened it up with LV2010 and could not reproduce the problem. Then I noticed your signature says LV8.5 - I don't have 8.5 loaded, so I opened it up in 8.6 and then the problem was just as you described. So, one fix would be to update to LV2010 :) But the crux of the problem seems to be the fact that the Write To Spreadsheet File VI opens and closes the target file on every write. When the File Dialog is open, the Open/Create/Replace file function seems to be blocking and can't open the data file on the read loop until the dialog closes. Take a look at the attached VI where I open the file outside the data loop and then append to it on every iteration and close the file when the loop exits. This is better practice. Best practice would be to separate the data read loop and the data write loop (see the producer/consumer template that ships w/LV). This creates a buffer so that the data taken gets stacked in a queue until the loop that writes to file can service it.

    Mark

    suspend-3.vi

  15. Hello everyone,

    First I want to thank you for your help. I' ve been working on it and here's what happened so far:

    - @ Hooovahh: About MAX yes I have it and I used it before I got the DAQ USB 6008 just to create a virtual DAQ and perform some tests and try out the different functions of DAQmx. And no, I was not using it when I ran my VI. As to the Express VI's with respect to DAQmx's, I'm starting not to like them either! I replaced the Express VI's with DAQmx functions such as "create task/ start/ clear / stop" ... etc Also I want to thank you for the other tips they were very useful. I tried some NI examples and not all of them are compatible with DAQ USB 6008 ( compatible with other DAQ modules).

    - @ mesmith: It's exactly what I suspected the two express VI's are fighting over the DAQ resources. But as for your revised VI I couldn't open it, you see I'm using LabVIEW 7.1 and you're using version 10 so I got the message below.throwpc.gif

    Actually I was able to somehow bypass the problem and so far it's working. You know what I did? I created a flat sequence structure and placed each acquisition operation in a separate frame!

    Anyways I've just started and the project is not yet complete so I'm gonna need your help everyone rolleyes.gif and thanks very much for the help so far.

    Regards

    Sequence structure!? Nooooooooooo............

    Sorry about that - it's just that sequence structures are one of those things that new LV'ers overuse (sometimes horribly so). Anyway, I can't save back to LV7.1, but here's a screen shot of a better way to do things. The crux is that you read both DAQ channels in a single scan and then just get the each channel's value from the scan results array.

    Mark

    post-1322-0-35546400-1308865096_thumb.pn

  16. The problem is exactly what the error message says - the first DAQ Express VI reserves the AI section of the DAQ card for an analog input task and the second thorws an error when it tries to reserve the AI, since the first DAQ Express VI has already reserved it. When you need to read multiple channels on most DAQ cards you have to read all channels in a single task, since there's really a single A/D and a multiplexer. Take a look at the revised VI I attached.

    Mark

    Two Analog In.vi

  17. I'm trying to make sure that I'm not out in left field. I've got a SR# with NI Tech support and would like a second opinion while he looks at it.

    I've narrowed down to the code in the attached VI causing problems for me. The VI will cause LabVIEW to, at best, stop responding (including window updates), or, at worst, go away. By go away I mean it vanished from Task Manager with no message as to why. I didn't see a known issue with LV 2010 SP1 (which is what I'm using) on this. I get proper behavior if I put in a i32 constant or an array of i32s, so it's something about having an array of clusters of the elements I'm using.

    Switching the boolean to include array size resolves the issue in that I get an error, which would be the behavior I expect.

    Thanks,

    Tim

    I can confirm that it crashes LabVIEW (V10.1). I suspect it has something to do with the fact that if you don't set the boolean true, then whatever memory labview needs for that array of clusters just doesn't get allocated before it tries to write to it and you get an access violation.

    Mark

  18. Thanx crelf, here is my vi. This is a very simple program for acquisition of thermocouple signal. I have the same problem, I can't use the calibration that I have done in the measurement and automation explorer.

    Thanx for your help

    In your example VI, you start the task by using a DAQmx physical channel (which just identifies an analog input line on the device) and you configure it from the VI. I can run this VI just fine on virtual hardware by selecting an available physical channel. But I think the problem is that if you are configuring the channel in MAX, then you must have configured it as a global channel and you should be using that global channel to start the task. If you use a physical channel, then you don't get any of the configuration info from MAX and that's why you have to use the Create Channels VI and select TC. The global channel will carry the configuration and scaling information with it. See the attached VI - if you have a global temperature channel defined in MAX, then select it and this VI should run.

    Mark

    Acq Thermocouple Sample.vi

×
×
  • Create New...

Important Information

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