Skip to main content

Programming the Controller Application in the Project

Declaring the global variables

First, declare the variables that you want to use across the entire application. To do this, create a global variable list below Application:

  1. Select the Application entry and click Add Object → Global Variable List in the context menu. Change the default name GVL to Glob_Var and click Add to confirm.

    The _cds_icon_gvl.png Glob_Var object is displayed below _cds_icon_application.png Application. The GVL editor opens to the right of the device tree.

  2. When the textual view opens, it already contains the keywords VAR_GLOBAL and END_VAR. For our example, click the _cds_img_button_decl_editor_tabular.png button on the right sidebar of the editor to activate the tabular view.

    An empty row appears. The cursor is in the Name column.

  3. In the context menu, click Insert.

    An input field opens. At the same time, the Scope VAR_GLOBAL and the Data type BOOL are entered in the line automatically.

  4. Specify rTempActual in the Name field.

  5. Double-click in the field of the Data Type column.

    Now the field can be edited and the cds_icon_open_input_asisstant.png button is displayed.

  6. Click the cds_icon_open_input_asisstant.png button and then select Input Assistant.

    The Input Assistant dialog opens.

  7. Select the data type REAL and click OK.

  8. Enter a numerical value in the Initialization column (example: 8.0).

Declare the following variables in the same way:

Name

Data Type

Initialization

Comment

rTempActual

REAL

8.0

Actual temperature

rTempSet

REAL

8.0

Set temperature

xDoorOpen

BOOL

FALSE

Status of door

timAlarmThreshold

TIME

T#30S

Time after compressor runs that a signal sounds

timDoorOpenThreshold

TIME

T#10S

Time after opening the door that a signal sounds

xCompressor

BOOL

FALSE

Control signal

xSignal

BOOL

FALSE

Control signal

xLamp

BOOL

FALSE

Status message

Creating the main program for the cooling control in the CFC editor

You will now describe the main function of the application program in the main PLC_PRG POU, which is created by default. The compressor is activated and cools when the actual temperature is higher than the set temperature plus a hysteresis. The compressor switches off when the actual temperature is less than the set temperature minus the hysteresis.

To describe this functionality in the CFC implementation language, follow the steps below:

  1. In the device tree, double-click PLC_PRG.

    The CFC editor opens in the PLC_PRG tab. The declaration editor appears above the graphical editor area in textual or tabular form. The ToolBox view is on the right side.

  2. In the ToolBox view, select the Input element and drag it to the CFC editor below the PLC_PRG tab.

    The nameless entry ??? has been inserted.

  3. In the CFC editor, click ??? at the input, and then click _cds_icon_input_assistent.png to open the Input Assistant. In the Variables category, select the rTempActual variable below Application → Glob_Var. This is how to reference the global variable rTempActual here.

    The input name is Glob_Var.rTempActual.

  4. As in Step 3, create another input with the name of the global variable Glob_Var.rTempSet.

  5. Create another input, and then click ??? and replace them with the name rHysteresis.

    Because this is not the name of a known variable, the Auto Declare dialog opens. The name is already used in the dialog.

  6. In the Auto Declare dialog, specify the Type as REAL and Initialization as 1. Click the OK button.

    The variable rHysteresis appears in the declaration editor.

  7. In the ToolBox view, select Block element and drag it to the CFC editor below the PLC_PRG tab.

    The POU opens in the CFC Editor.

  8. Replace ??? with ADD.

    The POU adds all inputs that are connected to it.

  9. Connect the Glob_Var.rTempSet input to the ADD POU. To do this, click the output pin of the input and drag it to the upper input pin of the ADD POU.

  10. In the same way, connect the input rHysteresis with the lower input of the ADD POU.

    The two inputs rHysteresis and Glob_Var.rTempSet are now added by ADD.

  11. To move an element in the editor, click an empty space in the element or click the frame, so that the element is selected (red border, red highlight). Drag the element to the desired position.

  12. Create another POU to the right of the ADD POU. Its purpose is to compare Glob_Var.rTempActual with the sum of Glob_Var.rTempSet and rHysteresis. Assign the GT function (greater than) to the POU.

    The GT POU works as follows: IF (upper input > lower input) THEN output := TRUE;

  13. Connect the input Glob_Var.rTempActual to the upper input of the GT POU.

  14. Connect the output of the ADD POU to the lower input of the GT POU.

  15. Now use the block element to create a function block to the right of the GT POU which starts and stops the compressor depending on the input conditions (Set – Reset). Specify the name SR in the ??? field. Press the Enter key to close the open input field above the POU (SR_0).

    The Auto Declare dialog opens.

  16. Declare the variable with the name SR_0 and the data type SR. Click the OK button.

    The SR POU from the Standard library is instantiated. SR is used for the definition of THEN at the output of the GT POU. The inputs SET1 and RESET appear.

  17. Connect the output pin on the right of the GT POU to the SET1 input of the SR_0 POU.

    SR can set a Boolean variable from FALSE to TRUE and back again. When the condition at the input SET1 is satisfied, the Boolean variable is set to TRUE. The variable is reset again when the condition at RESET is satisfied. The Boolean (global) variable in our example is Glob_Var.xCompressor.

  18. Create an Output element and assign it to the global variable Glob_Var.xCompressor. Drag a connecting line between Glob_Var.xCompressor and the output pin Q1 of SR.

