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

3 KiB

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;

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;

END_FUNCTION