Sample program for individual temperature calculation in the PLC

The terminals from the EL331x-xxxx series are used for the convenient measurement of temperatures with thermocouples. For this purpose they are equipped with various conversion tables for different types of thermocouples as well as an internal cold junction measurement. However, it is possible that a type of thermocouple might be used that is not stored in the firmware. In this case the EL331x offers the following method:

This calculation method, called cold junction compensation (CJC), corresponds approximately to that which is stored in the terminal for the implemented types.

The sample program implements such a procedure and produces a temperature value that takes into account the channel-wise cold junction temperature from the CoE. By way of example the terminal is continually switched between voltage and temperature measurement in the type K, thus enabling a comparison of the two temperature values. A recording of the measured values from channel 1 of the EL3314 on a type K thermocouple with the TwinCAT Scope is illustrated below (units 0.1 °C):

Sample program for individual temperature calculation in the PLC 1:
Blue: temperature values from the PLC calculation; red: PDO values in the temperature measurement range

Notes:

Sample program for individual temperature calculation in the PLC 2:
Structure of the sample program for "separate temperature calculation with CJC in the PLC"

Download: Program link

Preparations for starting the sample programs (tnzip file / TwinCAT 3)

Extract from the sample program:

Deklarationsteil:

// THIS CODE IS ONLY AN EXAMPLE - YOU HAVE TO CHECK APTITUDE FOR YOUR APPLICATION
PROGRAM MAIN
VAR

   nBuffer_INT           : INT;         // Buffer for reading or writing values from/to CoE objects
   aTCElement            : ARRAY[0..9] OF REAL := // Type K µV entries in 10°C Steps:
      [-1156, -778, -392, 0, 397, 798, 1203, 1612, 2023, 2436];
   nTabIndex             : INT;         // Index of node in table
   
   nT_start              : INT := -300; // -30°C for 0.1°C resolution
   nT_ResTab             : REAL := 100; //  10°C resultion of table (for 0.1°C resolution of values)
   
   // Variables for calculation:
   // ---------------------------
   nDiff_U_node2node     : REAL;    // Voltage difference of two nodes
   nDiff_U_node2U_TC     : REAL;    // Voltage difference of node and U TC
   nSlope                : REAL;    // Slope for 1st interpolation (temperature to voltage)
   nResidual             : REAL;    // Residual value for interpolation
   nRelation             : REAL;    // Relation for 2nd interpolation (voltage to temperature)
   // ===========================
   nU_TC                 : REAL;     // Voltage of temperature inkl. CJC
   nT_CJ                 : REAL;     // Cold junction temperature
   nU_CJ                 : REAL;     // Corresponding voltage of CJ
   nT_Result             : INT;      // Resulting Temperatur (resolution 0.1°C)
END_VAR

Ausführungsteil (nState=100):

// Cold junction temperature by CoE:
nT_CJ := INT_TO_REAL(nBuffer_INT);
// 1. Convert temperature to voltage:
// ========================================================================
// Determinate index of table:
nTabIndex := TRUNC_INT((nT_CJ - nT_start)/nT_ResTab);

// Calculate difference of two values with real value between them:
nDiff_U_node2node := (aTCElement[nTabIndex+1]-aTCElement[nTabIndex]);

// Get residual value of real value with integer value:
nResidual := nT_CJ - (nTabIndex * nT_ResTab + nT_start);

// Calculate slope nSlope = DY / DX:
nSlope := nDiff_U_node2node/nT_ResTab;

// Calculate interpolated voltage of the cold junction (m*x+b):
nU_CJ := nSlope * nResidual + aTCElement[nTabIndex];
// ========================================================================

// 2. Add this value to the PDO value:
nU_TC := INT_TO_REAL(nTC_Inputs_Value) + nU_CJ;
// ========================================================================

// 3. Convert calculated voltage to temperature:
// ========================================================================
//  Search index of higher target node: 
nTabIndex := 0;
 // Loop as long U TC is greater than a node:
WHILE nU_TC > aTCElement[nTabIndex] DO
   nTabIndex := nTabIndex + 1;
END_WHILE
// Loop ended with resulting nTabIndex

IF nTabIndex = 0 THEN
   // Temperature is below first table entry: end here
   nT_Result := nT_start;
ELSE
   // Voltage difference between U_TC and lower target node
   nDiff_U_node2U_TC := nU_TC - aTCElement[nTabIndex-1];
   
   // Voltage difference between two target nodes with U_TC nested between them:
   nDiff_U_node2node := aTCElement[nTabIndex]-aTCElement[nTabIndex-1];
   
   // Relation of the two differencies:
   nRelation := nDiff_U_node2U_TC/nDiff_U_node2node;
   
   // Resulting temperature in 0.1°C resoltion:
   nT_Result := REAL_TO_INT(nT_start + (nRelation+nTabIndex-1) * nT_ResTab);
END_IF