Jump to content

theoneandonlyjim

Members
  • Posts

    24
  • Joined

  • Last visited

Everything posted by theoneandonlyjim

  1. Cool. I’m not reinventing the wheel. I think so, at least on the face of it. In my most recent applications, I’ve applied OOP as far as my storage type goes – Storage (parent), Access DB (child), text (potential child), etc. My present approach is to bundle new data into an application-specific cluster, which is converted into a variant before input into a dynamic dispatch “Store” method. It works because the DB queries included with LV are able to decode the variant and insert results in the proper columns. I haven’t tried another file format because of time/lack of need, but I’d like to include others as an option in upcoming revs and I don’t think I’ll be able to slide by on included software. I also was looking to extend that principle into building the specific entries – test ID, captured data, test notes, time stamp. The linked example builds its entries for the logs by flattening clusters to a string in the “Add Log” VI, then unflattening using the same control as a key in the "Write Log". It works for the example, but it seems that this approach would couple the code to the application – especially for “results” entries. Could I follow a similar path with a modification that I think would decrease coupling: · Receive results or ID information in the logger mediator · Convert to a string, append header information (position in the log, etc.) based on message name · Enqueue the converted information into the logger process · Dequeue and handle the information in a known way using the header information – possibly by replacing a subset in an array of strings, then rely on non-LV, application-specific tools if doing analysis or retrieval · Keep the in-progress handled information in logger until “Store” instruction or record is complete · On “Store” or complete record, perform dynamic dispatch “Store” Method · Revert temporary logger information to in-progress state Storage space could be a problem, since strings are large data types, but maybe I could figure a way to include data type in the header and decoding in the logger. Thanks for the quick turn. Edited for formatting issues.
  2. I feel I've plateaued in my approach toward data storage. I am still stuck routing data from a tool through a central mediator to a component specifically designed to manage data. My applications have had low data rates or been manually controlled, so the approach has worked, but I'd expect that a faster data rate or more components could induce lag at some point. Here's a reduced-scale example: User presses "Store Data from A" or timer expires, message is sent to mediator >> Mediator routes "Store Data from A" message to Tool A >> Tool A makes measurement, passes to mediator >> Mediator passes measurement to Data Storage >> Data is stored. What I am looking to do is follow this sequence: Tool A generates data on a known schedule, puts it in "a place" (maybe its final location) User or program synchronization makes "Store Data from A" request Mediator routes message to Tool A Tool A handles "Store Data from A" by storing data currently in "a place" in specified location using preferred storage method In effect, cutting out the data manager that has to be written or adapted in each project. A couple of questions, then: Am I overthinking this - trying to achieve something overly fancy? Will I be able to make a method of data storage generic enough that I stay uncoupled? If the answer to these are no and yes, what architecture might one use to accomplish the goal of a decentralized, but still synchronized data manager? If possible, I would welcome links to any KB or other article that would move me forward. Thanks in advance, Jim
  3. Unchecking "Inline" throughout the project did the trick. Thanks. I guess I have some learning to do about to what level I can use that option. Accessors only? Small operations like array indexing, adding, comparison? I'll look on LAVA and NI, but any insight is welcome. Agreed. The debug tool wouldn't connect and generated an access violation, so I was left with forum and Google crawls. I considered that it was reentrancy, but didn't think of inlining. When the VI got stripped to little more than an event structure, initialization code, and empty while loops and the EXE was still broken, I thought something was wrong with one of my classes. I got stuck on "Well, if it's because the VIs are reentrant, the solution is going to be code duplication, and that's not what I want." I wasn't clear on this before, either. What can I leave in dependencies? Some of the classes explicitly contained in the project have parents that weren't. There was some reuse code in dependencies, too. I've moved all but the instr.lib, user.lib, and vi.lib into the project just to be safe, but I thought the build would capture them. This experience shows me that I should shore up my knowledge on app builds. I've run most of my projects in the dev environment and this was the first where I've tried to make a serious attempt at a formal app build. Thank you both.
  4. As part of my latest debug process, I've been building EXEs with a basic test platform and the necessary support files - hopefully cutting down on places to look for problems in each component. The test platform in each case is a basic UI where I can enqueue messages (start, stop, do something) or receive messages (data, status, errors) plus the control code I want to trace. I've been successful with debugging and building several components (temperature readout and calculations, stage control, voltage measurement), but have hit a wall with building the last (a pair of power supplies). I have changed no settings from build to build. For all components, I can do what I want in the development environment. With most, I can build and get the same expected function. With the power supplies, I can do what I want in dev, However, the build completes without error, but the EXE is broken. I get a "The VI is not executable. The full development..." error. The major difference that I'm able to discern is that the power supply test platform has reentrant VIs (some are inlined). Since I'm using OOP and dynamic dispatch, they're sharing clones. If I put a "diagram disable" box around the top level VI for one of the supplies, the app builds and runs successfully, albeit with only one supply functioning. I've looked on the web and the causes I've been able to find for the error aren't relevant for my test. I'm using an emulator for the supplies (no drivers), I'm not dynamically loading anything (path name failures don't happen), and there are no DLLs (I'm not that good yet). Has anyone else run into problems with this? Why wouldn't the error appear in the build process? I'm running LV2011.
  5. OK - I think I'm on my way to figuring this out, but I have a more specific question I hope will generate an answer. If I pursue this course of action, one of the "Choose Implementation" windows looks like the attachment. It seems like I leave myself open to slowdown as a result of the large dynamic dispatch tree the project would have to navigate through. Am I right in this thought? If so, to break it into smaller trees seems like it would require duplicates of the more basic methods that each parent class would have, since their class data would be very similar. This would lead to longer dev time and a larger project. Is this right and would that be this a bigger issue than the potential slowdown? [Edited to include attachment]
  6. I've started a project as a way of transitioning from task-based to object-oriented programming. So far, I wish I'd put the effort in sooner. OOP solves a lot of problems I spent frustrating hours considering ways to get around. Platitudes aside, I want to make sure I'm making the right choices as I learn, so that the right practices are in place beginning early in the process. I favor a hierarchical architecture similar to what's been discussed in other topics on the board, and an observation I've made as I write is that much of the code falls into two categories: abstraction layers and mediators. There are both general similarities (queues in and out, auto/manual mode, etc.) and functional differences (power supply vs. multimeter vs. stepper motor), which spawned a thought and a series of questions. I'm considering building a class for a parent abstraction layer and/or a class for a parent mediator, then inheriting as needed. What pitfalls or advantages might I have missed? Will I discover as my skills progress that I've imposed a need for work-arounds? Or, if I'm careful to keep the parent classes away from anything application-specific, will it provide a good base to my coding that can be managed by version control?
  7. Thanks for the illustration. It generated some additional questions for me. I'll admit I don't have a CS background, so please excuse any ignorance I show. When you say "don't know the specific VI at compile time", do you mean that I have (for example) three subVIs, and based on the input used to choose my plugin, I load the correct one? Or, do you mean that I'm leaving a placeholder for a VI with this specific connector pane that I haven't written yet? If it requires inclusion in my build, how is this an advantage over standard subVIs? If I'm not including VIs in my "always included" list for the executable build, they need to be part of the installer build so that they're placed at a location identified by the path within the caller VI, right? I think dynamic loading/launching is what I am after. The application calls for controlling one of three pre-defined tests sharing a common set of equipment. I want to mask user input because, though there are commonalities between the three tests, not all use all the equipment. I want to load only the components needed.
  8. Sorry - I meant dynamically loaded VIs using Open VI Reference. OOP is something I've yet to tackle.
  9. I'm kind of new to the use of dynamic subVIs, but I've come to recognize just how powerful they can be. I'm revising some existing code and really want to implement them. Before I make them a part of the project, I've been working smaller examples scratch-pad style to get my head around a couple of concepts. I've been able to develop a main and sub-vi example that I've successfully built into an application. While doing so, I've come up with a couple of questions. I'll throw them out to the 'net and see what I get back. -For diagram clarity/readability, I intend to use subVIs within the dynamic VIs. Are these loaded/unloaded as part of the dynamic code? -Along those lines, what happens when I build my application? Do I list the subVIs within the dynamic VIs under "Always Included"? Do I even have to include the dynamic VIs? What about source file settings? I could see that as getting complicated if my application grew past a certain point. -Is there a good VI or other program that allows one to monitor built application memory usage (running/loaded EXEs, VIs, etc.), similar to what "Dynamically Monitor VIs" can do in the development regime? Tracking program function might answer these and other questions I might have. I recognize that these are basic questions, but this topic has just not sunk in for me yet. Apologies also if this is the wrong forum.
  10. I've been working on a bug for sometime now. On two separate Windows systems (one XP and another Vista), I've run into a situation where I temporarily lose connection to a tool connected by USB - just long enough to throw an error in the code and stop the program. I have been thus far unable to figure out a set of conditions which induces this failure, which appears at irregular intervals: 700+ hours, 400+ hours, 48 hours after test start. This has now happened with a two different GPIB-USB and SCXI-1600 connected by USB. I've been told (and observed) two things: that occasionally Windows will selectively suspend USB inputs to conserve power or that the USB inputs will compete for resources. I have observed one tool to be unresponsive to *IDN queries until restart and another to be perfectly healthy when investigated. As such, I've tried a couple of things: -Edited the registry to disable selective suspend - the failure's happened once since then, but there are more "USB" prefixed keys in the registry - should I disable them all? -Added a separate USB card so that my tools aren't sharing resources with the mouse and keyboard - the failure has happened multiple times since then -Disabled all hibernation, sleep, and power off options A couple more were suggested by NI: -Reset Resource VI - I have yet to get the example VI in LV10 to work. -Changing to Windows 7 -Making connections with a GPIB-GPIB - not only is this out of budget, but it doesn't help for the SCXI I've thought of another: -Cutting the USB cable open, clipping the +5 VDC and putting each side on two halves of an SPDT switch connected by RS232 - effectively unplugging/plugging the cable as a manual reset. Since this is such an irregular error (and sometimes leads to thermal runaway), I'd like to apply as many backup solutions as I can before I commit more samples. Has anyone else had this error, and if so, did you try anything different?
  11. I only need temp at that specific point in the loop, so I was trying to economize with my loops. I didn't think I needed to monitor T throughout and pick off at needed times, but it seems like the overhead involved with the "Start Task -> Take Measurement -> Shutdown Task" is throwing my timing out of sync. I'll try producer/consumer where I pass a current value from loop to loop, but there seems like something easier that I'm missing.
  12. Thanks everyone. Live in Raleigh, work in Durham, NC I hadn't thought of that. I'd better polish my "No, thank you, I'm all set on new hardware" speech. LAVA's been great for specific stuff, but I'm thinking more in the abstract. I don't always have a question, but I always need to learn. Like crelf suggests, I want someone better, whose code I can look at in an idle moment and say, "That's a great way to do that." Maybe I can drift around LAVA when I have that urge. I've been thinking of a change, maybe it's time. Any chance of a Raleigh branch opening?
  13. Not specifically from this board, necessarily, but I'm looking for ways to build my skills. I'm the only person who uses the language at my company and I get around well enough to run our test sector, but if I'm going to move up or on, I need to get better. Does NI sponsor user groups? Are there real-world LAVA lounges? Any pointers in the right direction are appreciated. Thanks.
  14. I'm running into a synchronization issue with an SCXI-1112 in an SCXI-1000 frame. Irregularly (every 10 to 15 reads), the read takes roughly 10x longer than the majority of the reads. This slows the rest of that case down, which drops data. I've tried various sample sizes, changing my loop delay, and adding "DAQ Control Task" in my initialization to set the task into "Commit". What else might I try to polish the edges so it doesn't stick any more? I've attached pictures of the relevant code.
  15. Not stupid at all. I was blinded by a long day and failed to see that I wasn't ever running "Initialize". Oof.
  16. Some exposition before the question: I'm trying to restrict access to a tool using semaphores. In my top-level vi, I obtain the reference during my "Initialize" state and release it in my "Stop" state. The reference is untouched in any other state and resides in a shift register. When I pull the reference from the shift register, the "Release Reference" vi generates an error, saying the reference is invalid. I'm only to the point of testing my top-level VI, so no other manipulation occurs. When instead I obtain the reference before my state machine loop begins (initializing the shift register), I don't get this error. I might be having a mental block, but it's not clear to me what the difference is between the two styles. What am I missing?
  17. I love this idea. This would fit very nicely as a replacement to my current architecture and I can see where it would solve some code issues I have patched with duct tape and good intentions.
  18. Ah, and there's the rub. I'm just now getting into LabVIEW OOP, and my skills aren't quite up to this level of a challenge. Maybe in a future rev. Thanks.
  19. I've got to communicate dynamically with several stations which carry out essentially the same operations, where the parameters are individually input by UI and operation by semaphore-controlled tool function. Right now I've got the project set up as a QSM as seen in the attached photo. The top level VI initializes itself, the subVIs and then is idle while the subVIs operate unless an error or stop command is passed. I find myself saving each subVI as a unique file in order to maintain operation of the state machine for each, rather than what seems logical - to place a single reentrant VI. This brings to light my question - is there a better option than a QSM?
  20. Let's try this again. I am attempting to write software to accomplish the following: -Acquire, control and display on front panel temperature read in from DAQ -Acquire, control and display on front panel voltage and current Each of these individual functions works independently. I have six individual stages and my application requires me to have control of each of these inputs and outputs through a state machine. Two temperature measurements are important for each of the stages: below and above the device under test. When current is applied to the device, the temperature above changes with relation to the current. I've defined the state machine to be: -Initialize -Find maximum temperature difference with relation to current between two points on the device, adjust current accordingly -Adjust stage temperature to input target -Find maximum temperature difference with relation to current between two points on the device, adjust current accordingly -Cycle current on and off until user stops operation- subsequence of states: wait cycle time, increment cycles, write to log file, toggle current I am using a single, multi-source power supply, to which only one instruction at a time can be written. Where I am struggling is implementing the architecture to put this all together. If I can provide additional information, please let me know.
  21. Sorry for the double post, but I realized last night that I was pretty vague in what I was after. I have a framework for the individual pieces (collecting/adjusting temperature, collecting/adjusting voltage), but there needs to be some interaction between the collect/adjust loops in addition to displaying the values on the front panel and writing the data to the server. Right now the method is a complicated set of local variables, and I'd like to move away from that because it's been difficult to debug. If it was one stage, I think I'd be in business, but I'm having trouble wrapping my head around how to pass and process the data for each stage in a clean way.
  22. I'm a bit out of my depth on this one, but hopefully someone out there can take a flier. I've taken over a system from another test engineer which entails 6 (soon to be 12) independent LV-regulated stages, on which temperature, current, and voltage are all monitored by DAQ and controlled as programmed. Temperature is controlled by the user and is monitored by polling, current and voltage are initialized by the user then controlled by the device. Also, the data collected is uploaded via SQL to a server.The program works as is, but the overall function of the current/voltage test needs to be changed to fit a change in testing protocol. While I make these changes, I'd like to clean up the code. The present system uses a lot of bad to awful LabVIEW protocol (the previous user had no formal training), and I'm having trouble separating the challenge of designing the architecture vs. deciphering the function/necessity of each feature. I'm a recent CLAD and this is a bit of a stretch for my current abilities.
×
×
  • Create New...

Important Information

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