Jump to content

hooovahh

Moderators
  • Posts

    3,388
  • Joined

  • Last visited

  • Days Won

    283

Everything posted by hooovahh

  1. I'm not one that uses LLBs, so I'm glad I won't likely see this issue in this way, but regardless of how often I'm going to encounter a bug, I'm glad the cause of a bug was found. It had not occurred to me that LabVIEW might have different rules for saving files in an LLB than in the OS. Thank you.
  2. Yeah I thought about a database, and did look into using your SQLite library, but honestly it works, it's human readable, and I haven't had any real problems so I didn't see much of a need to change it yet. I was using the OpenG INI stuff and with very large data structures it was a bit slow so I moved to MGI at some point and haven't had any issues since. I think the coupling between actors would still be there even if I went to a database. The coupling I was referring to could be minimized with several techniques, but the actual format of the file isn't going to change this, other design decisions could. Like if each actor was responsible for doing their own configuration control, but as I said my design didn't go this way, not that this could work. Oh and my setup did have a cancel option, which just wouldn't send out the 1-to-N message that a setting was changed, and it would re-read the config file, and re-write the controls in the pages. One other thing I forgot to mention is some times pages of the config, would rely on other pages of the config. So say I had a page that had a Show Advanced Settings checkbox. If this was on you wanted all the other pages to show the advanced settings if there were any. So when I sent out this 1-to-N message to the actors telling them a config was updated, I would also have that message go to each of the pages, so that they could then re-read from the global the settings from all the other pages, so they could show or hide the advanced settings based on the last applied settings. I used this same message to the pages if you canceled too, because a cancel may revert to some state where the UI in the page needs to be updated. I've thought about cleaning this up and posting it, but since it isn't an NI Actor, it uses a decent amount of the reuse library which would need to be made generic or released.
  3. I don't use the Actor Framework, but do use an actor design (multiple parallel loops that are asynchronous and have dedicated tasks with messaging between). The design you describe sounds like it would work but here is a design I use. There is a configuration actor (module) that handles all the File I/O parts. It has a window just like LabVIEW's Tools >> Options dialog, where there is a listbox of settings, and a subpanel that a VI gets loaded into. The control values are what are saved and loaded into a single INI file. Each page in the config is a separate section in the INI. The page VIs are running, but they don't have to be, they can literally be just a set of controls but some times you want feedback so they run, and listen for the global quit message all actors get and stop if they see it. I also setup a slow polling so if the reference is invalid they pages stop too. This way hitting CTRL+. will stop them too, even though they are also asynchronous. On startup of the program, before any actors are started, a VI is called that loads the INI file and puts all the application settings into a global. Where they can be read but not written. Each actor during its init will read from the global the settings they want. Then when the user opens the config actor, makes a change, and then presses OK or Apply, the control values are all read, then re-written to the INI, and re-written to the global. Then a single message goes out to all actors telling them there are new settings that were applied. This is a 1-to-N message where there is no waiting on responses. In this message is data telling each actor which pages of the config were changed. This way each actor can look at the pages and determine if the data changed, is applicable to them. If I changed a COM port for a power supply, then the power supply actor now needs to cleanup and re-init with the new settings, but the DMM actor doesn't need to do anything. So in my setup one actor handles all File I/O, with the only exception is a single VI that is called before all actors start which does the initial read. Config is done in pages, which are just a collection of VIs and controls. This makes adding new settings easy, just add a new control, then read from the global which is a variant. This way when I add a new setting there is no type defs or controls that need updating, and no new code to write, just add the control to the page VIs, and now that setting is in the INI and global for the rest of the application to read. There is a chance for some runtime errors because of this, but these types of errors you see once in development, then make it the correct type, and never see again. You aren't changing the type of the data mid application. If I have a string data type that is Project Name, I'm not going to change that from a string, so once all the places that I'm reading Project Name are set to string you won't really see any errors again. In your design you mentioned each actor being responsible for their own settings, but I have a few settings that aren't specific to one actor. Under the Advanced page of my config I have a hardware simulation mode. If this is on each actor knows to pretend it is talking to hardware and return random, or semi-random data. I may also have multiple pages for each actor. I have a sequence engine, and it may have multiple sequences that could be in multiple pages, or a single page with a drop down of which sequence to edit. My point is I can have as many settings or as few, which can be shared between actors. A downside of this design comes when you want to just run a single actor without having to run the configuration actor. I realize my design adds some coupling that is generally not desired. So I had some extra code to detect if the configuration actor isn't running, and to use predefined defaults for that actor, if it's not.
  4. Yeah I can't imagine what it is. I think that error is saying those VIs are broken (I only speak English), but the Read/Write Key (Variant) functions don't call out to external code as far as I'm aware. It is all just native configuration file calls, and I don't think has any kind of external DLL calls, which might not have been included in the build by accident. Very odd.
  5. Attached is the VI performing the DLL calls and I think doing the same work as your original VI, notice there isn't anything in terms of error handling so you may want to check the return type to ensure it has no error. It should give you the prototypes you need to call this DLL outside of LabVIEW. Although I've never done this type of thing before, is there some legal notice that should go along with this DLL? I'd assume you are allowed to distribute it since building an EXE in LabVIEW will include it. Encrypt Decrypt Demo Using DLL 2014.vi
  6. Decompiling any NI source is against the terms and conditions you agreed to when you install any NI software.
  7. Filipe, are you aware of the LINX 3.0 toolkit that was released today which allows to deploy and run LabVIEW code on a Raspberry Pi 2/3 and BeagleBone Black? Were you in collaboration with NI, or approached by NI, or have any involvement in LINX 3.0 or was this developed independently?
  8. Your code has several race conditions. Do you need to write those DO before you read the DI? Because the way it is written it will be a race to see who writes to those serial ports first. You should serialize your code, since it is using one hardware port anyway. You are talking to an Arduino over a serial bus. Even at 115200 baud each command has several bytes of payload, then the Arduino needs to read those bytes, do some action (like read a DI) then send several serial bytes back, then your LabVIEW code needs to read those several serial bytes, and display it, then it will do this over again. Your LabVIEW code is Windows based and non-deterministic. Have you ever had a time when your mouse or keyboard just stopped responding in Windows? What do you think your program will do when this happens? You cannot perform reads on an Arduino this way, at any kind of deterministic rate. Instead you should have the Arduino perform the reading, and maybe return something else instead of each pulse. What if the Arduino just returned the number of pulses it saw in the last 1 second, or 500ms? This can be coded on the Arduino side, and have a new function made that performs the task. You can look at the Arduino source and see how other commands are implemented. Another option might be to look at how the continuous AI works. This causes the Arduino to take N samples that are hardware timed, and send them back to the Windows side. You can try to make your own continuous DI read, or possibly just wire your encoder to the AI. I don't know how fast the sampling rate is, but nyquist says you should be sampling at 2X the input rate minimum, or 10X in real world conditions. So what is the minimum amount of time between pulses? Then are you able to sample at 10X that rate with an Arduino? I'm guessing not. It really seems like some better hardware would be useful, one that has counter timers built in.
  9. Yes I too would reeeeeeeelly want this. If there were an RT Linux version of a PXI chassis, I feel like just making a hard drive image, and putting that into a VM might be a good start. But since there isn't, the other methods of getting this to work are outside of my skill set. I also thought about using some of NI's deployment tools, and if I could get my hands on hardware running RT Linux I could perform a back up, then restore it to a VM, but even with some trickery it won't let an image from a different hardware set be restored. I have a PXI chassis running RT and I made and image, but wasn't able to restore that image to my VM RT. For now I feel like I have to be content with the non-Linux RT in a VM, or hope for some new hardware that is running RT Linux, that I might be able to pull the OS from the hard drive. If you do come up with any other possible solution be sure and post back your results.
  10. I saw those kinds of errors at one point, here is a thread that discusses what might be your issue. http://forums.ni.com/t5/LabVIEW/Build-application-still-fails-with-error-1-in-LV12/td-p/2279948 Here's another thread that might help too. http://forums.ni.com/t5/LabVIEW/Error-1-when-building-my-application-in-Labview-2010-Version-10/td-p/1515860 Basically I think it has an issue with the output folder. If you make the output path, a new path that doesn't exist (or possibly a new empty folder) that is somewhere near the root of the drive (like C:\Test) I think it may resolve some issues with Error 1, but maybe not your exact situation. I've also had builds fail due to access issues, where maybe an explorer window was already open on the output path. In these cases I made a Pre-Build VI that would rename the folder if it already existed. I think that was a different error but could be a similar issue. http://forums.ni.com/t5/LabVIEW/BUG-Application-Builder-fails-if-the-target-window-is-open/td-p/3199387 Historically application builder has been a crap shoot. I've probably had as many successful builds as failed ones throughout the years. But honestly using that Pre-build (well a modified one combined with this one) and using 2015 I don't think I've had an unsuccessful build yet. EDIT: Oh and maybe recreating the project is a good idea if it isn't too much work.
  11. Well to answer your direct question of what is this, here is the help on these functions. http://zone.ni.com/reference/en-XX/help/371361M-01/lvcomm/encrypt_http/ http://zone.ni.com/reference/en-XX/help/371361M-01/lvcomm/decrypt_http/ More specifically they call the DLL at the following location: <LabVIEW Install Folder>\resource\ni_httpClient.dll With the function ni_httpClient_Encrypt or ni_httpClient_Decrypt. Beyond that I can't say what it is actually doing. Would calling that DLL from Java be an acceptable solution if you knew the parameters and data types?
  12. Thanks for the kind words. If you haven't found them yet there is a nugget series on the certification board. Whenever you feel like looking into the CLD be sure and read up on the information there.
  13. It's a system level DLL call that's documented here. https://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx The SystemPowerStatus type is defined here. https://msdn.microsoft.com/en-us/library/windows/desktop/aa373232(v=vs.85).aspx
  14. You can use NI's licensing technology, and your tools can activate, or have trials, just like NI tools do. http://sine.ni.com/nips/cds/view/p/lang/en/nid/209107 https://decibel.ni.com/content/groups/third-party-licensing-and-activation-toolkit
  15. Well that is concerning for sure. Unfortunately I don't have 2015 SP1 yet, but this might be as good of reason as any to start the long download process of that whole software suite. But the fact that this happens on the save makes me even more confused. If it were on the wire operation then I could do some debugging and look into the VIs that get ran, when the wire operation takes place. But the fact that the wire operation works just fine, and it is just on the save, makes me think it might be something more difficult to troubleshoot and resolve. Well I guess I'd send the report to NI...and hope for some support.
  16. You can set the default value of a control using scripting. But I don't think this is what you want. Very few scripting functions work in the run-time engine. Scripting is generally a thing that makes LabVIEW code, or edits LabVIEW code. These are not the types of things you do in a run-time engine. In a built EXE for C++ you wouldn't generate new source code that is compiled and then used in that EXE. It would be something like self modifying code, and probably should be avoided. But what you can do is use a function like the OpenG Write Panel to INI, and Read Panel From INI. This will take the control values for every control on your front panel, and save them to a human readable INI file. Then on startup of your program you can use the Read Panel From INI and it will set the control values to what they were last saved to. Where you save the INI is up to you, but you may get into some permissions issues if you try writing and reading to files under Program Files, which is why most programs are gravitating to using the Application Data folder, or ProgramData for all users. These two wonderful OpenG functions can be found in the Variant Configuration package.
  17. I haven't used the NI one, but the little amount I played around with the JKI Caraya unit tester, it seemed pretty slick. Have you used that unit test software? And did you also find it to be slow?
  18. I've never heard of an Academic Partner, but here are some links on NI's academic information. http://us.ni.com/academic https://decibel.ni.com/content/groups/ni-academic-partners It would probably be best to contact NI directly for this type of question.
  19. Oh yeah that is a sticking point isn't it. So I made a VI that is set to run when opened, and when it runs it just reads the Command Line Arguments using the property node. I then opened this VI (and ran it because it was opened) using a command line call to LabVIEW.exe. It opened and ran the VI just fine, but any command line parameters passed to LabVIEW.exe were not then passed along to my VI, I was hoping they would be. A launcher would work, you could then write to a temporary path, or the ProgramData folder, and your VI could then open it. I wish there was more documentation on the behavior of LabVIEW.exe when it comes to command line arguments, it might be possible to do what you want but I'm not aware of any other simple solution.
  20. Not really. I mean turning VI source code into a compiled piece of binary, is the responsibility of the compiler. In a built EXE, there is no compiler, this is in the LabVIEW IDE only. So when you look at a VI file that has separate compiled code, the compiled binary is saved in a temp location that I can't remember at the moment, but I suspect it is in ProgramData or AppData somewhere. If this tools needs compiled code to execute, and you don't have it in the VI file, and you are running from the run-time engine, then you have no way of using this tool. But if this tool can run from the LabVIEW IDE I think you should be fine. You can still invoke a VI to run programatically from a command line, and get functionality that looks like a built EXE, but runs from the IDE. LabVIEW.exe supports a command line parameter, which it will attempt to open as if you did a File >> Open. If this file is a VI, and it is set to run when opened then this might be a solution for you.
  21. The TDMS use is the only one I can think of too. Basically if we have data on an FPGA and we want to log it into a TDMS file on the host side, then the old method would be to transfer using a FIFO over from the FPGA to the host (making the data in two places), then write it to a TDMS file. The DAQmx VIs have the ability to log directly from hardware to disk. So this means instead of reading an AI from the hardware (which makes a copy) we can log directly from the DMA of the hardware, and log it to disk. This FPGA external DVR is apparently the same thing. Log directly from the memory on the FPGA to disk, without making copies, without extra data transfer, and reducing that load from host operations. Personally I've never done this but it is a neat concept if you have lots of FPGA data and just want to log it, of course in practice I think I'd want to do more than just log it.
  22. It sorta is dynamic. Actors can unregister or register to new events at run-time, but in practice is never really needs to. And the messaging structure is based on user events, and you can't register for an array of user events, unless each of the data types of each event are the same, which is where I used the variant as the data type. Also there are times when I might only want some information from the variant, and I don't pull out all of the payload, something like meta data instead, and I believe this is most efficient with a variant attribute, where you don't have to read everything.
  23. Yeah I have other issues with the CVT, like performance. And when writing a messaging library that is uses a wrapper constantly for variant data, I wanted it to be light weight, and generally I didn't find a wrapper for a look up table that wasn't better when it comes to performance than Variant Attributes.
  24. Well think of running your VI, similar to running a program for the first time, then closing it after the VI is done. So when you open up a new copy of Word, how does it know what your recent documents were? Well it can't just keep it in memory, because it is a new execution, unless it writes some data to a place on disk that will be maintained between runs. But a more simple way to accomplish this, is instead of using the Run button to do a new calculation, which again will run once, then stop, similar to running a program and exiting it, you can instead wrap the whole VI in a while loop, so the program keeps running until you tell it to exit. This is basic application design in LabVIEW, and while there are some work arounds, like reading and writing to local variables between runs, this design is not the appropriate method.
  25. Listen noob... Oh...let me start again... What is your problem? Because reading your post it doesn't seem like you have any question. You state you have an array of numbers, and you are indexing each one, one at at time. Each element goes into a case statement, and then one of N things happen, based on the value of the that indexed value. So what isn't working? Your title doesn't reflect your post. You are asking about holding a value in the title but not in the code. One thing you might be asking is why is your output only one value? What I mean by that, is you give it 8, 5, and 4, but your output only shows a value for 4. The reason for this is because your loop runs 3 times as it should (by the way you don't need the array size and wiring to the N terminal, that is only needed if no arrays are indexed) But even if your loop runs 100 times, the output of the loop is always going to be the values returned from the last run, and that is because your outputs (the booleans) are scalars, not arrays, and the output tunnel is not being indexed. If you want every boolean value returned, right click the output tunnel and enable indexing. But now you have N booleans being returned but you can only display one (since your boolean on the front panel is just a single boolean) so what you might want is to add an Or Array Elements, which takes an array of booleans, and if one or more are true, then it returns a scalar true. There are of course easier ways of producing this same output. Like the attached code which does the same thing, but in a more scaleible way. You probably have seen these links before but here is some free LabVIEW training links if you have some fee time you should check them out, especially the introduction videos. NI Learning Center NI Getting Started -Hardware Basics -MyRIO Project Essentials Guide (lots of good simple circuits with links to youtube demonstrations) -LabVEW Basics -DAQ Application Tutorials -cRIO Developer's Guide Learn NI Training Resource Videos 3 Hour LabVIEW Introduction 6 Hour LabVIEW Introduction Self Paced training for students Self Paced training beginner to advanced, SSP Required LabVIEW Wiki on Training
×
×
  • Create New...

Important Information

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