Now specify the condition under which the compressor should switch off again (in this case, the RESET input of the SR POU gets a TRUE signal). To do this, formulate the opposite condition to that above. Use the SUB (subtraction) and LT (less than) POUs to do this.

The result is the following CFC chart:

_cds_img_tutorial_refrigerator_plcprg_cfc_diagram.png

Creating a POU for signal management in the ladder diagram editor

In another POU, you will now implement the signal management for the alarm buzzer and for switching the lamp on and off. The ladder diagram (LD) implementation language is suitable for this.

Handle each of the following signals in their own networks:

  • When the compressor runs too long because the temperature is too high, a continuous audible signal sounds.

  • When the door is open too long, an intermittent signal sounds.

  • The light is on as long as the door is open.

  1. In the device tree, right-click the Application object and add a POU object of type Program with the Ladder (LD2) implementation language.

    Name the program as Signals.

    The Signals program is listed in the device tree next to PLC_PRG. The ladder diagram editor opens in the Signals tab. The declaration editor appears in the upper part, the ToolBox view to the right. The ladder diagram contains an empty network.

  2. Create a program in the network so that an audible signal sounds when the compressor runs too long without reaching the specified temperature. To do this, insert a TON timer POU in the next steps. It switches a Boolean signal to TRUE after a specified time.

  3. In the ToolBox view, drag the Block element and drop it into the empty network to an available insertion position.

    The block is displayed as a box with inputs and outputs.

  4. Double-click the three question marks (???) in the block and click the _ld_icon_input_assistant.png symbol in the line editor.

    The Input Assistant dialog opens.

  5. In the Input Assistant dialog, in the Standard function blocks category, in the Standard library, select the TON Timer and click OK.

  6. Now in the line editor of the block, which shows the function block name TON, press the Enter key.

    The TON POU is displayed with its inputs and outputs.

  7. To remove the EN input and the ENO output, select the block and click the EN/ENOEN in the context menu.

    Now the block has only the IN and PT inputs and the Q and ET outputs.

  8. Double-click the three question marks [???] directly above the block, specify TON_0 as the instance name, and press the Enter key.

    You have confirmed the instance name. The Auto Declare dialog opens.

  9. Click OK to confirm the dialog.

    Now the inserted TON POU is instantiated with the name TON_0.

  10. Program the block to be activated as soon as the compressor starts running. First drag the Contact ladder element from the ToolBox view in front of the IN input of the block. Double-click the three question marks and click the icon in the line editor (_ld_icon_input_assistant.png). In the Input Assistant, now select the already declared global variable xCompressor and click OK.

    The variable name Glob_Var.xCompressor is displayed above the contact.

    Tip

    When you begin to type a variable name at the input position, you automatically get a list of all variables with names that begin with the typed characters and can be used at this point. This assistance is a default setting in the CODESYS options for SmartCoding.

  11. Insert the signal that is to be activated. To do this, drag a Coil from the ToolBox view, Ladder category, to the Q output of the TON block. Specify the name Glob_Var.xSignal for the coil.

  12. Define the time period from the activation of the POU TON_0 until the signal should sound. This definition takes place via the variable Glob_Var.timAlarmThreshold, which you insert for this purpose at the input PT of TON_0. To do this, move the mouse pointer to the left end of the input pin of input PT. Click the fine-edged box which is now displayed to left of the input pin and specify the variable name.

  13. Press the Enter key.

    The Auto Declare dialog opens.

  14. Click OK to confirm the dialog.

    The newly declared variable is displayed in the declaration part.

  15. Right-click the TON POU and click Remove unused pins in the context menu.

    The unused output ET is removed.

  16. In the second network of the LD, program so that the signal sounds intermittently when the door is open too long.

    Use the mouse to drag an Network element from the ToolBox view to the insertion point below Network 1.

    An empty network with the number 2 appears.

  17. As in the first network, implement a TON POU for time-controlled activation of the signal. This time it is triggered by the global variable Glob_Var.xDoorOpen at the input IN. At the input PT, add the global variable Glob_Var.timDoorOpenThreshold.

  18. From the Util library, add a BLINK POU at the output Q of the TON POU in this network and instantiate it with the name Blink_0.

  19. The BLINK_0 POU clocks the signal forwarding Q and therefore Glob_Var.xSignal.

    First, drag two Contact elements from the ToolBox view to the OUT output of the POU. Assign the variable TON_1.Q to the contact directly after the output Q and the global variable Glob_Var.xDoorOpen to the second contact.

  20. Insert a Coil element after the two contacts and assign the global variable Glob_Var.xSignal to it.

  21. Declare the local variable timSignalTime : TIME := T#1S; and insert this variable at the inputs TIMELOW and TIMEHIGH. The cycle time is 1 second for TRUE and 1 second for FALSE.

  22. Right-click the TON POU and click Remove unused pins in the context menu.

    The unused output ET is removed.

  23. In the third network, program so that the lamp lights up as long as the door is open. Add an additional network and a contact. Assign the variable GlobVar.xDoorOpen to the contact.

  24. The inserted contact leads directly to a coil. Add a coil to the right of the contact and assign the global variable Glob_Var.xLamp to the coil.

  25. CODESYS processes the networks of an LD one after the other. Now install a jump to Network 3 at the end of Network 1 in order to ensure that either only Network 1 or only Network 2 is executed:

    When you hover the mouse pointer over the 3rd line in the top left-hand edge of the network, the information <insert jump here> is displayed. Double-click this position and specify DoorIsOpen: as the jump label in the line editor.

    Select the Network 1. From the ToolBox view, Ladder Diagram category, drag the Jump element to the insertion position marked with a triangle in front of the Glob_Var.xSignal coil.

    The jump element appears. The jump destination is still specified as ???.

  26. Double-click the three question marks [???] and click the _ld_icon_input_assistant.png symbol in the line editor. In the Input Assistant dialog, select DoorIsOpen from the possible label identifiers and click OK to confirm.

    The label to Network 3 is implemented.

