TwinCAT Software Testing

What is Software Testing

Software testing is the process of checking the quality, functionality, and performance of a software product before deployment to the actual devices. We shall focus on this article while we develop our software when the actual hardware is not available yet. There are many different kinds of testing in software engineering.

In most cases, the PLC software reads, processes,  and update the output variables for controlling the devices. The PLC program does some output and then the automation system signals (by input sensors) that it has done the desired work. PLC monitors the input variables for a certain time, if the desired input is not set within that time, PLC signals with an alarm for that device. 

As we see in the following diagram, our program continuously reads the inputs and decides what to do, if the program instructs to do an output then it does. The output normally activates the actuators. It can be solenoid valves, it can be a motor contactor. Actuators are devices that perform actions, such as opening valves, moving robots’ arms, or switching lights, based on signals from PLCs.

Figure 01: Typical PLC cycle

We can also test the PLC program by creating another task in the PLC program, where we can signal the input to the desired level. Here we are doing similarly but using HMI Software. The test cases can be flexible and visually observable.

Knife Gate Valve (Case Study)

In this tutorial, we shall use a simple knife gate valve. We assume that this one is a pneumatic valve. The valve is opened when a solenoid is active (the output is ON). When the solenoid is ON then compressed air pushes the valve’s blade to the upper direction and the blade goes up.  There are two proximity sensors for the valve. When the valve is fully open, the blade is in the upper position, and both proximity sensors are ON. If the lower one is ON and the upper one is OFF then the valve is half open. When the solenoid is OFF then the valve’s spring force pushes the blade to close the valve. When the valve is closed then both proximity sensors are OFF.

The valve is shown in the following diagram.

Figure 02: Pneumatic valve, 2 proximity sensors, and a solenoid valve (not shown here)

In the following code snippet, we command the valve to be opened by an action where we put the solenoidOutput variable ON (TRUE)

VAR			
(* input *)
upperProximitySensor AT%I*: BOOL;
(* input *)
lowerProximitySensor AT%I*: BOOL;
(* output *)
solenoidOutput   AT %Q* : BOOL;
(* analog *)
pressureRawValue AT%I*: DINT;
(* analog *)
temperatureRawValue AT%I*: DINT;
(* analog *)
terminalState AT %I* : WORD;
END_VAR

Note from the above code that few variables are commented as input, output and analog. By this way, we scan the variables and identify which variables are related to hardware device. For example, when the solenoidOutput is active (ON) then the valve should be in open state and the two proximity sensor should be active (ON) in ideal case. When the solenoid if inactive then the valve should be in closed position and the two proximity sensors should be inactive (OFF)

Figure 03: Pneumatic valve closed, partially closed, and fully open (right side of the image) and status of proximity sensors

We shall develop our test system without any physical valves, when our SW is tested then we just activate our program to the PLC then we are done! Following diagram shows possible commands and related results, we can develop similar cases based on our devices and process.

Figure 04: Valve Open and Close command and the possible results of the command

Different devices will have different inputs, outputs and command. These are just an example.

Possible Hardware Setup

We don’t have the hardware yet but we can configure the possible setup in Visual Studio. An embedded PC has a coupler connected to an ethernet port. Two cards EL2008 (Output card) and EL1808 (Input card) are connected to the coupler. The variable solenoid output is linked to 1st channel. The variables upperProximitySensor and lowerProximitySensor are linked to the 1st and 2nd channels of card EL1808. This is drawn as in the following image.

Figure 05:  Hardware setup for controlling the valve (simplified version, electrical safety stuff omitted).

With this setup, we activate our tested program, which should start working when the hardware is available. Since we don’t have the hardware yet we shall try to complete the test using our test tool ADSTestDriver.

Valve control Code in ST

In this section, we shall focus on the implementation of valve control in the structured text programming language. 

Please download the source code from the download section. This is basically a valve function block that can be used to control the actual device. We have 3  other variables which are not related to the valve itself, those are terminalState of type WORD, pressureRawValue of type DINT, and temperatureRawValue of type DINT. We shall show how we can generate pressure or temperature data while we don’t have actual hardware. The terminal state is another important variable that indicates the communication status with hardware. We can set that status by using our test software.

How the test system works

