Obsidean_VM/04-SIDEL/09 - SAE452 - Diet as Regul.../FB2121 - Read AI 4.20ma/FB2121 - Analog Input 4-20m...

9.7 KiB

Purpose

Function block for managing 4-20mA analog inputs with error detection and automatic recovery. Designed for SIMATIC S7-315 systems.

Hardware Requirements

  • Module: SIMATIC ET 200S 2AI I 4WIRE ST (6ES7 134-4GB11-0AB0)
  • Range: 4-20mA
  • Connection: 4-wire configuration

Interface

Input

Parameter Type Description
i_IW_Analog WORD Raw analog input value (PEW)

Outputs

Parameter Type Description
o_CurrentMa REAL Current value in mA
o_ErrorCode INT Error code (0=OK, higher values = higher severity)

Error Codes (Priority Order)

Code Severity Description Current Output
0 OK Normal range (4-20mA) Calculated value
1 WARNING Overload range (20-22.8mA) Calculated value
2 WARNING Underload range (3.9995-4mA) Calculated value
10 ERROR Overflow (>22.8mA) 22.8142mA
11 ERROR Underflow (<3.9995mA) 3.9995mA
20 CRITICAL Wire Break (32767 value) 22.8142mA
99 CRITICAL Undefined range 3.9995mA

Error Recovery Behavior

Cooldown Mechanism

  • When a critical error (code ≥10) is resolved, a 500ms cooldown period begins
  • During cooldown: previous error code and current value are maintained
  • After cooldown: automatic reset to normal operation
  • No manual reset required

Current Value Logic

  • Normal operation: Calculated using linear conversion: mA = 4 + (AnalogValue / 27648) * 16
  • Error conditions: Fixed logical values based on error type
  • Value limits: Always constrained between 3.9995mA and 22.8142mA

Usage Example

// Instance declaration
VAR
    AnalogInput_Measurement : FB_AnalogMeasurement;
    InputValue : WORD;
    CurrentMa : REAL;
    ErrorStatus : INT;
END_VAR

// Function block call
AnalogInput_Measurement(
    i_IW_Analog := InputValue,      // Connect to PEW address
    o_CurrentMa => CurrentMa,       // Current in mA
    o_ErrorCode => ErrorStatus      // Error monitoring
);

// Error handling example
CASE ErrorStatus OF
    0: // Normal operation
    1,2: // Warnings - operation continues
    10,11,20,99: // Critical errors - check wiring/module
END_CASE;

Key Features

  • Simplified operation: No diagnostic configuration required
  • Automatic recovery: 500ms cooldown with self-reset
  • Prioritized error handling: ELSIF logic ensures most critical errors take precedence
  • Logical fallback values: Sensible current values during error conditions
  • No memory: Stateless operation after cooldown period

// FB2121 - Simplified 4-20mA Analog Measurement Management
// Required hardware configuration:
// - SIMATIC ET 200S 2AI I 4WIRE ST (6ES7 134-4GB11-0AB0)
// - Range: 4-20mA

FUNCTION_BLOCK "FB_AnalogMeasurement"
TITLE = 'Simplified 4-20mA analog input management'
AUTHOR : tk
FAMILY : Process

VAR_INPUT
    i_IW_Analog : WORD;                 // Analog input value (PEW)
END_VAR

VAR_OUTPUT
    o_CurrentMa : REAL;                 // Current value in mA
    o_ErrorCode : INT;                  // Error code (0=OK, increasing priority by severity)
END_VAR

VAR
  
    // Internal variables
    AnalogValueInt : INT;               // Analog value converted to INT
    CurrentErrorCode : INT;             // Current error code
    PreviousErrorCode : INT;            // Previous error code for cooldown
    PreviousCurrentMa : REAL;           // Previous current value for cooldown
    
    // Timer for 500ms cooldown
    CooldownTimer : TON;
    CooldownTime : TIME := T#500MS;     // 500ms cooldown
    InCooldown : BOOL;                  // Flag indicating if in cooldown
END_VAR

VAR_TEMP
    TempReal : REAL;                    // Temporary value for floating point calculations
END_VAR

CONST
    // Constants definition according to 4-20mA analog module documentation
    OVERFLOW_VALUE  := 32767;           // 7FFFH - Overflow/wire break value
    UNDERFLOW_VALUE := -32768;          // 8000H - Underflow value
    UNDERFLOW_DIAG  := -32767;          // 8001H - Underflow with diagnostics enabled
    MAX_NORMAL := 27648;                // 6C00H - 20mA (maximum value in nominal range)
    MIN_NORMAL := 0;                    // 0000H - 4mA (minimum value in nominal range)
    RANGE_HIGH := 32511;                // 7EFFH - 22.8142mA (overload range start)
    RANGE_LOW := -1;                    // FFFFH - 3.9995mA (underload range end)
    
    // Logical values for extreme conditions
    OVERFLOW_MA_VALUE := 22.8142;       // mA value for overflow
    UNDERFLOW_MA_VALUE := 3.9995;       // mA value for underflow

END_CONST


