Beispielprogramm zur individuellen Temperaturberechnung in der PLC

Die Klemmen der Serie EL331x-xxxx dienen zur bequemen Temperaturmessung mit Thermoelementen. Dazu haben sie diverse Umrechnungstabellen für verschiedene Thermoelement-Typen sowie auch eine interne Kaltstellenmessung implementiert. Ggf. soll aber ein besonderer Thermoelementtyp verwendet werden, der nicht in der Firmware hinterlegt ist. Dann bietet sich bei den EL331x der folgende Weg an:

Dieser Rechenweg der Kaltstellen-Kompensation (engl: CJC, Cold Junction Compensation) entspricht in etwa dem was für die implementierten Typen in der Klemme hinterlegt ist.

Das Beispielprogramm realisiert einen solchen Vorgang und liefert einen Temperaturwert unter Berücksichtigung der kanalweisen Kaltstellentemperatur aus dem CoE. Beispielhaft wird die Klemme zwischen Spannungsmessung und Temperaturmessung im Typ K kontinuierlich umgeschaltet, damit dadurch ein Vergleich beider Temperaturwerte ermöglicht wird. Im Folgenden ist eine Aufzeichnung der Messwerte von Kanal 1 der EL3314 an Typ K Thermoelement mit dem TwinCAT Scope dargestellt (Einheit in 0,1 °C):

Beispielprogramm zur individuellen Temperaturberechnung in der PLC 1:
Blau: Temperaturwerte aus der PLC-Berechnung; Rot: PDO-Werte im Temperaturmessbereich

Hinweise:

Beispielprogramm zur individuellen Temperaturberechnung in der PLC 2:
Aufbau zum Beispielprogramm zur „separaten Temperaturberechnung mit CJC in der PLC“

Download: Programmlink

Vorbereitungen zum Starten des Beispielprogramms (tnzip-Datei/TwinCAT 3)

Ausschnitt aus dem Beispielprogramm:

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