In the current version of the test software, we connect to the PLC program and load a test case. The test case is generated by using or configuring an output. Basically we define what kind of input or process values we expect when an output goes active. Then we can observe the PLC program and fix the found issues. The following figure explains the configuration process for each variable in the system when we are testing a generic function block.

Figure 06:  Test configurations, this can be used to test any PLC program with ST

Test configurations

Here we describe the functions of each button, check boxes, list boxes, etc.

1 => AMS NetID of the PLC where the PLC program is running

2 => PLC name

3 => Port number of the PLC program

4 => Button for connecting to the PLC (it will read only those variables that have comments as mentioned in 20, 32, and 48)

5 => Connection status to the PLC (Checked when connected and unchecked when not connected). Uncheck can disconnect from the PLC

6 => Current test case name

7 => Relation of variables in the current test case

8 => Test case file name where the test cases can be saved

9 => Update intermediate test cases, we configure 1 output at a time and press the update test case button before pressing “Save Test Cases”. Every time we configure 1 output and press the Update Test Cases button

10 => When we have configured all outputs then we save to the file name mentioned in step 8 (“Valve Test”). When we have saved the test case that file name will be visible in the list of 12

11 => Delete the current test case file from the list

12 => List of all test case files we have configured (we can have valve test all OK, input sensors malfunctioning, etc). If we select a file that will be visible in Tree View 7

13 => We need to tell the system that we are starting a new test case, if we don’t select this option, we can’t save data.

14 => Output variable (tag name), when we select another variable its property will be visible in the fields 15, 16, 17

15 => If this is checked then the system will change the configured input or analog variables

16 => Comment related to this output if needed

17 => If checked this output will be ignored

18 => If we change any properties (in 15, 16, and 17) that will be updated for the current output

19 => Update the list (21) by reading  the variables from the system

20 => When we connect to PLC, this text is used to filter variables. If the system finds an output comment in any variable that will be added to the list 21,  for example

(* output *)
solenoidOutput   AT %Q* : BOOL;

21 => Variable names found in the system which has a comment that matches in the field 20

22 => We need to check so this variable will be configured. Only 1 output can be configured at a time.

23 => Currently selected input which we are going to configure

24 => If checked the input will be ON (after the delay in 25)

25 => Delay in seconds (the input will be changed as configured in 24). Delay can’t be -ve

26 => Ignore the case, no action will be taken if checked

27 => If we set Error active then we can configure the input Always ON or Always OFF

28 => If checked then the input will be ON all the time (27 and 28 should be selected)

29 => If checked then the input will be OFF all the time (27 and 29 should be selected)

30 => If we press this button then currently selected properties will be updated for the selected tag

31 => Refresh the input list which is found in the system based on the comment in field 32

32 => When we press on the connect then it will read the text and produce a list (in list 33) as shown below

(* input *)
upperProximitySensor AT%I*: BOOL;

 

33 => Display a list of variables which has a comment as found in field 32

34 => If selected this variable will be added to the list when we press “Update Test Cases” 9

35 => Currently selected variable from the list 49

36 => Max value for the analog variable

37 => Min value for the analog variable

38 => If selected, then the system will write to output variable average of min and max

39 => If selected, then the system will write to output variable from min value to max value during the time in 41

40 => If selected, then the system will write to output variable from min value to max and then back to min value during the time in 41

41 => The system will use this time to update the analog variable. The time is in seconds

42 => Delay in seconds (data will be written to the variable after the delay)

43 => If checked the case will be ignored (no data will be written)

44 => If checked, then we can simulate the error case

45 => If checked, then it will write the min value (44 and 45 must be checked)

46 => If checked, then it will write random data between min and max values (44 and 46 must be checked)

47 => The configured output will be updated internally

48 => This value will be used to find the variables from the program. In the PLC, the code is written like the following.

(* analog *)
terminalState AT %I* : WORD;

 

49 => Variables found which has a comment as mentioned in the field 48

50 => If checked this variable will be used for the test system

Steps for creating test case

Step 01: Configure all the needed outputs, inputs, and analog variables

    => Selecta  variable, configure its properties and update

    => One output should be configured for many inputs and analog variables

Step 02: Select Start New TestCase, and select the output, input(s), and analog data(s)

Step 03: Update TestCases

