Jump to content

ned

Members
  • Posts

    571
  • Joined

  • Last visited

  • Days Won

    14

Everything posted by ned

  1. QUOTE(BrokenArrow @ Jan 7 2008, 07:49 PM) It depends - what else is happening at the time? I remember seeing somewhere that a zero wait allows LabVIEW to yield processor time to other tasks (including other parts of your LabVIEW program), whereas a loop without a wait just runs as fast as possible, consuming all available CPU time. So if you have other tasks executing in parallel then the zero wait is probably a good idea; if you just need that VI to complete as fast as possible, leave it out.
  2. QUOTE(BrokenArrow @ Jan 7 2008, 01:42 PM) Looks like my computer is faster than yours - I get 595ms without the "zero" timer and 795ms with the timer. Build Array should be acceptable in this case because the array is the same size on every iteration, so the memory for it only needs to be allocated once and then it can be reused each time through the loop. You should avoid using Build Array in a loop when you are adding elements to the array on each loop iteration and speed is critical, because adding new elements grows the array. Resizing the array may force LabVIEW to allocate a new, larger segment of memory and then copy all values into that space, which is a time-consuming operation.
  3. DO NOT click on the links to the screenshots; they point at a website in a foreign language, and not at full-size images. Reported to the moderator.
  4. QUOTE(ned @ Nov 13 2007, 09:31 AM) Someone asked me by personal message for this file saved as 8.0, so I'm adding it here. http://lavag.org/old_files/post-3989-1196442371.vi'>Download File:post-3989-1196442371.vi
  5. QUOTE(MeltingPlastic @ Nov 29 2007, 11:47 PM) Right - which is why I suggested unchecking "Transpose Array." A chart can take a lot of different types of data as input. One data type is a two-dimensional array, where one axis is points in time, and the other is plots. You can add multiple points to a chart at the same time. What's happening here is that your axis are being interpreted backwards. Each time through your loop, instead of adding one point to each of two plots, you're adding two points to the same plot. Then it draws a line between them, which is what you're seeing. Try replacing your combination of decimate array and build array with the following (index array and bundle), so that you're passing a cluster to the chart: http://lavag.org/old_files/monthly_11_2007/post-3989-1196441775.gif' target="_blank">
  6. QUOTE(MeltingPlastic @ Nov 29 2007, 03:18 PM) This is just a guess, but try right-clicking on your graph and uncheck "Transpose Array." See if that fixes your problem.
  7. QUOTE(Tomi Maila @ Nov 20 2007, 03:21 PM) Ah, right. I've been bitten by that one before, and now my solution is usually to fork the wire outside the for loop.
  8. QUOTE(Tomi Maila @ Nov 20 2007, 03:21 PM) Ah, right. I've been bitten by that one before, and now my solution is usually to fork the wire outside the for loop.
  9. QUOTE(Jim Kring @ Nov 20 2007, 03:00 PM) Why would you need refnums to be shift registers? Unless you're closing the reference within the loop and replacing it with a not-a-refnum constant, I'd expect they would pass through a loop unmodified, and I don't think there would be a benefit to using a shift register over a tunnel (although I don't think there would be a disadvantage, either, which might be enough to make your point).
  10. QUOTE(Jim Kring @ Nov 20 2007, 03:00 PM) Why would you need refnums to be shift registers? Unless you're closing the reference within the loop and replacing it with a not-a-refnum constant, I'd expect they would pass through a loop unmodified, and I don't think there would be a benefit to using a shift register over a tunnel (although I don't think there would be a disadvantage, either, which might be enough to make your point).
  11. QUOTE(Nero @ Nov 19 2007, 11:11 AM) Yes, you need to go through the FPGA in order to access cRIO I/O modules.
  12. QUOTE(vito @ Nov 15 2007, 12:09 AM) tcplomp understood pretty much what I meant, but I should have looked closer at your code and been clearer in my comment. I had thought that you were clearing the boolean indicators using property nodes rather than writing to them directly, for two reasons: many of your event cases have a property node in the last frame of the sequence, and as a rule I only trigger events on controls so I missed that you are using indicators. However, if you're already doing what you're doing, you can at least avoid accidentally clearing the wrong indicator by using something like this: http://lavag.org/old_files/monthly_11_2007/post-3989-1195136758.gif' target="_blank">
  13. QUOTE(vito @ Nov 13 2007, 07:20 PM) Sorry if I was a bit harsh in my initial reply; let me see if I can explain myself by responding to your points below. I also realize that there is no one ideal architecture for every program, and that your approach may be a good fit for your applications. QUOTE(vito @ Nov 13 2007, 07:20 PM) My objective is to put up for consideration a simple, effective and expandable architecture for LabVIEW programs. The ELCL architecture requires queues to be established, wired up and destroyed and an additional loop. So it's not as simple, therefore it needs to have other advantages to make up for the loss of simplicity. I'd like to now address each of the disadvantages that have been mention for the ESSM architecture: 1) My primary criticism is that this isn't LabVIEW - you have broken any sense of dataflow. Maybe I'm missing something here, but whether you put an action into the (invisible) Event Queue or a queue that the programmer explicitly established, dataflow is broken. And to the same extent. I don't see any difference between the ESSM and ELCL architectures in terms of dataflow breaks. While using a queue does break strict dataflow, I find it easier to follow what is happening because there is a clear connection (a wire) between the two loops, between the enqueue element and dequeue element. There's no guesswork as to what happens when a value goes into the queue. Also, if you look at the example code I wrote, you'll see that chaining multiple actions together does happen in a strict dataflow way, through the use of shift registers. QUOTE(vito @ Nov 13 2007, 07:20 PM) 2) It is impossible to probe a wire to see the sequence in which your states execute. The "LED panel" provides this information and in a better form than a text string. This is because the "LED panel" is graphical. You can see LEDs flash and note their occurrence and order a lot better than strings that flash up. I disagree about this, but perhaps it is a matter of preference. A single string takes up much less space, and if you want to have booleans you still have that option although it requires more coding. A definite advantage of the text string is that it is unique. Let's say one of your event cases hangs up somewhere, but several of your booleans are true (either because you've caused a value change event on one in your event case, or you've forgotten to clear a boolean in a previous state, or you accidentally selected a property node for the wrong boolean). How do you know which case you're in? With an enumeration this is never an issue. (... as an aside, in your template code, you could simplify by using the reference provided in the event data node to clear your boolean, rather than using an explicit property node ...) QUOTE(vito @ Nov 13 2007, 07:20 PM) 3) If a user event occurs in the middle of one of your event sequence chains (one case triggering another) you'll lose the ordering and will have trouble following what happened. Whether you handle user events in the Event Structure or delegate them to a Consumer Loop, if a user event occurs it will equally interrupt the ordering. Please take a look at the example code I posted and note that this is not the case: only in the Idle state do I dequeue actions, so if several states all chain together they are guaranteed to execute uninterrupted in that order. However, I could also chain events together by enqueuing them, and still guarantee execution order by inserting them at the beginning of the queue (as opposed to the event structure which would insert them at the end), something that is not possible in your model. At any time I can examine the entire contents of the queue using the "Get Queue Status" primitive in a separate loop for debugging purposes; in fact, if I use a named queue, I can create a new VI that obtains a reference to that named queue and view its contents without interrupting running code. Furthermore it becomes possible to modify the contents of the queue and discard them if necessary. For example, if someone clicks a STOP button, you can flush the entire queue, forcing a return to the Idle state as soon as the action in progress completes. When you use LabVIEW's internal event queue you give up this control and flexibility. QUOTE(vito @ Nov 13 2007, 07:20 PM) 4) If you ever need to split your logic from your user interface - say, you decide to move to an RT target with a remote display - you'll have to rewrite all your code. Yes, this is a disadvantage of the ESSM architecture. However all the code will not have to be rewritten, but it will have to be cut and pasted into a new structure or the Event Structure will have to be changed to a case structure and unwanted cases removed. Not sure how hard this would be to do or how often or likely it is to happen. Haven't had a need to move my code to another target yet and I'll cross that bridge if and when I come to it. I hope you don't find yourself in that situation. I've converted several applications to RT which depended heavily on passing a cluster of references to every front panel object through to every subVI, and because of this, separating the logic from the user interface was not simple. I think you'd find that replacing all your events would be similarly difficult. QUOTE(vito @ Nov 13 2007, 07:20 PM) 5) As an added benefit, other LabVIEW programmers will quickly understand what you're doing, because it's a standard pattern. This is the subject of the topic. This is a new proposed architecture. Is it good enough to use or not? If it stands the test of the LAVA forum, perhaps it will get used. If significant holes are found in the ESSM architecture then it will disappear. So, I'm still happy with the ESSM architecture, but I look forward to more input as I'm keen to standardise my development on a simple, effective and expandable architecture. Regards, I hope my comments explain why I do not think this would be a good choice for a standard architecture, and I welcome more discussion and opinions from others.
  14. QUOTE(vito @ Nov 12 2007, 11:04 PM) I have to admit that after an initial reading of this my first reaction was pure horror, and that hasn't changed after reading it again. My primary criticism is that this isn't LabVIEW - you have broken any sense of dataflow. It is impossible to probe a wire to see the sequence in which your states execute. If a user event occurs in the middle of one of your event sequence chains (one case triggering another) you'll lose the ordering and will have trouble following what happened. If you ever need to split your logic from your user interface - say, you decide to move to an RT target with a remote display - you'll have to rewrite all your code. Events are wonderful things but they're designed to respond to occasional, unpredictable actions. They're not intended to control the normal flow of your program; if they were, we wouldn't need wires and dataflow. The standard approach here would be to create an enumeration with all your states, with one value for each of your current boolean. That value is stored in a shift register around a while loop. An event structure resides in a separate while loop, and a queue communicates between them. When an event occurs, the corresponding enumeration value is placed in the queue to be processed by the case structure. This structure has all the advantages you listed and it follows traditional data flow. If you want to know where you are you just put a probe on the input to the case structure (or wire an indicator to it). Much easier than a page of booleans. If you ever need to separate your logic from your user interface, you just move the case structure to the new target and replace the queue with some sort of network communication. As an added benefit, other LabVIEW programmers will quickly understand what you're doing, because it's a standard pattern. See attached example. I think you'll see it's easier to set up, read, expand and debug.
  15. QUOTE(Neville D @ Nov 9 2007, 01:24 PM) Do you have the option of using UDP instead of TCP? UDP should be faster and the dedicated link between the machines should prevent data loss and mis-ordering.
  16. QUOTE(BrokenArrow @ Oct 26 2007, 04:08 PM) It helps ensure that your application exits, rather than waiting on a notifier or queue in some other loop. I usually release all my queues and notifiers when my main loop finishes, and that forces my other loops, which use those queues and notifiers, to terminate.
  17. QUOTE(yanouk @ Oct 11 2007, 08:44 AM) I'm pretty sure you can only update all cells at once, but you can do this by replacing only the single array element you want to modify: http://lavag.org/old_files/monthly_10_2007/post-3989-1192117042.gif' target="_blank">
  18. QUOTE(zero-tolerance @ Oct 11 2007, 10:25 AM) Bundle the CD Name and the number into a cluster, with the CD Name as the first element. Build an array of those clusters, one for each disc. Sort the array of clusters using Sort Array. Unbundle the cluster and write out your file.
  19. QUOTE(Jon Sweeney @ Oct 2 2007, 03:31 PM) Here's one way to do it. If you need to change the direction of lines as your code is running, you can clear the existing tasks and create new ones with the lines set as necessary. The VI on the left is "DAQmx Flatten Channel String" from DAQmx - Data Acquisition -> DAQmx Advanced -> DAQmx Utilities; the one on the right is "DAQmx Create Virtual Channel". http://lavag.org/old_files/monthly_10_2007/post-3989-1191415376.gif' target="_blank">
  20. QUOTE(alukindo @ Sep 30 2007, 09:47 PM) Here's a good explanation from the Info-LabVIEW mailing list archives: http://sthmac.magnet.fsu.edu/infolabview/ILVDigests/2005/10/26/Info-LabVIEW_Digest_2005-10-26_015.html' target="_blank">"type-def constant problem".
  21. QUOTE(george seifert @ Sep 25 2007, 08:53 AM) A good option here is to create a user event, register for it in your event structure, and trigger it in your main VI. It would look like this (simplified to one VI with two loops): http://lavag.org/old_files/monthly_09_2007/post-3989-1190733584.gif' target="_blank"> Alternatively, if you already have a timeout case in your event structure, you could check the state of a notifier in that timeout case to see if the notifier has fired.
  22. QUOTE(Thang Nguyen @ Sep 19 2007, 10:41 AM) Different Modbus implementations may use slightly different forms for addresses; that's why in my case the master and slave addresses did not match. You may not have a similar problem if your master and slave agree on the number of digits in the address. Other than that, I'm not sure why you're having problems. Are you certain you're specifying the remote address (for Modbus over TCP, the IP address of the remote machine) properly? Are you communicating over ethernet or a serial connection? Have you tried connecting a null-modem cable between the Fieldpoint module and your host PC, and running Modbus over the serial port?
  23. QUOTE(Louis Manfredi @ Sep 19 2007, 09:51 AM) I'm going to be a voice of dissent here and suggest that this is sufficiently basic that it doesn't need to be documented. You run a wire to the N terminal and you don't get a broken wire, so it must be valid LabVIEW code. What other value, other than the actual value of N, could possibly be a reasonable value on that wire?
  24. QUOTE(Gabi1 @ Sep 19 2007, 09:44 AM) Is there any reason you must use an occurrence rather than a notifier? If not, then I'd suggest you use a single notifier, to which you can send a notification from multiple places. If the notifier might need to contain different data depending on the source of the notification, use a cluster, or use a variant with an attribute that indicates how the variant should be converted to to usable data.
  25. QUOTE(Thang Nguyen @ Sep 17 2007, 05:04 PM) If you're asking how to change the address of the register using the Modbus I/O Server, you need to type in the number yourself after you select the address range, in the shared variable properties. This wasn't obvious to me at first but you've probably already figured it out. I also found that the IO Server allows one digit more of the address than the Modbus master I used, and to fix this I removed the second digit (starting from the left - highest order) from the address. That is, I assigned 4000001 to a shared variable, and I set the master to read from 400001. QUOTE(Thang Nguyen @ Sep 17 2007, 05:57 PM) I did solve the problem about the shared variables which bind to the modbus. Form the PC, I can read the data through the shared variables already. But when I tried to use a Modbus Simulator to simulate the Modbus Master, I cannot read anything form the same adderss. Because in this project, I use the PI Server to read from the modbus. It's not a VI run on the host machine. I don't know what is the real problem with it, I tried some simulators already. Could you give me some recommendations? I'm not familiar with the PI Server, nor unfortunately can I suggest any simulators other than to suggest that if you have a second Fieldpoint module available you could make one of them a master and the other a slave. If you're using Modbus over TCP/IP, is it possible that you have a firewall or other network permissions set in a way that limits access to your Fieldpoint module? As a very basic check, try opening a Windows command window and run "telnet <fieldpoint.ip.address> 502" to see if you can connect.
×
×
  • Create New...

Important Information

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