The LD program now looks like this:

_cds_img_first_cds_program_ld_signals.png

Calling the "Signals" program in the main program

In our program sample, the main program PLC_PRG should call the Signals program for signal processing.

  1. In the device tree, double-click PLC_PRG.

    The PLC_PRG program opens in the editor.

  2. In the Toolbox view, drag a Block element to the editor of PLC_PRG.

  3. Double-click the three question marks [???] and click the _ld_icon_input_assistant.png symbol in the line editor. In the Input Assistant dialog, in the POU / Program and Function Calls category, select the Signals program and click OK to confirm.

Creating an ST POU for a simulation

Because the application in this example project is not linked to physical sensors and actuators, you also need to write a program for the simulation of increase and decrease in temperature. This will allow you to monitor the operation of the refrigerator controller afterwards in online mode.

You create the simulation program in structured text.

The program increases the temperature until the main program PLC_PRG determines that the set temperature has been exceeded. Then the program activates the compressor. Then the simulation program decreases the temperature until the main program deactivates the compressor again.

  1. In the device tree, right-click the Application object and add a POU object of type Program with the Structured Text (ST) implementation language. Name the POU as Simulation.

  2. Implement the following code in the ST editor:

    Declaration part:

    PROGRAM Simulation
    VAR
            TON_1: TON;                         //The temperature is decreased on a time delay, when the comepressor has been activated
            P_Cooling: TIME:=T#500MS;
            xReduceTemp: BOOL;                  //Signal for dereasing the temperature
            TON_2: TON;                         //The temperature is increased on a time delay
            P_Environment: TIME:=T#2S;          //Delay time when the door is closed
            P_EnvironmentDoorOpen: TIME:=T#1S;  //Delay time when the door is open
            xRaiseTemp: BOOL;                   //Signal for increasing the temperature
            timTemp: TIME;                      //Delay time
            iCounter: INT;
    END_VAR
    
    

    Implementation part:

    iCounter := iCounter + 1;     // No function, just for demonstration purposes.
    
    // After the compressor has been activated due to TempActual being too high, the temperature decreases.
    // The temperature is decremented by 0.1°C per cycle after a delay of P_Cooling
    IF Glob_VAR.xCompressor THEN
            TON_1(IN:= Glob_Var.xCompressor, PT:= P_Cooling, Q=>xReduceTemp);
            IF xReduceTemp THEN
                    Glob_Var.rTempActual := Glob_Var.rTempActual-0.1;
                    TON_1(IN:=FALSE);
            END_IF
    END_IF
    
    //If the door is open, the warming occurs faster; SEL selects P_EnvironmentDoorOpen
    timTemp:=SEL(Glob_Var.xDoorOpen, P_Environment, P_EnvironmentDoorOpen);
    
    //If the compressor is not in operation, then the cooling chamber becomes warmer.
    //The  temperature is incremented by 0.1°C per cycle after a delay of tTemp
    TON_2(IN:= TRUE, PT:= timTemp, Q=>xRaiseTemp);
    IF xRaiseTemp THEN
            Glob_Var.rTempActual := Glob_Var.rTempActual + 0.1;
            TON_2(IN:=FALSE);
    END_IF

