254 lines
9.7 KiB
Markdown
254 lines
9.7 KiB
Markdown
|
|
## 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
|
|
|
|
```scl
|
|
// 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
|
|
|
|
|
|
|
|
|
|
```pascal
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
``` |