Jump to content

MikaelH

Members
  • Posts

    835
  • Joined

  • Last visited

  • Days Won

    49

Posts posted by MikaelH

  1. post-941-12592272902_thumb.png

    Singleton or not…

    I often use Singleton classes, it might be because I’m lazy wiring the class wire through all my application.

    Here is a brief description of why I use singletons.

    This is how my standard implementation of my manufacturing rigs looks like.

    I use a top level VI, and some singleton classes and a bunch of instrument driver classes.

    Let’s look at the current rig I’m working on.

    This rig should:

    1. Place, align and glue 3 optical components on the DUT.

    2. Every component is held by a motorized stage with 4-5 axis.

    3. Every stage has about 7-10 additional digital IOs

    4. There is an over all vision system with 2 cameras with different lighting controls.

    5. There is an additional optical measurement system I’m using for alignment.

    In total it’s about 50 IOs in the system from simple position sensors, pneumatic values to 13 motorized stages, cameras, glue dispense systems and other more advanced measurement system.

    So where should I start when implementing a large system like this?

    I start by looking at the system from an operator’s perspective, what can I see?

    I see 3 separate motor stages.

    I see a camera and lighting arm, holding 2 cameras and some lamps.

    So I decide to create 3 classes, one for every motor stage, this is because they look completely different and hold different components.

    I name the classes after what component they are holding.

    So one stage will be called “Mirror”-class, and I choose to use a singleton class here.

    So why do I use a singleton class?

    I know that I will only use one of these objects in my application, but the main reason is that I don’t want to clutter the block diagram of my Main VI, that is going to use this object ;-)

    This “Mirror”-class will aggregate all instrument objects it needs, e.g. 4 motion control motors.

    This class will encapsulate all functions I might need to perform on the Mirror component.

    I will have a public method (a method that my main VI will call) named “Pick up and place mirror at initial location”, and also one called “Cure Mirror Glue”.

    These methods will be a bit abstract and I let the method figure out how to perform these actions.

    That way I get a good abstraction level, and it’s easy to follow the application flow in my Main VI.

    I never allow my main VI to access the instruments direct, so I’m forced to go through an abstraction layer.

    By using this approach, I can break down the complex system into smaller solvable parts, in my case I use classes.

    And for this project I use only singleton classes in my application component layer that abstracts the driver layer from the main VI.

    post-941-12592273265_thumb.png

    Cheers,

    Mikael

  2. Hi

    I'm a GDS fan (no wounder biggrin.gif ), so I just right click in the Project Tree amd selectes New->GOOP Class (Using The Endevo's Reference based provider).

    Then I just select a singelton class type, it's so easy :-)

    post-941-125918066954_thumb.png

    post-941-125918074263_thumb.png

    ..one advantage I like about this template (or any GDS class templates) is that if there is a new version of the class template I've used, the GDS toolkit can automatically update the class to the new template.

    Cheers,

    Mikael

  3. Hi

    We use a central MSSQL production database, where we have all software listed, plus a change log what have been changed between all versions.

    So every time the application starts up it check if it's Software Part Number and revisi0n is the latest one, if not it displays all changes between the versions and gives the user an option to upgrade.

    If they decide to upgrade I start another LabVIEW exe-file located on the network (instead of using a batch file) and closes the current application.

    The Upgrade application, takes a copy of the current version and stores it locally in an OldVersions-folder, and then download the next version (using the database as a reference).

    When it's copied the application in place it starts it up. It also gives the user an option to revert back to the old version if the new version has some problems.

    To get this working smooth fully, we have a Configuration Management tool (simple LV app), to help out with creating new versions in the database and upload, commit and tag every release.

    Cheers,

    Mikael

    • Like 1
  4. Do you have a preference between the two? I just installed Eventum, but I like Fogbugz.

    My favorite is FogBugz, because it's faster and have some extra fun features.

    But Eventum has what's needed for a bug tracking system, but our version is a bit slow compared to FogBugz.

    //Mike

  5. Hi

    I’m a bit puzzled about NI's Motion Control Driver VIs and maybe someone can answer this question.

    - The In and out of the Board ID /Handle has a coercion dot.

    - That is because they are of 2 different type defs.

    - My question is why aren’t they of the same type def?????

    post-941-125712332661_thumb.png

    Cheers,

    Mikael

  6. I on the other hand would not even consider a reference solution unless all else failed.

    I agree that by value should be used where ever it’s applicable.

    By most of my classes are instrument drivers and there I can’t live without references.

    Some other classes are Singletons and others uses shared aggregation, and therefore it makes my life easier to use one type for all of them, because if I forget that a particular class is by value I get really strange errors ;-)

    This is an example of the different looks and feels when using composite aggregation.

    post-941-125503884051_thumb.png

    post-941-125503883373_thumb.png

    ByRefByValue.zip

    Cheers,

    Mikael

  7. So replacing the string property node with a local variable seems to me the better solution.

    Sure it's one solution, but assume that I use the local variable for the Tab Control and use a local variable for the string.

    And then suddenly we need to update this code to also gray out the string control, so I change it to a property node to disable the control and at the same time I use the same property node to update the value of the string control.

    But of cause I now know about this problem so I have to change the updating of the tab to a property node.

    But I have 5 LV developers in my team and I can't do all updates myself so maybe the developer I assign this task to might not remember this.

    Cheers,

    Mikael

  8. I like the property node since they have Error in/Out that makes the me in control of the flow.

    But the property nodes are slow.

    post-941-125410476666_thumb.png

    This code takes around 8 ms, but if you change it to the property node it takes 10 seconds.

    That is because the control works in Synchronous mode.

    You get the same time if you set the control to "Synchronous Display" but still uses a local variable.

    So my conclusion is to always use the Property Node when updating a Tab control.

    Cheers,

    Mikael

  9. Hi GDS users

    The last release has a bug that we missed in the testing phase of GDS.

    I’ve attached the file that you need to replace in the GDS folder.

    GOOP_CheckClassState.vi

    This file is saved in 8.5 and needs to be saved to your current version of LabVIEW.

    Step 1: Remove the Read-Only flag of the file “EndevoProvider.llb” in the folder:

    C:\Program Files\National Instruments\LabVIEW <Version>\resource\Framework\Providers\Endevo

    Step 2: Open the new file “GOOP_CheckClassState.vi”, and save it into the llb: EndevoProvider.llb, replacing the old one.

    Step 3: Restart LabVIEW.

    Sorry for the inconvenience.

    ------------------------ Edits---------------------

    Just created a new release candidate for GDS that has this fix.

    http://goop.endevo.net/GDS/GDS_P8P_85.zip

    http://goop.endevo.net/GDS/GDS_P8P_86.zip

    http://goop.endevo.net/GDS/GDS_P8P_2009.zip

    Cheers,

    Mikael

  10. Hi

    I suggest a database, a fast one :)

    The table has to be optimized for high speed inserts and queries/searches.

    When I get data from a table to show a plot and it contains huge number of values, I let the database do some decimation of the data, i.e. Take the first 1000 values and convert it to 1 value, the next 1000 values will be value 2. For this decimate function I have 3 options (Max, Avg, Min) the database uses when converting 1000 values to 1.

    Also every night you can let the database create records in an aggregation table that contains some pre-calibrated values and is optimized for queries only.

    Use this table when the user doesn’t need live data.

    Another thing, I always save the raw data as well in the database in a Special table and then let the database do the Math to “Calibrate” the raw data to the real value that is stored in a separate table.

    This approach is good if you want traceability. E.g. After a sensor gets recalibrated, and you noticed that it has been using the wrong calibration constants. In that case you can just recalculate the old data so it becomes correct.

    Cheers,

    Mikael

  11. I better report it so we might get it fixed until next NI-week :-)

    I've always got my code working with some workarounds.

    One way is to use the Property Node of the Tab Control when changing the value.

    Sometimes I use a SubVI to change the Tab like this:

    post-941-125383273245_thumb.png

    This also saves some Block Diagram Space.

    But then I have to make sure the Tab is a Type Def and that can create some other issues.

    Cheers,

    Mikael

  12. Hi

    I guess many of you have encountered this issue with the tab control.

    Is this a bug or something everybody knows about and always just manage to live with it.

    The problem is that the Tab Control don’t always changes Tab when you programmatically changes is using a local variable, if you at the same time updates a control or indicator using the property node which is located on any of the tabs.

    Why??

    (LV 8.6)

    //Mikael

    TabTest.vi

×
×
  • Create New...

Important Information

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