Search code examples
plccodesyswagopfc200

Casting function block


I'm using Wago PFC200 for my home automation. I got base function block:

FUNCTION_BLOCK ABSTRACT Room

and two the interface:

INTERFACE IBlinds
- BlindsUp
- BlindsDown 

and

ILights
-TurnOffLights
-TurnOnLights

My room's instances looks like this:

FUNCTION_BLOCK Garage EXTENDS Room IMPLEMENTS ILights, IBlinds

In my PLC_PRG I've all instances of my rooms:

PROGRAM PLC_PRG
VAR
    Bedroom: Bedroom;
    Garage: Garage; 
    Hall: Hall;
    Boilerroom: Boilerroom;
    ...
END_VAR

Under the PLC_PRG I've some methods to e.g.: automate blids:

METHOD MoveBlindsToMorningPosition
VAR CONSTANT
    siCount: SINT := 5;
END_VAR
VAR_INPUT
    xMoveSignal: BOOL;
END_VAR
VAR
    _siIndex: SINT;
    _rooms: ARRAY[0..siCount] OF POINTER TO IBlinds := [ADR(Livingroom), ADR(Diningroom), ADR(Kitchen), ADR(Toilet), ADR(Boilerroom), ADR(Garage)];
END_VAR

FOR _siIndex := 0 TO siCount DO
    _rooms[_siIndex]^.MoveBlindsToMorningPosition(xMove := xMoveSignal);
END_FOR

But I got the following compilation errors in the _rooms array: C0032: Cannot convert type 'POINTER TO Garage' to type 'POINTER TO IBlinds'

My function blocks actually implement IBlinds. Is there a way to cast function block?


Solution

  • First of all, an interface is already a reference to a function block:

    CODESYS always treats variables declared with the type of an interface as references.

    So there shouldn't be a need to use pointers.

    Secondly, to cast an function block into an interface, personally I'd recommend using a dedicated method inside a function block. For example:

    INTERFACE inter1
    - ...
    - ToInter1
    
    INTERFACE inter2
    - ...
    - ToInter2
    

    and implement them inside MyObject like:

    ToInter1 := THIS^;
    
    ToInter2 := THIS^;
    

    And then you can:

    myObj: MyObject;
    i1: inter1 := myObj.ToInter1();
    i2: inter2 := myObj.ToInter2();
    

    Or

    arr: ARRAY[x..y] OF inter1;
    arr[z] := myObj.ToInter1();
    

    At least this is what I do to solve this