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?
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