| 

.NET C# Java Javascript Exception

5
While the notion of inheritance is used readily and frequently, interfaces are rather rarely applied. However, interfaces provide a number of benefits, which increase flexibility of the PLC programs and improve maintenance. The following post will introduce the possibilities of interfaces relating to the IEC 61131-3 standard. Inheritance appears to be the best known concept […]

While the notion of inheritance is used readily and frequently, interfaces are rather rarely applied. However, interfaces provide a number of benefits, which increase flexibility of the PLC programs and improve maintenance. The following post will introduce the possibilities of interfaces relating to the IEC 61131-3 standard.

Inheritance appears to be the best known concept of the object-oriented programming. This is certainly because most textbooks cover it as the first topic and in this way put emphasis on it. Objects from the real world are readily represented as classes, which depict an “is-a” relationship in this manner. A dog is a mammal; a mammal is a living organism. Thus, a human or a spider can be mapped fairly simply.

FUNCTION_BLOCK PUBLIC FB_LivingOrganism
FUNCTION_BLOCK PUBLIC FB_Mammal EXTENDS FB_LivingOrganism
FUNCTION_BLOCK PUBLIC FB_Dog EXTENDS FB_Mammal
FUNCTION_BLOCK PUBLIC FB_Human EXTENDS FB_Mammal
FUNCTION_BLOCK PUBLIC FB_Insect EXTENDS FB_LivingOrganism
FUNCTION_BLOCK PUBLIC FB_Spider EXTENDS FB_Insect

Representation as a UML class diagram:

Since the term class is more common in object-oriented programming, it is preferred to the term function block in the following.

Inheritance

If one deals with the concept of object-oriented programming, one would notice that inheritance is its best known feature. It allows an easy definition of new classes (subclasses), which are derived from the existing classes (base classes). A subclass inherits all properties, methods, actions, inputs and outputs of the base class. They should be reprogrammed only if their inherited functionalities have to be extended or changed.

While actions, inputs and outputs are always inherited to the subclasses, inheritance of properties and methods can be influenced by the keywords PUBLIC, PROTECTED, INTERNAL and PRIVATE. In the case of defining a function block, creating subclasses, i.e. possibilities of inheritance can also be constrained (PUBLIC, INTERNAL, and FINAL).

However, inheritance brings along with it several disadvantages:

Changes of base classes can affect the subclasses, which inherit from it. Subclasses and base classes are closely coupled to one another.
If base classes and subclasses are in one PLC library, the inheritance hierarchy of these blocks can not be changed by the user of the PLC library.
The IEC 61131-3 standard does not allow, as well as Java and C# multiple inheritance. A subclass always has a base class. Thus, it would be no longer simply be possible to create a function block for Spiderman with the abovementioned class hierarchy. Inheritance from FB_Human and(!) FB_Spider is not possible.
Subclasses are always dependent on their base classes. This can make it difficult to reuse a subclass.

NB:

Base classes mutate easily to a “melting pot” of methods and properties, which are required in one or the other subclass. Such “super base classes” get eventually difficult to maintain. Therefore, I try to keep base classes as small as possible. The deeper you are in the inheritance hierarchy, the smaller the classes should be. Likewise, I try to keep the number of inheritance levels small. The maximal value of 6 for the depth of inheritance can serve here as a benchmark.

Interfaces

Interfaces deal with definition of methods and properties, which are implemented in one class. The classes that implement the same interface look identical from outside and can be treated equally. The exact implementation of the required methods and properties is not described by the interface. Each class, which implements the interface, can determine the internal structure itself.

Example:

The interface I_Sample contains the method M_DoFoo() with a return value of type BYTE.

INTERFACE I_Sample
METHOD M_DoFoo : BYTE

Two function blocks implement the interface.

FUNCTION_BLOCK PUBLIC FB_A IMPLEMENTS I_Sample
METHOD M_DoFoo : BYTE
M_DoFoo := 100;
RETURN;
 
FUNCTION_BLOCK PUBLIC FB_B IMPLEMENTS I_Sample
METHOD M_DoFoo : BYTE
M_DoFoo := 200;
RETURN;

Both function blocks have no other binding except the common interface. Nevertheless, both of them can be equally treated.

PROGRAM MAIN
VAR
 aTest : ARRAY [1..2] OF I_Sample;
 fbA : FB_A;
 fbB : FB_B;
 a : INT;
 nIndex : INT;
END_VAR
 
aTest[1] := fbA;
aTest[2] := fbB;
FOR nIndex := 1 TO 2 DO
 a := aTest[nIndex].M_DoFoo();
END_FOR

The method M_DoFoo() of the function block FB_A is accessed in the first loop pass, the method M_DoFoo of FB_B is accessed in the second loop pass. The implementation of the methods is determined individually in each function block (FB_A and FB_B).

While inheritance is a “is-a” relationship, interfaces can be described as “behaves-as” relationship or “has-a” relationship.

