Join us today!
A few difficulties while learning OOP
Hi,
I have a few problems that I ran into while learning Object Oriented PLC Programming:
- no possibility to use temporary variables in Method and Properties. For example: I call the RunConveyor method in which I assign TRUE to some %Q variable. Then I stop calling this method. I would like the output variable %Q to be FALSE then. A temporary dirty solution is resetting the VAR (%Q) variable in the implementation part of the FB or using the StopConveyor method (which I don't like),
- separation of automatic and manual control in Function Blocks of devices (FB_Motor, FB_Pump, FB_Valve etc.). Is there any nice solution for this? Example: block automatic control when bManual = TRUE. It's been a while since I tried to solve this problem and I know a bit more about OOP now, so I'll probably try something like using interfaces: I_ManualControl, I_AutoControl, I_Control and code like: If bManual Then I_Control := I_ManualControl (...),
- how to write code to work with two types of HMI / SCADA: those that support method and properties and those that do not? [universal code],
- writing code for critical logic in OOP - example: interlocks (protection against collisions etc.), additional safety logic in PLC (resetting outputs), (...). My temporary, dirty solution is to work with local variables -> check logic, safety and interlocks in the implementation part of FB -> rewrite to %Q variables in the implementation part of FB.
I will be grateful for hints on how best to solve these problems in the OOP way.
Hi, OOP is long journey 🤔
I am also on this way....
So:
- no possibility to use temporary variables in Method and Properties. For example: I call the RunConveyor method in which I assign TRUE to some %Q variable. Then I stop calling this method. I would like the output variable %Q to be FALSE then. A temporary dirty solution is resetting the VAR (%Q) variable in the implementation part of the FB or using the StopConveyor method (which I don't like),
- writing code for critical logic in OOP - example: interlocks (protection against collisions etc.), additional safety logic in PLC (resetting outputs), (...). My temporary, dirty solution is to work with local variables -> check logic, safety and interlocks in the implementation part of FB -> rewrite to %Q variables in the implementation part of FB.
You re right your not able to use temporary var in Method. For Interlock, or Safety, you can add a FB_Interlock and a FB_Safety in your Conveyor object. FB_Interlock and FB_Safety use interface I_Interlock, I_Safety ...
Interlock with 2 Inputs and its property ''IsSafe''
FUNCTION_BLOCK FB_InterlockInputx2 IMPLEMENTS I_Interlock VAR InterLock1 AT %I* :BOOL; Interlock2 AT %I* :BOOL; END_VAR IsSafe:=FALSE; IF InterLock1 AND InterLock2 THEN IsSafe:=TRUE; END_IF
So you conveyor is driven by an Input ( instead of a method) and an Interlock :
FUNCTION_BLOCK FB_Conveyor VAR fbInterlockx2 :I_Interlock; bDriveConveyorInput AT %I* :BOOL; bConveyorOut AT %Q* :BOOL; isSafe :BOOL; END_VAR issafe:=fbInterlockx2.IsSafe; // just for the show //Start Stop the conveyor bConveyorOut := bDriveConveyorInput AND fbInterlockx2.IsSafe;
Manual / Automic is a mess
my 2 cents,
Alex
@alex Thank you very much for your answer. I'm afraid it is too procedural - all core of the logic is in the implementation part, we are using inputs instead of methods and properties. Only OOP part is:
fbInterlockx2 : I_Interlock;
But thank you for hint on using FB_InterlockInputx2. I would use regular input of FB 😀
My temporary solution is something like this:
FUNCTION_BLOCK FB_ControlSomeActuator VAR fbInterlockx2 : I_Interlock; //Taken from your example - it can be also Input of FB or anything else bControlOutput: BOOL; //Variable used by methods like "Start" and Stop" bDigitalOutput AT %Q* : BOOL; //Variable after checking interlocks END_VAR bDigitalOutput := bControlOutput AND fbInterlockx2.IsSafe;
The difference is that you can use variable bControlOutput in more OOP way: set it in method Start and reset in method Stop or something like that. Then you switch to old, procedural code where you execute checking interlocks in the implementation part of the FB.
The difficult part of this task is that interlocks/safety logic should be executed in some cyclic code (for me most secure would be implementation part of the FB, but it's not OOP). Additionally, you must be sure that if you execute some method in cyclic code where you check interlocks/safety and reset output that this method is executed as last part of the code (there are no more calls of method where you SET the output).
So you may have:
METHOD Start VAR END_VAR bDigitalOutput := TRUE AND fbInterlockx2.IsSafe;
and also:
METHOD SafetyReset VAR END_VAR IF fbInterlockx2.IsNotSafe THEN bDigitalOutput := FALSE; END_IF
The problem is where to execute this SafetyReset method to be 100% sure that no one will call method Start after it.
OOP is a new approach. We have to think about object with methods and properties.
ie FB_InterlockInputx2 is an ''interlock object with two inputs''. If tomorow if you have 3 inputs for a new interlock you just have to define a FB_InterlockInputx3 implements I_Interlock and that's done.
We can go further, and set our Input as FB_NoInput and Fb_NcInput both Implement I_Inputs. Like this you don't care if the input are NO or NC...
One goal of OOP is to be, among other things, as flexible as possible.
Like Ladder vs ST, ''Traditional Programming'' vs OOP, I would say : Use the best of each parts.
-
Operator Overloading in TwinCAT using OOP
10 months ago
-
Fluent Interface and Method Chaining in TwinCAT 3
2 years ago
-
Decorator Design Pattern
2 years ago
-
Dependency Injection in TwinCAT
2 years ago
-
Object Oriented Programming (OOP) resources
2 years ago
- 17 Forums
- 265 Topics
- 932 Posts
- 1 Online
- 688 Members