Tip

We recommend that you use a visualization for convenient operation and monitoring of the entire controller program. A visualization created with CODESYS Visualization is installed in the completed sample project for this tutorial, which is provided with the CODESYS standard installation (Projects directory). You can download this project to the controller and start it to see it working together with the visualization. When started, the Live_Visu begins with a representation of the refrigerator which reproduces the operation of the simulation program without you having to input any data. However, you can open and close the door by clicking the on/off switch. It is possible to adjust the default temperature by means of the needle of the rotary control. We will not cover the creation of the visualization in this tutorial. An corresponding tutorial is planned in the help for CODESYS Visualization.

Defining the programs to be executed in the task configuration

The default task configuration contains the call for the main program PLC_PRG. For our sample project, you also need to add the call for the Simulation program.

  1. In the device tree, drag the Simulation entry to MainTask below the Task Configuration.

    The Simulation program is inserted into the task configuration.

  2. To view the task configuration, double-click the MainTask entry to open the editor.

    In the table in the lower part of the editor, you see the POUs that are called by the task: PLC_PRG (entered by default) and Simulation. The call type of the task is Cyclic at intervals of 20 milliseconds. In online mode, the task will execute the two POUs one time per cycle.

Defining the "active application" for the communication with the PLC

The name of the Application is displayed in bold in the Devices view. This means that this application is set as the "active application". The communication with the controller then refers to this application.

When there is only one application in a project, it automatically becomes the active application. If your application is not active yet, then activate it as follows:

  • In the context menu of Application, click Set Active Application.

    Application is now displayed in bold in the Devices view.

Debugging the application program

When you are inputting the code, CODESYS immediately alerts you to syntax errors by means of a wavy red underline below the text in question. The result of the check is also shown in the message view. If necessary, click View → Messages to open the message view. The messages are displayed in the Precompile message category. You can select a message and press the F4 key to jump to the corresponding point in the code. More tests of the application program are performed when the application is downloaded to the controller.

Afterwards, only an error-free application can be downloaded to the controller.