1

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?

Dawid Rutkowski
  • 2,658
  • 1
  • 29
  • 36

1 Answers1

2

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

Guiorgy
  • 1,405
  • 9
  • 26
  • Thanks! I was not aware that CODESYS always treats variables declared with the type of interface as references. – Dawid Rutkowski Apr 26 '21 at 19:19
  • Was in your shooes a while ago. The [codesys documentation](https://help.codesys.com/webapp/_cds_obj_interface;product=codesys;version=3.5.16.0) is your friend is such times ;) – Guiorgy Apr 26 '21 at 19:24
  • I'm programming for 15 years but I'm just starting with the PLC programming :) I'm automating my home using PFC200. Do you have some experience with OSCAT Building ligrary? – Dawid Rutkowski Apr 26 '21 at 21:14
  • I think I found one more option - usage of `__QUERYINTERFACE`. https://help.codesys.com/webapp/_cds_operator_queryinterface;product=codesys;version=3.5.16.0 – Dawid Rutkowski Apr 27 '21 at 06:10
  • 1
    Unfortunatly no, I have no expirience with OSCAT Building, as I work in the industrial water plant automation. Also, we have looked at OSCAT basic, but in the end decided to write our own libraries for anything we need. As for `__QUERYINTERFACE` it does `"type conversion of an interface reference into another type"`, I don't think this iswhat you were looking for. And unless you have hundreeds of interfaces, imo having a dedicated method for conversion is easier to read and debug. – Guiorgy Apr 27 '21 at 10:19