Jump to content

ned

Members
  • Posts

    571
  • Joined

  • Last visited

  • Days Won

    14

Everything posted by ned

  1. We use these all over the place (in non-LabVIEW applications) and I've never heard any complaints. I've only recently needed LabVIEW to talk to a device through one of them. Setup was simple.
  2. It sounds like you should make a separate VI for each type of unit, that overrides a VI in the parent class. If you don't want to include the GUI directly in the class, you could develop a system where you use a set of queues or user events to pass data, or embed the VI as a subpanel. Your description does sound like a classic use case OOP. It's a function, not a setting, found with the other OOP functions in the palettes.
  3. What you're doing should work. There's no reason your classes should be losing their association with their specific type if everything is coded properly - your serial unit should always "know" that it's a serial unit even if it's passed to a VI that expects a generic unit. You might need "Preserve Run-Time Class" on an output of a VI somewhere.
  4. Is anyone else planning to attend a FIRST Regional Competition? If so, which one? I'm curious who's involved in FIRST, and encourage everyone to go see a competition near you if you can. I'm volunteering at the Boston Regional March 25-27, and would be interested in meeting other LAVA members there.
  5. Does this link help you at all? It's written for a FieldPoint unit but will work on a PC. Transferring Logged Data from the FP-20xx through Serial Modem Communication.
  6. I suppose I've been enjoying the anonymity of having different usernames on LAVA and the NI Forums, but here I am: ned (LAVA) / nathand (NI Forums) / nathand (NI Community)
  7. That's one way to do it; another is simply to build an array of all your IDs and use Search 1D Array. Slightly slower but uses slightly less memory; if you're only handling about 30 IDs, I doubt you'll see any difference in speed. Here's a modified version that generates the lookup table on the fly, using Search 1D Array. I don't think the use a build array in a loop in this version will cause noticeable speed issues. The array of clusters of arrays looks odd, but in LabVIEW you can't have an array of arrays - it would just be an array with an additional dimension, which forces all the sub-arrays to have matching dimensions. The way around it is to wrap each array in a cluster. If you're expecting roughly the same number of messages from each ID and you know in advance how many messages that is, you could efficiently use a 2D array instead. Sorting array-3.vi
  8. Can you change the format of your data? Strings aren't that efficient, and CAN packets are fixed-size. You could convert to a cluster of numeric values, where the first element is the ID. Then, one route would be to use that ID as an index into an array, where each element of the array contains a cluster that contains an array of all data found for that ID. Ideally you would pre-allocate each array, since one reason your example is slow is the use of build array in your loop. What output do you actually need? Instead of moving your CAN data around, you could build arrays of indices into the original data, one per ID. This would give you a quick way to retrieve all the data for one ID without making a large number of copies. I've attached a quickly-written sample that demonstrates this, then uses the generated array of indices to extract the data into separate arrays for each node. Oops, forgot the attachment - and the "Use Full Editor" button doesn't seem to be working, so I couldn't attach it to the previous post. Sorting array-1.vi
  9. Why do you need a weaker reference? LabVIEW will automatically upclass references when necessary (so if you build the tree reference into an array of references of other types, it will make an array of the most specific common parent). If you want to do this explicity, use "To More Generic Class." Also, I think you might be confusing two types of references. The reference you have right now refers to the tree on your front panel. If you right-click on that reference and choose "Create constant" then you'll have a reference for which you can specify the class. That constant is simply a type specifier, so it can be as specific or generic as you want.
  10. There's a configuration option for Call Library Node that says "Specify path on diagram." Have you tried setting that option? Then when your application (or plugin) starts, you can store the path to the library in some sort of global storage and pass it to each call library node.
  11. Looks fine to me, and if I turn on execution highlighting on the child methods I see them executing. I opened your VIs in 8.6.1.
  12. Your image shows three loops trying to dequeue, not enqueue. This will not work, since each element in the queue can only be dequeued once, after which it's no longer in the queue. Which loop will dequeue a particular element is random. You should consider using a notifier, if you don't need to capture every element, or use three separate queues.
  13. I already wrote the array implementation - that's where I started, and it worked. As a weekend problem I was investigating other ways to do it. Here's a simplified, stripped down version of my linked list; is there a better way to do this, while still using a recursive data structure? By the way, I discovered in the process that the following code crashes LabVIEW, almost immediately and with no error message at all: Linked List.zip
  14. No, you're not missing anything here - an array is an easy way to do this in LV. I'm just curious if the new features in LV allow it to be done neatly as a linked list, since that's how I'd do it in C. I'm building a list of chemical reactions. The list is read from a file, so I don't know in advance how large the list will need to be. Then I need to run those reactions. Sometimes the user might want to re-run a reaction before proceeding, but I'll never need to back up to a previous reaction, so a linked list is a reasonable structure. From a performance point of view there's no problem with either implementation, since the list is short and I only need to build it once when the run starts. My question is pure curiousity as to whether a LabVIEW implementation exists (or can exist) that does what I want.
  15. Thanks for all the comments, but I should have phrased my original question more clearly. I'm trying to learn about what can be done with recursive data structures (using a parent class as a member of a child class), without using any type of reference (DVR, queue). I'm looking for an implementation, if anyone has one, that can efficiently add items to the end of a list (without having to iterate through the entire list for each insert). The problem is that, as far as I can tell, it's not possible to keep track of both the beginning and end of the list at the same time. Adding an item to the end of the list invalidates the front, because the front can only point at the list at a specific point in time. In C I would use two pointers, one to the beginning of the list and one for the current end, and I can't see a way to duplicate that structure in LabVIEW.
  16. I have a project in which I'm trying to use a linked list. An array is an acceptable alternative, but it seems like a good opportunity to learn about recursive data structures. I've used linked lists in C, which might be hurting my ability to use them in LabVIEW since I'm accustomed to thinking in pointers. Is there a neat way I can maintain a reference to the head of a list while continually adding items to the tail? Aristos Queue posted an implementation that allows an insert at any point but traverses the list recursively in order to do it, which seems inefficient. I'd like to maintain the current location in a shift register, with a function in the loop that takes the current index, adds a new element on the end, and returns the new element so it can be put in the shift register. I can't find a way to do that and maintain the list order. Either I keep adding to the beginning of the list, and the elements are in reverse order, or I lose track of the beginning of the list. The best solution I've found so far is to maintain both the previous and next element in the list (a doubly linked list), insert them backwards, and then reverse the list after adding all elements to it. Is there another way?
  17. You can use TCP to send data between two programs on the same PC. The LabVIEW program and the C++ will use different ports because only one application can open a port at a time, but this is not a problem. You will want to pick one of the two applications to be your "server" and the other as a "client." The server opens a specific port and listens for a connection. The client connects to that port (which is not the same as opening it) to establish communication. The client is automatically assigned a random port when it opens the connection.
  18. If you want to see the definitive syntax, grab a copy of "The C Programming Language" by Kernighan and Ritchie (K&R). At first glance, you're missing the qualifiers "short," "long," "signed," and "unsigned." Several of the types you listed (for example, the ones ending in numbers) aren't part of the C specification but are instead defined as their own typedefs in (often platform-specific) header files. There are many other types, especially in Windows programming, that you're likely to come across and are defined in header files. A good start might be the list of types from LabVIEW's "Call DLL" example, but that's pretty short.
  19. Just to confirm, are you also seeing that you can read back the file you posted just fine on a PC, and you're only having problems on the cRIO? I don't have access to a cRIO against which I can test your code, but it looks fine on my PC.
  20. Are you getting back the same number of points that you wrote? Do you get any error from Read from Binary File? That information would help determine if there's an offset when reading the file, or if you're writing the correct number of bytes but misinterpreting them. You do have an unnecessary "Set File Position" in the read, but I don't think that's causing your problem. There are some style points you should correct in your code. Do you really need to check every 1 ms if the time is elapsed, or can you use a longer, more reasonable wait? You should eliminate most of your global variables and replace them with shift registers (I know, the FIRST framework uses global variables all over the place). Both Current Line and the Previous Data Time should be integers, not floating point values (find the global definition, right-click, and change the representation to I32). Sequence structures, especially stacked ones, are almost never necessary and can be removed.
  21. If you read the help for the LabVIEW Seconds to Date/Time, you'll see that LabVIEW's "epoch" date is 12:00 a.m., Friday, January 1, 1904. You can determine the number of seconds between your epoch date and LabVIEW's, then add that amount before doing the conversion. Also make sure to use a numeric format with enough bits to store your number of seconds, taking LabVIEW's epoch date into account.
  22. It's an ActiveX application, not direct calls to a DLL, so I don't have to worry about whether it's threadsafe. It's designed to talk to multiple instruments concurrently. The external component I'm calling assigns every instrument a unique name and then requires that name as a parameter to most of its methods. There's some wackiness about the way it handles data - it seems to like structures flattened a bit like LabVIEW except with only a single length byte for strings and opposite endianness for multi-byte values, and it uses Windows messages to send status updates - but I've been able to make the communication work. At least that keeps it exciting. We're replacing an existing but outdated system (built by an outside vendor) with newer equipment from other divisions in our company, so the project goal was well-defined from the start. There are only a limited number of chemicals we need to produce and the market for them is mature so future expansion is unlikely.
  23. Thank you for taking the time to comment in so much detail. This is the sort of feedback I was hoping to get. I like this suggestion; I'll see if I can implement it. I do have, as you suspected, the problem of a single ActiveX reference for accessing multiple instruments, but I can use the unique instrument name (which is a parameter to all the relevant ActiveX calls) as a proxy for the actual instrument reference. It seems to me, though, that the manager might be as simple as a queue with a maximum length equal to the total number of instruments available. Is there any reason to make it more complicated than that? Good point about considering future needs, although fortunately in this specific case we answered a lot of these questions during the initial design discussions for the project. I only have one liquid handling robot in the system, so it seems to make sense to treat it as a singleton object. The reference to it is an ActiveX refnum. Because there's only one, it is convenient to avoid wiring that refnum to every function that needs it (also, I don't want to accidentally open multiple references to the same ActiveX object). That's why I was looking at storing the refnum inside a DVR (or SEQ), and then putting that containing reference inside a class global of some sort.
  24. This is partly the thinking that prompted my question, but if you want to use a class, how do you do it? I couldn't think of an elegant way to get a singleton class where running a VI in that class precludes running another VI in the same class concurrently, unless you use a DVR. If you do use a DVR, do you wire a single instance of the class everywhere (making it essentially a singleton), or store the DVR inside a FGV or global inside the class?
  25. Maybe not "a lot" but I do use occurrences regularly. For example I'm using one now where I call an ActiveX method that executes a callback when it completes. After calling the ActiveX method I wait for an occurrence, and the callback function sets the occurrence.
×
×
  • Create New...

Important Information

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