s7-SCL-scripts/dew-point-calulator.md

137 lines
3 KiB
Markdown
Raw Permalink Normal View History

2026-07-13 10:23:43 +00:00
```
2026-07-13 10:23:21 +00:00
FUNCTION "FC_DewPoint" : Void
{ S7_Optimized_Access := 'TRUE' }
VAR_INPUT
Temperature_C : Real; // Air temperature in degrees Celsius
Humidity_RH : Real; // Relative humidity in percent: > 0 to 100
END_VAR
VAR_OUTPUT
DewPoint_C : Real; // Calculated dew point in degrees Celsius
Valid : Bool; // TRUE when calculation is valid
END_VAR
VAR_TEMP
Gamma : Real;
END_VAR
VAR_CONSTANT
B : Real := 17.625;
C : Real := 243.04;
END_VAR
BEGIN
// Validate the input range.
// RH must be greater than zero because LN(0) is undefined.
#Valid :=
(#Temperature_C >= -40.0) AND
(#Temperature_C <= 50.0) AND
(#Humidity_RH > 0.0) AND
(#Humidity_RH <= 100.0);
IF #Valid THEN
// Gamma =
// LN(RH / 100) + (B * Temperature) / (C + Temperature)
#Gamma :=
LN(#Humidity_RH / 100.0)
+
((#B * #Temperature_C) /
(#C + #Temperature_C));
// Dew point =
// (C * Gamma) / (B - Gamma)
#DewPoint_C :=
(#C * #Gamma) /
(#B - #Gamma);
ELSE
#Gamma := 0.0;
#DewPoint_C := 0.0;
END_IF;
2026-07-13 10:30:43 +00:00
END_FUNCTION
```
# Buck version
```
FUNCTION "FC_DewPoint_Buck" : Void
{ S7_Optimized_Access := 'TRUE' }
VAR_INPUT
Temperature_C : Real; // Air temperature in °C
Humidity_RH : Real; // Relative humidity in %
END_VAR
VAR_OUTPUT
DewPoint_C : Real; // Dew point in °C
Valid : Bool;
END_VAR
VAR_TEMP
T : LReal;
RH : LReal;
SaturationVP : LReal;
ActualVP : LReal;
S : LReal;
Discriminant : LReal;
Td : LReal;
END_VAR
BEGIN
// RH must be greater than zero because LN(0) is undefined.
#Valid :=
(#Humidity_RH > 0.0) AND
(#Humidity_RH <= 100.0);
IF #Valid THEN
#T := REAL_TO_LREAL(#Temperature_C);
#RH := REAL_TO_LREAL(#Humidity_RH);
// Buck saturation vapour pressure over liquid water.
// Result is in hPa.
#SaturationVP :=
6.1121 *
EXP(
(18.678 - (#T / 234.5)) *
(#T / (257.14 + #T))
);
// Actual water vapour pressure.
#ActualVP :=
(#RH / 100.0) * #SaturationVP;
// Intermediate logarithmic value.
#S :=
LN(#ActualVP / 6.1121);
// Part below the square root.
#Discriminant :=
((18.678 - #S) * (18.678 - #S))
-
((4.0 * 257.14 * #S) / 234.5);
IF #Discriminant >= 0.0 THEN
#Td :=
(234.5 / 2.0) *
(
18.678
- #S
- SQRT(#Discriminant)
);
#DewPoint_C := LREAL_TO_REAL(#Td);
ELSE
#DewPoint_C := 0.0;
#Valid := FALSE;
END_IF;
ELSE
#DewPoint_C := 0.0;
END_IF;
2026-07-13 10:23:43 +00:00
END_FUNCTION
```