Step 04: Select new output variables

    => If we want to reuse any input or analog variables that were used previously, we have to change their properties (if needed)

    => Select all the needed analog/input variables 

    => Press Update Test Cases

Step 04: Finally give a name and press Save Test cases

 

Testing the valve

Figure 07:  Testing the valve

When we are testing our software, we must select a test case file (from the configuration page) and the test sw should be connected to the PLC.

Testing Result

As we see the terminal state is 8, the output solenoid is ON (top circle), and 2 sensors are active. Also, pressure and temperature have some value as specified. This is done and tested in the ideal case. If we press open, the valve will be opened and when we press the valve will be closed. All are fine.

But now, let’s assume after a few days one of the sensors will be broken. When we run the same test the result will be like the following.

Figure 08:  Testing the valve, one sensor is broken (configure a limit switch as OFF)

At this point, your user (operator) fixed the broken sensor and he wants to recover it himself. if he presses Open, Close nothing will help. The only way to make it working restarting the PLC. So the big question is, could we have done the test already beforehand so we could have better software? Yes, we have a solution for that. There are many ways to handle the case. The following is one of the ways to handle it. We introduce a reset button and change the PLC code to handle it so that if such a situation occurs then the operator can manage it without restarting the PLC or calling the developer.

Figure 09:  Testing the valve, reset button and it’s functionality has been introduced in the PLC

The following code snippet has been introduced in the PLC. Note there are many different ways to handle the case, but this is one of those. You can download both versions from the download section.

IF state > VALVE_INIT THEN	
IF valveResetCommand= TRUE  THEN
    valveResetCommand := FALSE;
    valveOpenCommand := FALSE;
    state :=VALVE_CLOSED;
    solenoidOutput := FALSE;
    valveCloseCommand:= FALSE;
    upperProximitySensor := FALSE;
    lowerProximitySensor := FALSE;
    stateInit := FALSE;
    pressureRawValue := 0;
    temperatureRawValue := 0;
    terminalState := 0;
    pressureRealValue := 0.0;
    temperatureRealValue := 0.0;
END_IF 
IF state= VALVE_CLOSED  AND valveOpenCommand= TRUE  THEN
state :=VALVE_OPENING;
valveOpenCommand:= FALSE;
solenoidOutput := TRUE;
stateInit := FALSE;
END_IF
IF state= VALVE_OPENED AND valveCloseCommand= TRUE  THEN
state :=VALVE_CLOSING;
solenoidOutput := FALSE;
valveCloseCommand:= FALSE;
stateInit := FALSE;
END_IF 
END_IF

 

 

Architecture of the Test System

In the following figure, we can see the architecture of the test system. The system use the ADS library provided by Beckhoff.

Figure 10:  Architecture of the test system

ADSTestDriver is a DLL that we wrap with the extension module. Since the source code is unavailable to you if you find any issue please get in touch with us and we shall update it and deliver it to you for free.

YouTube Video

Coming soon…

Download Source Code

The code contains the server extension DLL and ADSTestDriver.dll. You need to activate the ServerExtension.dll in the Visual Studio project. 

The download link for the first version is ValvePLCProject_V01.zip

 

The download link for the second version (fixed with reset) is ValvePLCProject_V02.zip

 

Feel free to discuss the test system in our Google group https://groups.google.com/g/hemelix

After unzipping the project you get the following files in the folder ValvePLCProject\ServerExtension\bin\Debug

 

Figure 11:  List of binaries provided in the zip files

To run the project directly please follow the following steps:

=> Load the solution in visual studio ValvePLCProject.sln and build the solution

=> First run the PLC program (local or on the remote PLC)

=> Right-click on the ServerExtension (under HMI Configuration Project) and activate the extension

=> Open Desktop.view and load in live view, press on “Configure Test Cases”

=> Press on the connect button, if all are fine we should get the connected check box checked

=> If we press on refresh list, we get the list of filtered variables

=> Now we can configure each output and define what the input variables and analog variables should do

 

Known Issues

=> Once we have created test cases (configured properties) then we can’t load the test case file and edit it (we need to recreate it again, we shall fix it in the next version)

=> ADSTestDriver, the binary is available in the downloadable project, if you need source code you can contact us!

New approaches!

We got some good feedback, and based on that feedback, we are taking completely new approaches. Here is the GUI