BEGIN
    // Convert WORD value to INT for processing
    AnalogValueInt := WORD_TO_INT(i_IW_Analog);
    
    // ========================================================================================
    // ANALOG VALUE ANALYSIS AND ERROR CODE DETERMINATION (ELSIF PRIORITY)
    // ========================================================================================
    // Error codes by priority (0=OK, increasing numbers = higher severity):
    // 0 = OK - Nominal range (4-20mA)
    // 1 = WARNING - Overload range (20-22.8mA) 
    // 2 = WARNING - Underload range (3.9995-4mA)
    // 10 = ERROR - Overflow (>22.8mA or 32767)
    // 11 = ERROR - Underflow (<3.9995mA or negative values)
    // 20 = CRITICAL - Wire Break (32767 confirmed)
    // 99 = CRITICAL - Undefined range
    
    // ELSIF list with concurrent error priority (from most severe to least severe)
    IF AnalogValueInt = OVERFLOW_VALUE THEN                         // 32767 (7FFFH) - Most critical
        CurrentErrorCode := 20;                                     // Wire Break
        
    ELSIF AnalogValueInt = UNDERFLOW_VALUE OR 
          AnalogValueInt = UNDERFLOW_DIAG THEN                      // -32768 or -32767
        CurrentErrorCode := 11;                                     // Critical underflow
        
    ELSIF AnalogValueInt > RANGE_HIGH THEN                          // > 32511 (overflow)
        CurrentErrorCode := 10;                                     // Overflow
        
    ELSIF AnalogValueInt < RANGE_LOW THEN                           // < -1 (underflow)
        CurrentErrorCode := 11;                                     // Underflow
        
    ELSIF AnalogValueInt > MAX_NORMAL AND 
          AnalogValueInt <= RANGE_HIGH THEN                         // Overload range
        CurrentErrorCode := 1;                                      // Warning overload
        
    ELSIF AnalogValueInt < MIN_NORMAL AND 
          AnalogValueInt >= RANGE_LOW THEN                          // Underload range
        CurrentErrorCode := 2;                                      // Warning underload
        
    ELSIF AnalogValueInt >= MIN_NORMAL AND 
          AnalogValueInt <= MAX_NORMAL THEN                         // Nominal range
        CurrentErrorCode := 0;                                      // OK
        
    ELSE                                                            // Any other case
        CurrentErrorCode := 99;                                     // Undefined range
    END_IF;
    
    // ========================================================================================
    // 500MS COOLDOWN MANAGEMENT
    // ========================================================================================
    
    // Detect transition from error to no-error to start cooldown
    IF PreviousErrorCode >= 10 AND CurrentErrorCode < 10 THEN
        InCooldown := TRUE;
        CooldownTimer(IN := TRUE, PT := CooldownTime);
    END_IF;
    
    // Manage cooldown timer
    CooldownTimer(IN := InCooldown, PT := CooldownTime);
    
    // End cooldown when timer expires
    IF CooldownTimer.Q THEN
        InCooldown := FALSE;
        CooldownTimer(IN := FALSE, PT := CooldownTime);
    END_IF;
    
    // ========================================================================================
    // ERROR CODE AND CURRENT VALUE ASSIGNMENT
    // ========================================================================================
    
    // If in cooldown, maintain previous error and current
    IF InCooldown THEN
        o_ErrorCode := PreviousErrorCode;
        o_CurrentMa := PreviousCurrentMa;
    ELSE
        // Assign current error code
        o_ErrorCode := CurrentErrorCode;
        
        // Assign current value based on detected error
        IF CurrentErrorCode = 20 OR CurrentErrorCode = 10 THEN      // Wire Break or Overflow
            o_CurrentMa := OVERFLOW_MA_VALUE;                       // 22.8142mA
            
        ELSIF CurrentErrorCode = 11 THEN                            // Underflow
            o_CurrentMa := UNDERFLOW_MA_VALUE;                      // 3.9995mA
            
        ELSIF CurrentErrorCode = 99 THEN                            // Undefined range
            o_CurrentMa := UNDERFLOW_MA_VALUE;                      // 3.9995mA (safe value)
            
        ELSE
            // Normal calculation for OK and WARNING ranges: mA = 4 + (AnalogValueInt / 27648) * 16
            TempReal := INT_TO_REAL(AnalogValueInt);
            o_CurrentMa := 4.0 + (TempReal / INT_TO_REAL(MAX_NORMAL)) * 16.0;
            
            // Limit to logical maximum and minimum values
            IF o_CurrentMa < UNDERFLOW_MA_VALUE THEN
                o_CurrentMa := UNDERFLOW_MA_VALUE;                  // Minimum: 3.9995mA
            ELSIF o_CurrentMa > OVERFLOW_MA_VALUE THEN
                o_CurrentMa := OVERFLOW_MA_VALUE;                   // Maximum: 22.8142mA
            END_IF;
        END_IF;
        
        // Save values for next cycle
        PreviousErrorCode := CurrentErrorCode;
        PreviousCurrentMa := o_CurrentMa;
    END_IF;
    
END_FUNCTION_BLOCK