This kind of binding reduces dependencies considerably. Thus, the FOR loop (line 12 … 14) deals with the interface I_Sample all along. The loop works against the interface I_Sample and not against a specific implementation. The function blocks FB_A and FB_B could always be exchanged for other function blocks, as long as these implement the interface I_Sample. There would be no need in any adjustment of a FOR loop.

Since an interface represents a data type, it can be transferred through the inputs or parameters of the methods to the function blocks. The function block calls the methods of the interfaces without concrete knowledge of executed functionality (polymorphism).

Object composition

One function block can implement several interfaces. As a result, functionalities which are defined by interfaces can be combined in one function block. The class hierarchy stays very flat and the dependencies of the function blocks among themselves are minimal. By means of splitting a single assignment into several smaller, there exists no danger of covering all imaginable features in one super base class.

Example:

A PLC library makes the interfaces I_Light, I_Delayable and I_Dimmable available. Each interface has a corresponding implementation (FB_Light, FB_DelayedLight and FB_DimmingLight), which are also located in a PLC library.

InterfacesFunction blocks, with the implemented interfaces

FB_DelayedLight and FB_DimmingLight inherit from FB_Light. FB_Light contains the methods M_On() and M_Off(), as well as the property bControlLevel. This function block serves as a base class, because this base functionality is precisely equal for all function blocks.

Representation as a UML class diagram:

Statement of task:

On the basis of this PLC library, a programmer has to draft a function block, which contains functionalities of both FB_DelayedLight and FB_DimmingLight.

It would be appropriate to use the interfaces I_Delayable and I_Dimmable. The function block FB_Light can also be used as a base class. This brings along the advantage, that wherever I_Delayable, I_Dimmable and FB_Light are applied, their own block can also be replaced. There is a small example further on.

FUNCTION_BLOCK FB_MyLight EXTENDS FB_Light IMPLEMENTS I_Delayable, I_Dimmable

Thus, the function block has the following methods and properties:

Tip:

The already existing function blocks can be used, so that the methods do not have to be entirely reprogrammed. For this, I have created instances of both FB_DimmingLight and FB_DelayedLight.

VAR
 fbDimmingLight : FB_DimmingLight;
 fbDelayedLight : FB_DelayedLight;
END_VAR

I redirect the invocations to these instances in the respective methods:

METHOD M_SetControlLevel
VAR_INPUT
 nControlLevel: BYTE;
END_VAR
 
fbDimmingLight.M_SetControlLevel(nControlLevel);
IF (nControlLevel = 0) THEN
 fbDelayedLight.M_Off();
ELSE
 fbDelayedLight.M_On();
END_IF

Thus, the logic for dimming or switching on/off does not have to be developed for the second time.

Representation in CFC:

Methods and properties can not be directly graphically represented with the IEC 61131-3 standard. But if it is possible, a corresponding input or output can be created for each method and for each property. Changes in the inputs are forwarded to the respective methods and the states from the properties are assigned to the outputs.

FUNCTION_BLOCK FB_MyLight EXTENDS FB_Light IMPLEMENTS I_Delayable, I_Dimmable
VAR_INPUT
 bRecallMinLevel : BOOL;
 bSetControlLevel : BOOL;
 nSetControlLevel : BYTE;
END_VAR
VAR_OUTPUT
 nControl : BYTE;
END_VAR
VAR
 rtrigRecallMinLevel : R_TRIG;
 rtrigSetControlLevel : R_TRIG;
 fbDimmingLight : FB_DimmingLight;
 fbDelayedLight : FB_DelayedLight;
 _nControlLevel : BYTE;
END_VAR
 
rtrigOn(CLK := bOn);
IF (rtrigOn.Q) THEN
 M_On();
END_IF
 
rtrigOff(CLK := bOff);
IF (rtrigOff.Q) THEN
 M_Off();
END_IF
 
rtrigRecallMinLevel(CLK := bRecallMinLevel);
IF (rtrigRecallMinLevel.Q) THEN
 M_RecallMinLevel();
END_IF
 
rtrigSetControlLevel(CLK := bSetControlLevel);
IF (rtrigSetControlLevel.Q) THEN
 M_SetControlLevel(nSetControlLevel);
END_IF
 
fbDimmingLight();
fbDelayedLight();
_bControlLevel := fbDelayedLight.bControlLevel;
IF (_bControlLevel) THEN
 _nControlLevel := fbDimmingLight.nControlLevel;
ELSE
 _nControlLevel := 0; 
END_IF
 
bControl := bControlLevel;
nControl := nControlLevel;

Thus, the block can be easily used in CFC or the like:

Request of an interface at runtime

Instances of function blocks can be forwarded to other function blocks as parameters. The function block has therefore unlimited access to all methods, properties, and inputs and outputs of the forwarded block.

Example:

