Skip to content

Single Output

A cylinder component can be created using the SOLID principles outlined in the SOLID Overview document. This example will demonstrate how to create a reusable Cylinder component that can be easily integrated into various projects. This simple cylinder component will control the extension of a pneumatic cylinder using only one digital output. We will assume that the cylinder is spring retracted, meaning that when the output is de-energized the cylinder will retract automatically.

Step 1: Define the Interface

Create an interface I_Cylinder that defines the methods for the Cylinder component.

1
2
3
4
INTERFACE I_Cylinder
    METHOD Extend
    METHOD Retract
END_INTERFACE

Step 2: Create the Cylinder Component

Create a function block Cylinder that implements the I_Cylinder interface. Previously when creating the Digital Output, it was dependent upon a REFERENCE TO BOOL variable for the output. The Cylinder component will depend on the Digital Output component through the I_DigitalOutput interface. This adheres to the Dependency Inversion Principle (DIP) by depending on an abstraction rather than a concrete implementation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FUNCTION_BLOCK Cylinder IMPLEMENTS I_Cylinder
VAR
    ExtendOutput : I_DigitalOutput; // Dependency Injection of Digital Output component
END_VAR

METHOD FB_Init : BOOL
    VAR_INPUT
        bInitRetains : BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold)
        bInCopyCode  : BOOL; // TRUE: the instance will be copied to the copy code afterward (online change)   
        ExtendOutput : I_DigitalOutput;
    END_VAR

    THIS^.ExtendOutput := ExtendOutput;
END_METHOD

METHOD Extend
    ExtendOutput.On := TRUE;    
END_METHOD

METHOD Retract
    ExtendOutput.On := FALSE;
END_METHOD

END_FUNCTION_BLOCK

Step 3 : Using a Null Object for the Digital Output Dependency

To adhere to the Dependency Inversion Principle (DIP) and avoid null reference issues, we can create a Null Object implementation of the I_DigitalOutput interface. This Null Object will provide default behavior when no actual digital output is injected.

In the Cylinder function block declare the Null Object variable for the digital output dependency:

1
2
3
4
5
6
7
8
FUNCTION_BLOCK Cylinder IMPLEMENTS I_Cylinder
VAR
    ExtendOutput : I_DigitalOutput; // Dependency Injection of Digital Output component

    // Null Object for Digital Output dependency
    NullEO           : BOOL;
    NullExtendOutput : DigitalOutput(Output := NullEO);
END_VAR

Then, in the FB_Init method, check if the ExtendOutput input is provided. If not, assign the NullExtendOutput to the ExtendOutput reference.

1
2
3
4
5
6
7
8
METHOD FB_Init : BOOL
    IF ExtendOutput = 0 THEN
        THIS^.ExtendOutput := NullExtendOutput;
    ELSE
        THIS^.ExtendOutput := ExtendOutput;
    END_IF

END_METHOD

Step 4: Using the Cylinder Component

To use the Cylinder component, create an instance of it in your main program start by declaring the DigitalOutputVar, then the DigitalOutput, and finally the Cylinder component. Initialize the Cylinder component with the digital output object and control it through the Extend and Retract methods.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PROGRAM MAIN
VAR
    DigitalOutputVar at %Q* : BOOL; // Must be declared before injecting into the DigitalOutput component
    DigitalOutput           : DigitalOutput(Output := DigitalOutputVar); // Must be declared before injecting into the Cylinder component
    Cylinder                : Cylinder(ExtendOutput := DigitalOutput);

    ExtendCylinder   : BOOL;
    RetractCylinder  : BOOL;
END_VAR

// Extend the cylinder
IF ExtendCylinder THEN
    ExtendCylinder := FALSE;
    Cylinder.Extend();
END_IF

// Retract the cylinder
IF RetractCylinder THEN
    RetractCylinder := FALSE;
    Cylinder.Retract();
END_IF

END_PROGRAM

Conclusion

By using the Cylinder component, you can easily manage and control the extension and retraction of a pneumatic cylinder while adhering to the SOLID principles. This approach promotes reusability and maintainability in your automation projects.