Casting function block

577 views Asked by At

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?

1

There are 1 answers

5
Guiorgy On BEST ANSWER

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