FUNCTION_BLOCK "ProgramAlarmGenerator"
TITLE = Handling ProgramAlarm
{ S7_Optimized_Access := 'TRUE' }
FAMILY : General
VERSION : 1.0
VAR_INPUT
AlarmSignal { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // zu überwachendes Signal
Acknowledge { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Quittierung
AutoQuit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // 0 = Quittierung mit Quitt-Signal; 1 = Automatische Quittierung
SimulationOn { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Simulation ist eingeschaltet
ResetAlarmWithSimulation { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Störung bei Simulation rücksetzen/ ignorieren
END_VAR
VAR_OUTPUT
ProgramAlarmActive { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // ProgramAlarm aktiv
AlarmNumberCycle { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt; // Fortlaufende Alarmnummer in der Aufrufreihenfolge
ErrorProgramAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Fehler ProgramAlarm
StatusProgramAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word; // Status ProgramAlarm
ErrorGetAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Fehler GetAlarm
StatusGetAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word; // Status GetAlarmState
AlarmStateGetAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Byte; // Status ProgramAlarm vom GetAlarm Baustein (86 = Alarm inaktiv, 87 = Alarm aktiv)
END_VAR
VAR_IN_OUT
SetElementMessageType { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Ausgang um Element-Meldungstyp zu setzen (Error/ Warning/ Information..)
InstanceProgramAlarm {InstructionName := 'Program_Alarm'; LibVersion := '1.0'; S7_HiddenAssignment := 'Show'} : Program_Alarm; // ProgramAlarm Instanz
AdditionalValue1 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 1 ProgramAlarm
AdditionalValue2 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 2 ProgramAlarm
AdditionalValue3 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 3 ProgramAlarm
AdditionalValue4 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 4 ProgramAlarm
AdditionalValue5 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 5 ProgramAlarm
AdditionalValue6 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 6 ProgramAlarm
AdditionalValue7 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 7 ProgramAlarm
AdditionalValue8 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 8 ProgramAlarm
AdditionalValue9 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 9 ProgramAlarm
AdditionalValue10 { S7_HiddenAssignment := 'Hide'; S7_PredefinedAssignment := 'NULL'; S7_ShowAssignmentIfParamsNotIdentical := 'true'} : Variant; // Begleitwert 10 ProgramAlarm
END_VAR
VAR
TriggerAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Program Alarm auslösen
ResetAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Program Alarm zurücksetzen
LastSignalProgramAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Signal für Program Alarm vom vorherigen Zyklus
TimestampProgramAlarm { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : LDT; // Zeitstempel Program Alarm Telegramme wiederholen
GetAlarmStateAfterTrigger { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Status Program Alarm nach dem Triggern auslesen
GetAlarmStateAfterReset { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Status Program Alarm nach dem Rücksetzen auslesen
StorageProgramAlarmActive { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Speichervariable ProgramAlarm aktiv
LastSignalExportActive { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Signal für ExportActive vom vorherigen Zyklus
END_VAR
VAR_TEMP
signalProgramAlarm : Bool; // Signal für Program Alarm
END_VAR
VAR CONSTANT
ALARM_INACTIVE : Byte := 16#86; // ProgramAlarm ist inaktiv
ALARM_ACTIVE : Byte := 16#87; // ProgramAlarm ist aktiv
END_VAR
BEGIN
REGION Program Alarm
// init
#ErrorProgramAlarm := #ErrorGetAlarm := FALSE;
#StatusProgramAlarm := 0;
// Quittierung Program Alarm mit Quitt bzw. AutoQuit
IF #Acknowledge OR (#AutoQuit AND NOT #AlarmSignal) OR (#SimulationOn AND #ResetAlarmWithSimulation) THEN
#StorageProgramAlarmActive := FALSE;
END_IF;
// Störungssignal verarbeiten
IF #AlarmSignal AND NOT (#SimulationOn AND #ResetAlarmWithSimulation) THEN
#StorageProgramAlarmActive := TRUE;
END_IF;
// Ausgang für Platz gestört setzen
IF #StorageProgramAlarmActive THEN
#SetElementMessageType := TRUE;
END_IF;
// Status Alarmbit ausgeben
#ProgramAlarmActive := #StorageProgramAlarmActive;
// Alarmzähler hochzählen
"General".ProgramAlarm.CounterProgramAlarms += 1;
#AlarmNumberCycle := "General".ProgramAlarm.CounterProgramAlarms;
// Trigger für Alarm bilden
#signalProgramAlarm := ((#StorageProgramAlarmActive AND NOT "General".ProgramAlarm.ExportActive) OR ("General".ProgramAlarm.SetAllErrorMessages AND "General".ProgramAlarm.CounterProgramAlarms < ("General".ProgramAlarm.StartNumberSetMessage + "General".ProgramAlarm.CountSetMessages) AND "General".ProgramAlarm.CounterProgramAlarms >= "General".ProgramAlarm.StartNumberSetMessage)) AND NOT "General".ProgramAlarm.ActivateAlarmsAfterFirstScan;
// Flanke SetAllErrorMessages überwachen => Trigger ablöschen
IF "General".ProgramAlarm.ExportActive AND NOT #LastSignalExportActive THEN
#TriggerAlarm := FALSE;
END_IF;
#LastSignalExportActive := "General".ProgramAlarm.ExportActive;
// prüfen ob Alarm ausgelöst oder quittiert werden soll
IF #signalProgramAlarm AND NOT #LastSignalProgramAlarm AND NOT #TriggerAlarm THEN
#TriggerAlarm := TRUE;
#TimestampProgramAlarm := "General".DateAndTimeUtc;
ELSIF NOT #signalProgramAlarm AND #LastSignalProgramAlarm AND NOT #ResetAlarm THEN
#ResetAlarm := TRUE;
#TimestampProgramAlarm := "General".DateAndTimeUtc;
END_IF;
// Alarm auslösen oder quittieren
IF #TriggerAlarm AND "General".ProgramAlarm.MessageCounter < "MESSAGES_PER_CYCLE" THEN
#InstanceProgramAlarm(SIG := TRUE,
TIMESTAMP := #TimestampProgramAlarm,
SD_1 := #AdditionalValue1,
SD_2 := #AdditionalValue2,
SD_3 := #AdditionalValue3,
SD_4 := #AdditionalValue4,
SD_5 := #AdditionalValue5,
SD_6 := #AdditionalValue6,
SD_7 := #AdditionalValue7,
SD_8 := #AdditionalValue8,
SD_9 := #AdditionalValue9,
SD_10 := #AdditionalValue10,
Status => #StatusProgramAlarm,
Error => #ErrorProgramAlarm);
#GetAlarmStateAfterTrigger := TRUE;
"General".ProgramAlarm.MessageCounter := "General".ProgramAlarm.MessageCounter + 1;
ELSIF #ResetAlarm AND "General".ProgramAlarm.MessageCounter < "MESSAGES_PER_CYCLE" THEN
#InstanceProgramAlarm(SIG := FALSE,
TIMESTAMP := #TimestampProgramAlarm,
SD_1 := #AdditionalValue1,
SD_2 := #AdditionalValue2,
SD_3 := #AdditionalValue3,
SD_4 := #AdditionalValue4,
SD_5 := #AdditionalValue5,
SD_6 := #AdditionalValue6,
SD_7 := #AdditionalValue7,
SD_8 := #AdditionalValue8,
SD_9 := #AdditionalValue9,
SD_10 := #AdditionalValue10,
Status => #StatusProgramAlarm,
Error => #ErrorProgramAlarm);
#GetAlarmStateAfterReset := TRUE;
"General".ProgramAlarm.MessageCounter := "General".ProgramAlarm.MessageCounter + 1;
END_IF;
// Status Program Alarm nach dem Auslösen prüfen
IF #GetAlarmStateAfterTrigger OR #GetAlarmStateAfterReset THEN
Get_AlarmState(Alarm := #InstanceProgramAlarm,
AlarmState => #AlarmStateGetAlarm,
Error => #ErrorGetAlarm,
STATUS => #StatusGetAlarm);
IF #TriggerAlarm AND #GetAlarmStateAfterTrigger AND #AlarmStateGetAlarm = #ALARM_ACTIVE THEN
#TriggerAlarm := FALSE;
#GetAlarmStateAfterTrigger := FALSE;
IF NOT #signalProgramAlarm THEN
#ResetAlarm := TRUE;
END_IF;
// Status Program Alarm nach dem Rücksetzen prüfen
ELSIF #ResetAlarm AND #GetAlarmStateAfterReset AND #AlarmStateGetAlarm = #ALARM_INACTIVE THEN
#ResetAlarm := FALSE;
#GetAlarmStateAfterReset := FALSE;
IF #signalProgramAlarm THEN
#TriggerAlarm := TRUE;
END_IF;
END_IF;
END_IF;
// Trigger Signal für Flankenauswertung speichern
#LastSignalProgramAlarm := #signalProgramAlarm;
// ProgramAlarmError
IF NOT "General".ProgramAlarm.ProgramAlarmError.Active AND #ErrorProgramAlarm AND #StatusProgramAlarm <> 16#80C4 THEN
"General".ProgramAlarm.ProgramAlarmError.Active := TRUE;
"General".ProgramAlarm.ProgramAlarmError.State := #StatusProgramAlarm;
"General".ProgramAlarm.ProgramAlarmError.AlarmNumberCycle := #AlarmNumberCycle;
END_IF;
// GetAlarmError
IF NOT "General".ProgramAlarm.GetAlarmError.Active AND #ErrorGetAlarm THEN
"General".ProgramAlarm.GetAlarmError.Active := TRUE;
"General".ProgramAlarm.GetAlarmError.State := #StatusProgramAlarm;
"General".ProgramAlarm.GetAlarmError.AlarmNumberCycle := #AlarmNumberCycle;
END_IF;
END_REGION
END_FUNCTION_BLOCK