Rotating an Image around center by animation framework

The TwinCAT HMI framework can be used to rotate an image easily. But if you want to do it in a certain way (depending on the complexity) it may be difficult. We want to rotate an image around the center based on a variable in PLC. If the PLC variable is TRUE then we start a rotation if it is FALSE we stop the rotation. This can be useful for example in relation to a motor. We want to display how a motor is running at a certain speed.

I have tried to use the transformation function with a timer but it is not smooth. So animation framework help to display the rotation smoothly. We shall design the sample to display the DC motor speed in our fictitious home automation system.

 

https://www.hemelix.com/wp-content/uploads/2021/09/Animation_Rotation_BeckhoffImage.zip

A keyframe (or keyframe) in animation and filmmaking is a drawing or shot that defines the starting and ending points of any smooth transition. TwinCAT HMI allows us to create and configure animations that can be played using CSS or JavaScript. The Animation API is designed for use within controls.

 

HMI and the PLC program

The main user interface and a tiny PLC program in the background. The simple PLC program has variable called startRotation. If if this variable is TRUE then we rotate the Beckhoff image and stop rotation (and set to the original position). We need to set the variable to TRUE, since we don’t have any actual device, we set it by the button START/STOP.  Same button will toggle the startRotation variable. Try to download the sample and test it in your environment. 

Create  the short PLC program and  run it in the Visual Studio. Make sure you can change the variable in the PLC program.

 

//PLC Program
PROGRAM MAIN
VAR
startRotation : BOOL := FALSE;
END_VAR
 If you are new and have not started yet, please  take a look in this sample first https://www.hemelix.com/scada-hmi/beckhoff-hmi/beckhoff-hmi-installation/

Design of the sample:

 

STEP 01:

=>Create an HMI project by visual studio

=>insert the following control from the tool box (View | ToolBox or CTRL+ALT+X )

Text block: Change the text to Angle 

Chage the ID to TcHmi_Controls_Beckhoff_TcHmiTextbox_Angle

Text box: Change the text to 36000

Text block: Change the text to Time

Chage the ID to TcHmi_Controls_Beckhoff_TcHmiTextbox_Time

Text box: Change the text to 2000

Start/Stop button: for changing the PLC variable

Now the HMI content is ready, but it just display the content if you run. We need to link the HMI to PLC program.

STEP 02:

=> Make sure that the PLC variable is available in the HMI (Select TwinCAT Project | TwinCAT HMI | TwinCAT HMI Server configuration)

=> ADS | RunTimes | PLC1 | Accept (as shown in the following image)

 

STEP 03 :

=> Configure Start/Stop button so when we press it will toggle the startRotation in PLC

=>Create a folder in the HMI project, name it JavaScript and insert a code behind file (if needed see https://www.hemelix.com/scada-hmi/beckhoff-hmi/twincat-javascript-function-and-code-behind/)

=> Declare a animation object there

module TcHmi {
    // If you want to unregister an event outside the event code you need to use the return value of the method register()
    var destroyOnInitialized = TcHmi.EventProvider.register('onInitialized', function (e, data) {
        // This event will be raised only once, so we can free resources. 
        // It's best practice to use destroy function of the event object within the callback function to avoid conflicts.
        e.destroy();
        // ----------------------
        // Place your code here!
        // ----------------------
        var animationGlobal; //<<<< This the variable we are talking about
    });
}

STEP 04:

=> Select the Beckhoff image and bring the properties (select the range tool or F4 )

=> Press on the event button (lightning bolt)

=>Configure the Custom event to tell framework to do some action when the startRotation in the PLC changes as shown in the following image.

 

We need to insert the java script code. See how we are reacting to the changes of variable. Once you have inserted the script you are ready to test it.

 


var startMotor= '%s%PLC1.MAIN.startRotation%/s%';  
TcHmi.Symbol.readEx2(startMotor, function(data) {                     
if (data.error === TcHmi.Errors.NONE) {   
if(data.value == true) { 
var angleControl = TcHmi.Controls.get("TcHmi_Controls_Beckhoff_TcHmiTextbox_Angle");
var timeSControl = TcHmi.Controls.get("TcHmi_Controls_Beckhoff_TcHmiTextbox_Time");
    if (angleControl != undefined && timeSControl != undefined) {    
var angle = parseFloat(angleControl.getText(), 10); 
var timeS = parseFloat(timeSControl.getText(), 10);
var finalFrame = 'rotate('.concat(angle.toString()).concat('deg)');
console.log(finalFrame);
console.log(timeS);
animationGlobal = new TcHmi.Animation('ViewDesktopBeckhoffLogo', '');
animationGlobal.addKeyframe('transform', 'rotate(0deg)', 0)
    .addKeyframe('transform', finalFrame, 1)
    .duration(timeS*1000);  
animationGlobal.run();
}
}                     
else 
{
console.log('Reset');
//Stop the animation and put back the beckhoff image to horizontal position
//I don't have reference to the animation object if I don't declare in code behind file or in some otherway
//At least if I declare the animation in a code behind  file  then I have access to the object and I can reset it or pause it
//Problem with pause the image does not go to the original shape  
//Problem with reset, the animation does not start again if I create the animation in code behind file. If I declare it in code behind file and 
//initialized in the embedded code then it is  fine.  But I am not sure related to memory leak or other performence issue.
//With subscription, I have similar issues.
//animationGlobal.pause();
animationGlobal.reset();
}
}                   
}); 
=> Test it  and see the result.

I have a question to you for discussion in https://groups.google.com/g/hemelix, since animation framework takes time value when we create or configure the animation object, what value we should set and how? Lets discuss in the group.

Download the sample:

Link is given at the top

 

Reference:

 

 https://infosys.beckhoff.com/english.php?content=../content/1033/te2000_tc3_hmi_engineering/36028800864323851.html&id=

https://developer.mozilla.org/en-US/docs/Web/CSS/animation

 

Download the sample from the link given above.

 

Next, let’s try to display data as a tree by JavaScript at https://www.hemelix.com/scada-hmi/beckhoff-hmi/display-tree-like-nodes-to-twincat/

 

Ask questions related to Hemelix sample code and design at Google group https://groups.google.com/g/hemelix