Jump to content

ned

Members
  • Posts

    571
  • Joined

  • Last visited

  • Days Won

    14

Posts posted by ned

  1. Hello,

    We have labview 7.1 and 8.2 installed on a network share.

    With labview7.1 (or any other programm installed on this network share) we have no trouble at all, but when we work with lv8 we get a lot of "Generic file I/O error" messages when we want to save (a lot of) vi's to the network.

    IT also told me there is no problem with the network.

    After a few retry's most of the time saving does work.

    Is there anyone who has the same problem when using labviw8(.2)?

    I saw this issue when I first upgraded to LabVIEW 8.2, but at the same time our network drives were regularly having problems so I assumed it was related to that, even though LabVIEW 7.1 never complained. Since then our IT staff has apparently fixed something related to the network drives and I no longer see the error, but I have no idea what changed. Sorry I can't be of much help other than to tell you that you're not the only one who's seen the problem. If I get an opportunity I'll ask our IT staff what they did.

  2. At the risk of repeating myself... just create another notifier, like you did for the inputs, but this time put the "Send Notification" inside of MotCan.vi, and the "Get Notifier Status" inside the while loop of the Plate Motor VI. Wire the actual speed as the notification to be sent and you'll be all set.

  3. Working on a joint application with delbertson, got notifiers working for alot of different user inputed reentrants, is there any 'simple' way to get outputted indicators from each individual reentrant VI. :headbang:

    We have AC Motors, Stepper Motors & Sensors all split over multiple reentrant VI's, it would be great to get some feedback onto the Front Panel Main application.

    I can get the indicators updating in the actual reentrant VI but not in the Main application, as far as I can see from 'Help' and web site sources this is not possible without initialising VIServer, is this correct :question:

    Perhaps I'm misunderstanding your problem, but you can use notifiers for your outputs, too.

  4. Couldn't work out how to add a notifier out though. Ended up adding the control to the main VI then turned the section into a VI to create the interface.

    Is there a more direct way of doing this?

    I usually create notifier controls or indicators by right-clicking on the "Notifier" terminal of any notifier function and choosing "Create -> Control". I then copy and paste the control wherever it's needed.

  5. The reentrant VI solution is the right way to go, and you just need to separate the logic from the user interface. Create a custom control of a cluster containing the speed, power and direction controls and place one instance of it for each motor you want to control. Then, use a notifier to pass values from the user interface into the timed loop while the loops are running. Note the use of "Get Notifier Status" and not "Wait On Notification" in the subVI. As often happens with LabVIEW, a diagram is much clearer than an explanation, so take a look at the illustration below.

    post-3989-1165945873.gif?width=400

    post-3989-1165945882.gif?width=400

    post-3989-1165945887.gif?width=400

    post-3989-1165945893.gif?width=400

  6. The attached ZIP file contains two folders, each containing one project. Open both projects, then open "copy typedef bug.vi" from project 1, and "blank fp.vi" from project 2. Try to copy the enumeration from the front panel of "copy typedef bug.vi" to the front panel of "blank fp.vi" (copy/paste or drag) and notice that it fails silently, because there's a conflicting type definition already in memory in the application instance for project 2. I accept that the copy should fail, I just don't think it should do so without explaining the error. If you're trying to copy a number of front panel elements at once, one of which happens to be a type definition, and the conflicting type definition in the target VI is buried several layers deep in subVIs, it's very puzzling to see the copy fail.

    Download File:post-3989-1165587744.zip

  7. The problem is that this gives me a "disable-wave". From one side of the vi to the other, clearly visible.

    Cool effect, but not planned :rolleyes:

    Is there a better way?

    The way you're doing it is just fine. Surround your for loop with enabling and disabling the front panel property "Defer Panel Updates" as shown below. All the controls will be disabled simultaneously when you disable "Defer Panel Updates" at the end of the loop.

    post-3989-1164124787.gif?width=400

  8. Maybe you could try an alternate interface. Instead of showing the user an array of steps, have a listbox showing the steps that have been created, and one single cluster control. The user could set up the cluster, and then insert that set of parameters into the list of steps. See the attached mock front panel. When the user selects an existing step from the list, update the cluster control (using a local variable). You'd need to maintain a list of the steps that have been created by putting an array of clusters into a shift register.

    As for for activating only the appropriate controls, see the attached block diagram image. Note that on the front panel I've moved each set of parameters into its own sub-cluster. When the user selects a type of test, it automatically enables the appropriate sub-cluster of parameters, and disables the rest.

    I hope I've provided enough detail for you to implement this, if you like this approach.

    post-3989-1163692725.gif?width=400

    post-3989-1163693018.gif?width=400

  9. In your VI, the loop time is irrelevant; the reason that your LabVIEW results don't match your Simulink results is because the dt input to H(s) is too large. You are supplying the dt input to H(s) so you'll always get the same results regardless of how fast the loop runs. If your loop time matches your dt, then your code executes in "real time" - at the same rate as an equivalent physical system. However, you probably want to simulate faster than that (as Simulink does), so if you were to make your loop time 1ms, but leave your dt input at 10ms, you'd get your results 10 times as fast as real life.

    A better approach, though, might be to put your processing into a for loop inside your while loop, as shown in this diagram:

    post-3989-1163691735.gif?width=400

  10. You don't seem to use the type descriptor so you can use _Variant to Flattened String_ instead of Flatten to string. Then you'll transmit only data, without the datatype (which includes names)

    Right, except that what I'm trying to do here is directly replace an existing queue (carrying a variant) with a TCP/IP connection. If I flatten the variant to a string, then when I read from the TCP/IP connection I can put the data directly into a variant and place it on the queue as though it had come from the queue locally, and the network VI doesn't need to know anything about the type of data in it (thus making the VI easily reusable). If I use Variant to Flattened String, then the receiving network VI needs to be able interpret the data, even though I'm just going to turn it right back into a variant and enqueue it. Also, I'm using variant attributes, which are conveniently transferred when flattening a variant to a string, but aren't available using Variant to Flattened String.

  11. I have an application that handles communication between a control loop and the user interface by passing messages over a pair of queues that contain variants. In order to allow these two loops to run on separate machines, I've added a VI to each loop that dequeues an element, flattens it to a string, sends it over a TCP/IP connection, and does the reverse on the receiving end. This all works great, and since I'm flattening the variants directly to a string I can use it for any data whatsoever that comes over the network.

    However, sometimes I'm sending clusters back and forth, and the cluster element names are included in the flattened string, which adds unnecessary network traffic. Is there any easy way to "anonymize" my clusters, either before they're queued or before sending them over the network?

  12. You might want to see this post about obtaining queues. It's not that there's a bug in obtaining multiple copies of the same queue by name, it's by design - every time you obtain a queue by name you need a corresponding release queue. You should not do obtain queue in a loop unless you also have a release queue in that loop. Personally I generally pass queue references directly to subVIs in most cases to avoid this problem; the main VI is responsible for both creating the queue and destroying it when it finishes. This approach also allows the main loop to signal termination to any subVIs that may be waiting on the queue, because any queue operation will generate an error once the queue has been destroyed. There are times when having each subVI obtain its own copy of the queue is useful - for example if you want to run and debug just the subVI and it needs a valid queue refnum.

  13. Has anyone else here already done it and has an example to share?

    NI has already done it and has an example to share, even for those who don't have the PID toolkit:

    C:\Program Files\National Instruments\LabVIEW 7.1\examples\daq\solution\control.llb\simple PID.vi (also available in LabVIEW 8.0)

    Or you can find this in the Example Finder under Hardware Input and Output -> Traditional DAQ -> Solutions -> PID and Alarm Controllers -> Simple PID Demo

    It's not as elegant as the one in the PID toolkit but does the same thing.

  14. If you know the destination email address in advance, you could look up the SMTP server for that address and connect directly to it, which would avoid needing authentication. You can use the "nslookup" tool on Unix or from a Windows command prompt to do this, as shown below. The server with the lowest MX preference has first priority. If your users can enter the email address then this becomes more work, but perhaps you could get the domain from the email address, feed the query to nslookup using "Shell Exec," parse the output and determine the server to which to connect.

    C:\>nslookup -q=mx yahoo.com

    Server: nfcntad01

    Address: 172.20.0.215

    Non-authoritative answer:

    yahoo.com MX preference = 1, mail exchanger = mx2.mail.yahoo.com

    yahoo.com MX preference = 1, mail exchanger = mx3.mail.yahoo.com

    yahoo.com MX preference = 5, mail exchanger = mx4.mail.yahoo.com

    yahoo.com MX preference = 1, mail exchanger = mx1.mail.yahoo.com

  15. This is exactly the expected behavior. The Dialog Box vi does not terminate until the user clicks the button, and that's important - there are times when you might want to wait for the user to acknowledge the message before continuing (that's why there's an output from the Dialog Box vi). A structure (case statement, while loop, etc) can't complete until every VI inside of it has terminated, so your VI waits in the case structure until you click OK.

    Second, the code is not ignoring the effect of the property node until after you click the button - in fact, you may see that the motor button does change positions on the front panel while the message box is still visible - but that's not enough to turn off your motor. Somewhere in your code you must be reading the value of that button and writing that value to a relay, and your motor isn't turning off because the message box is preventing that read from occurring.

    One easy solution is to write directly to the relay inside your case statement (but also update the property node so you don't turn the motor back on again after the user acknowledges the message). Another is to put your message box in a separate loop, and use a notifier to tell that loop to show the message box. If you post your code, I'm sure someone will be able to suggest a good solution for you.

  16. I'm not sure I've completely understood what you're trying to do here, but here's my suggestion:

    Don't use a state machine. Instead, create an array of clusters and store that in a shift register in the while loop. Inside the while loop, remove the first element of the array, which should be a cluster containing the name of the remote FTP server, the directory, and list of file names. Run your code for that loop. If it succeeds, continue to the next element of the array; if it fails, add that cluster back into the array and try again. See the attached image.

    Also note that I disconnected the error shift register inside the while loop. Be careful with storing errors in a shift register; the way you had written it previously, if one case caused an error, that error would continue through the rest of the cases, probably causing them not to do anything.

    post-3989-1153231150.png?width=400

×
×
  • Create New...

Important Information

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