A PLC library has to be extended by a function block, which groups three lighting blocks together. All three blocks can be controlled by the inputs. Thus, all lights should be switched on or off by bAllOn and bAllOff. The input bAllCallMinLevel has to affect only the blocks, which implement the interface I_Dimmable. The control variables are read out through the outputs.

FUNCTION_BLOCK PUBLIC FB_RoomController
VAR_INPUT
 bAllOn : BOOL;
 bAllOff : BOOL;
 bAllCallMinLevel : BOOL;
 refLight01 : REFERENCE TO FB_Light;
 refLight02 : REFERENCE TO FB_Light;
 refLight03 : REFERENCE TO FB_Light;
END_VAR
VAR_OUTPUT
 aControlLevel : ARRAY [1..3] OF BOOL;
 aDimmLevel : ARRAY [1..3] OF BYTE;
END_VAR

It should be possible to forward all variants of the lighting blocks to the block. For this reason, FB_Light is used as a data type of the three lighting blocks. In this way, each block derived from FB_Light can be transferred at the inputs.

VAR
 fbRoomController : FB_RoomController;
 fbLight : FB_Light;
 fbDelayedLight : FB_DelayedLight;
 fbDimmingLight : FB_DimmingLight;
END_VAR

The inputs bAllOn and bAllOff are therefore easily reassembled. If a positive edge is detected at input, the reference of the corresponding method is invoked. It has to be controlled before the invocation, whether the reference is valid.

IF (__ISVALIDREF(refLight01)) THEN
 refLight01.M_On();
END_IF
IF (__ISVALIDREF(refLight02)) THEN
 refLight02.M_On();
END_IF
IF (__ISVALIDREF(refLight03)) THEN
 refLight03.M_On();
END_IF

But how can the method M_RecallMinLevel() be called, if there exists a function block, which implemented the interface I_Dimmable? After all, the data type of the input is FB_Light, and it does not know the method M_RecallMinLevel().

The function _QUERYINTERFACE() enables type conversion from one interface reference to the other. If the conversion is successful, the function returns TRUE, and the second parameter contains a reference to the requested interface.

iLight : I_Light;
iDimmableLight : I_Dimmable;
 
IF (__ISVALIDREF(refLight01)) THEN
 iLight := refLight01;
 IF (__QUERYINTERFACE(iLight, iDimmableLight)) THEN
 iDimmableLight.M_RecallMinLevel();
 END_IF
END_IF

Thus, the implementation of an interface can be queried at runtime and afterwards can also be used.

Since the block FB_MyLight is derived from FB_Light, it can be used with FB_RoomController without adaptation. Furthermore, the method FB_RecallMinLevel() is called from FB_MyLight, because it implements the interface I_Dimmable.

Sample (TwinCAT 3.1)

Advantages

The block FB_RoomController makes it not only possible to use the blocks from the PLC library (FB_Light, FB_DimmingLight and FB_DelayedLight), but also to forward directly its own blocks derived from FB_Light. If such function blocks implement the interface I_Dimmable, FB_RoomController can access the method M_RecallMinLevel() without knowing the exact type of the lighting block. The mere fact, that I_Dimmable is implemented, is sufficient. In this case, FB_RoomController and the lighting blocks communicate through the interface I_Dimmable.

So far, this problem could be solved with a communication structure. All lighting blocks and FB_RoomController would have as an input/output variable a structure, through which the blocks communicate with each other. But this variant has a disadvantage: what if the block FB_RoomController should be extended? Managing of scenes could serve as an example. Each lighting block has 10 scenes, which should be callable with the help of FB_RoomController. In the previous variant, FB_RoomController had to obtain other communication structures for the management of scenes, or the existing communication structure had to be extended. In both cases, FB_RoomController had to be adapted in such a way that it would be incompatible to the previous one. Development of a completely new blocks (e.g., FB_RoomControllerV2) could be one more option.

Defining a new interface (e.g., I_SceneManager) is more flexible. This interface determined the methods and the properties, which are necessary for the invocation of the respective scenes. If a lighting block has implemented this interface, FB_RoomController can invoke the requested scene. Extensions or adaptations of the existing inputs and outputs of FB_RoomController are not necessary; the block stays downward compatible.

Conclusion

Since inheritance is easy to apply, there is a great temptation to create base classes, which contain all possible functionalities. These functionalities are actually required from only one or the other subclass. After several extension cycles, dependencies arise, which are difficult to maintain. Interfaces give the opportunity to specify a particular task. These interfaces can be accessed during the development of a new function block without applying complex inheritance hierarchies.


iec-61131-3 oop twincat codesys-v3 plc interfaces inheritance
1 Meinung
0
Play run 23 and get fun actually this one is the best place to know better about the online craze fun run 3 so please play it and share the information.
Schreibe einen Kommentar:
Themen:
inheritance interfaces plc codesys-v3 twincat oop iec-61131-3
Entweder einloggen... ...oder ohne Wartezeit registrieren
Benutzername
Passwort
Passwort wiederholen
E-Mail