Extending the HMI parallel class (FB)
In many use cases, the number of displayed values on the surface is to be extended. For this purpose, the HMI parallel class can be extended so that the new values are accessible in the HMI environment at a suitable location.
- For the complete implementation the extension of the base class (FB) is necessary.
- 1. Perform steps 1 to 5 of Base class extension (FB) for the base class.
- 2. Create a new class (FB) and remove VAR_INPUT and VAR_OUTPUT
.
FUNCTION_BLOCK FB_CustomAxisHmi
VAR
END_VAR
- 3. Add the class to be inherited to the class definition using the
EXTENDS
keyword.
FUNCTION_BLOCK FB_CustomAxisHmi EXTENDS FB_AxisHmi
VAR
END_VAR
- 4. So that you can also address the class and the added elements via an interface, create an interface with the same name.
INTERFACE I_CustomAxisHmi
- 5. Let the interface inherit from the interface of the inherited class.
INTERFACE I_CustomAxisHmi EXTENDS I_AxisHmi
- 6. Implement the interface in the previously created class (FB).
FUNCTION_BLOCK FB_CustomAxisHmi EXTENDS FB_AxisHmi IMPLEMENTS I_CustomAxisHmi
VAR
END_VAR
- 7. Instantiate the interface in the base class (FB).
FUNCTION_BLOCK FB_CustomAxis EXTENDS FB_Axis IMPLEMENTS I_CustomAxis
VAR
iCustomAxisHmi: I_CustomAxisHmi;
END_VAR
- 8. Overwrite the SetHMI() method of the base class.
// Setter method for HMI-Class
METHOD SetHMI : HRESULT
VAR_INPUT
ipBaseHmi: I_BaseHmi; // interface on hmi object
END_VAR
IF NOT __QUERYINTERFACE(ipBaseHmi, iCustomAxisHmi) THEN
SetHMI := F_HresultFailure(E_AdsErr.DEVICE_INVALIDINTERFACE);
RETURN;
END_IF
SetHmi := S_OK;
- 9. Extend the Init() method and add a __QUERYINTERFACE() operation for the new interface.
METHOD Init : HRESULT
IF NOT __QUERYINTERFACE(iCustomAxisHmi, iAxisHmi) THEN
RETURN;
ELSIF NOT F_SucceededHr(SUPER^.Init(), Init) THEN
RETURN;
END_IF
Add a new setting or command value for the HMI
- 10. Add a new property to the HMI class.
PROPERTY NewHmiProperty : LREAL
- 11. Add the Monitoring attribute to the declaration to make the property visible to the HMI.
This makes the property visible even when the PLC is logged in.
{attribute “monitoring” := “call”}
PROPERTY NewHmiProperty : LREAL
- 12. Copy the property to the interface with the same name.
- 13. Create a similarly named variable in the HMI class where the value can be cached.
FUNCTION_BLOCK FB_CustomAxisHmi EXTENDS FB_AxisHmi IMPLEMENTS I_CustomAxisHmi
VAR
fNewHmiProperty: LREAL;
END_VAR
- 14. Add the 'TcHmiSymbol.Hide' attribute to the declaration so that the variable is not seen by the HMI.
This ensures that the variable is not mistakenly used by the HMI instead of the property. If you set the ADS mapping in the HMI to Use whitelisting, you can basically hide all variables. To continue showing the HMI classes, you must add the {attribute 'TcHmiSymbol.ShowRecursively'} to the declaration.
FUNCTION_BLOCK FB_CustomAxisHmi EXTENDS FB_AxisHmi IMPLEMENTS I_CustomAxisHmi
VAR
{attribute 'TcHmiSymbol.Hide'}
fNewHmiProperty: LREAL;
END_VAR
- 15. Implement the property write and read operation in the Get and Set method.
- You have successfully added a property.
Making an existing property of the base class accessible to the HMI
- 1. Instantiate an interface of the base class type in the HMI parallel class.
FUNCTION_BLOCK FB_CustomAxisHmi EXTENDS FB_AxisHmi IMPLEMENTS I_CustomAxisHmi
VAR
{attribute “TcHmiSymbol.Hide”}
iCustomAxis: I_CustomAxis;
{attribute “TcHmiSymbol.Hide”}
fNewHmiProperty: LREAL;
END_VAR
- 2. Add the Init() method to the HMI class.
// Init method for linking to a control class (FB)
METHOD Init : HRESULT
VAR_INPUT
ipBase: I_Base; // Base interface on linked control class (FB)
END_VAR
- 3. In the Init() method, perform a
__QUERYINTERFACE()
operation from the base interface passed to the last interface instantiated.
Init := F_HresultFailure(E_AdsErr.DEVICE_NOTINIT);
RETURN(NOT __QUERYINTERFACE(ipBase, iCustomAxis));
RETURN(NOT F_SucceededHr(SUPER^.Init(ipBase), Init));
Init := F_HresultSuccess(NOERR);
- 4. [If inheriting from
Init:=F_HresultFailure(E_AdsErr.DEVICE_NOTINIT);
IF iCustomAxisHmi = 0 THEN
RETURN;
ELSIF NOT F_SucceededHr(iCustomAxisHmi.Init(THIS^), Init) THEN
RETURN;
ELSIF NOT F_SucceededHr(SUPER^.Init(), Init) THEN
RETURN;
END_IF
- 5. Add a new property to the HMI class.
PROPERTY SecondNewHmiProperty : LREAL
- 6. Add the Monitoring attribute to the declaration to make the property visible to the HMI.
This makes the property visible even when the PLC is logged in.
{attribute “monitoring” := “call”}
PROPERTY NewHmiProperty : LREAL
- 7. Copy the property to the interface with the same name.
- 8. Program the access to the property of the interface in the Get (and if necessary Set) method of the property.
IF iCustomAxis <> 0 THEN
SecondNewHmiProperty := iCustomAxis.ExistingValue;
END_IF
- 9. For further properties with reference access, steps 1 to 4 are omitted accordingly.
- You have successfully added a property with reference access to the main class.