Trying to learn OOP, overkill?

somlioy
2018-02-28
2018-03-07
  • somlioy - 2018-02-28

    Thought I'd try using OOP with a system I'm making, more specific control of navigation lights for ships.
    Every lit the same way, has feedback wether current is running when enabled (to check for open circuit), a set of customizeable presets (different combinations).

    Is it overkill to use oop for such simple system or is it "ideal"? In that case could anyone point me in the right direction for how to divide each required component?

     
  • somlioy - 2018-03-01

    Ok som more questions theyn.

    Let's say I've initiated a couple of navigation lights in a "light manager";

    VAR
       sb, port, aft, fwd, towFwd, towAft      : fbNaviLight;
    END_VAR
    

    What's the best way of turning them on from a preset? Similary disabling them all?

    I tried declaring them in an array then looping the array and that works, but it seems a bit cumbersome having to declare a light twice? And also the need of updating numOfLights.

    VAR
       numOfLights : INT := 6;
       sb, port, aft, fwd, towFwd, towAft : fbNaviLight;
       naviLights : ARRAY [1..numOfLights] OF iNaviLight := [sb, port, aft, fwd, towFwd, towAft];
    END_VAR
    IF disableAll THEN
       FOR i := 1 TO numOfLights DO
          naviLights[i].setLight(0);
       END_FOR
       disableAll := FALSE;
    END_IF
    
     
  • dFx

    dFx - 2018-03-01

    To me there is no better case to use OOP. Every system is acting in a same way ...

    I would use it this way :

    // Déclarations
    naviLights : ARRAY [1..numOfLights] OF fbNaviLight;
    // Code
    // Inputs
    naviLights[1].LigthAsk := %IX0.0;
    naviLights[2].LigthAsk := %IX0.1;
    naviLights[3].LigthAsk := %IX0.2;
    // Call of every FB
    FOR i := 1 TO numOfLights DO
          naviLights[i](DisableAll:=disableAll);
    END_FOR
    DisableAll := FALSE;
    // Outputs
    %QX0.0 := naviLights[1].LigthOut;
    %QX0.1 := naviLights[2].LigthOut;
    %QX0.2 := naviLights[3].LigthOut;
    

    FB code

    IF DisableAll THEN
       LigthOut := FALSE;
    ELSE
       LigthOut := LigthAsk;
    END_IF
    

    Your FB will have the duty to manage a ligth, and how it is light up.
    This ensure consistency along your program.
    But as I/Os are independant, it is generally managed via FB I/Os, in a manner that you must affect it one by one.

    you may also declare your I/Os directly as naviLights[i].LigthAsk and naviLights[i].LigthOut

    Regards,
    dFx

     

    Related

    Talk.ru: 1
    Talk.ru: 2
    Talk.ru: 3

  • somlioy - 2018-03-02

    dFx hat geschrieben:
    To me there is no better case to use OOP. Every system is acting in a same way ...

    Do you mean OOP is waste of time?

    Also how do I take care of input and outputs in relations to this? As in where do I define them and where do I enable them?

    What about methods and properties? When to use either of them.

     
  • Anonymous - 2018-03-03

    Originally created by: scott_cunningham

    CoDeSys gave a good example similar to your question. See these two CoDeSys store links:

    https://store.codesys.com/object-orient ... re=default

    https://store.codesys.com/object-orient ... __store=en

    OOP has many merits, but to some in the Automation world, the name and concept is dismissed. I have found that you can use many OOP concepts very nicely in CoDeSys. The ironic part, is the people that dismiss OOP are already using it when they use a function block!

     
  • somlioy - 2018-03-05

    Thanks, I'll check those out.

    What would be the best way to make lights and presets persisten/retain when working with OOP?

     
  • Anonymous - 2018-03-05

    Originally created by: scott_cunningham

    If you want persistence, be a bit careful. If you define a variable inside of your FB as persistent, the whole FB will go into persistence memory. If your FBs are large or you have a lot of FBs or you have a very small amount of persistent memory, you will have a problem. In that case, create a method you call to pass an external persistent variable’s address to a local pointer or use REFERENCE TO (my recommendation). Instead of a method you can also use FB_INIT and force a reference link on instantiation. But I would start the simple way and let your whole FB go into persistence and worry about running out of memory if it actually happens.

    Also be aware that some hardware platforms do not support persistence (Rasp Pi for example).

     
  • somlioy - 2018-03-06

    I'm using Wagos PFC200 PLC.

    I tried declaring my function-blocks as persistent retain in declaration;

    VAR PERSISTENT RETAIN
       sb, port, aft, fwd, towFwd, towAft      : fbNaviLight;
    END_VAR
    

    But then I get a warning:

    Zitat:
    C0244: No VAR_PERSISTENT-list is part of the application to enter instance path for variable naviLightManager.sb

    What's causing this.

     
  • Anonymous - 2018-03-07

    Originally created by: scott_cunningham

    You should define your variables inside the FB as persistent retain, not the FB itself. I only mentioned that for compiler reasons, the whole FB will use retain space...

    Program

    Var
    Light1, Light2 : MyLightControl;
    End var

    If Sunrise then
    Light1.TurnOff();
    Light2.TurnOff();
    End if
    ....

    If Light1.Service() then
    ....

    Function block MyLightControl
    Var
    Temp : bool;
    //other vars that don’t need memory
    End var

    Var persistent retain
    LightIsOn : bool;
    HoursOn : DWORD;
    End var

     
  • Anonymous - 2018-03-07

    Originally created by: AntonZ

    If you want to use persistance anyway without making everything inside the function block persistent:

     

Log in to post a comment.