Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/11/2016 in all areas

  1. 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.
    2 points
  2. I found the root cause of the problem. I had an LLB file that contained a VI with an invalid character in the file name. LabVIEW would compile the VIs, but at the end of the compilation process, the files are copied into a folder named for your .exe. The invalid Windows file name could not be created, but the error message never contained the name of the file. I sent the LLB to NI and declared that I think this is a bug. I found it by converting all of my LLBs to folders using the LLB Manager. When I got to the problem LLB, the conversion reported an error on the badly named file. I copied the LLB, deleted the offending file, converted the copied LLB to a folder without error. I manually saved the offending VI as a file into the folder without an error. Then I could compile. I've had bad experiences in the past when I use "Save As" into an LLB to create a new VI. The "Save As" dialog is not a standard dialog and can act wierd when you use the control keys to move about within the name box. I might have somehow inserted a TAB or control character that LabVIEW was willing to accept as a VI name inside an LLB. LabVIEW just didn't know how to fix the name when saving it outside the LLB. I spent over a week screwing around with creating new projects, mass compiling and re-installing LabVIEW because of this. I know that many people will say "don't use LLBs", but this is the first time I have been bit by them in such a bad way.
    1 point
  3. Yes, that's the one I was referring to. Specifically, the part that relates: This issue can be caused because some third party devices do not implement all serial settings on their USB-Serial adapters. To avoid the problem, do not use the VISA Configure Serial Port VI in your program. Instead use a VISA property node to set only the supported properties. To determine which properties are unsupported by your USB-Serial adapter, use a VISA property node, and set the properties one at a time to see which properties cause the I/O error to be thrown. The error message is all about serial. I looked in the Modbus serial init and saw all the properties being set. Try just setting one at a time to see what is throwing the error.
    1 point
  4. Ah RT, gotcha. You COULD pass on a display OBJECT instead of an actual subpanel reference (Abstract base with no action / data) with a DD "display" method and only provide a child of this with actual subpanel functionality for non-RT code. That way you retain encapsulation and provide extensibility but it IS more work. this transfers to a NOP on RT and can be modified as required if future code changes are needed.
    1 point
×
×
  • Create New...

Important Information

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