Join us today!

A few difficulties ...
 
Notifications
Clear all

A few difficulties while learning OOP

4 Posts
2 Users
1 Reactions
556 Views
Posts: 4
Topic starter
(@unnameduser001)
Active Member
Joined: 1 year ago

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.

Reply
Topic Tags
3 Replies
Posts: 30
 Alex
(@alex)
Eminent Member
Joined: 2 years ago

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

 

Reply
1 Reply
(@unnameduser001)
Joined: 1 year ago

Active Member
Posts: 4

@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.

Reply
Posts: 30
 Alex
(@alex)
Eminent Member
Joined: 2 years ago

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.

Reply
Share: