Hilfe bei einem FB (SCL) bin ich hier richtig? Sorry, bin neu hier...

Zuviel Werbung?
-> Hier kostenlos registrieren
Aber noch eins @Thomas: kannst Du mir vielleicht noch ein wenig genauer erklären was da genau passiert?

Grundsätzlich sollte dir erstmal klar sein dass die TON-Funktionen Einschaltverzögerungen sind.
Also ist IN = true, dann wird nach Ablauf von PT der Ausgang Q gesetzt.

In der FOR-Schleife wird geprüft ob ein Fehler aktiv ist.
Die Prüfung erfolgt nur wenn der Timer für die Pausenzeit zwischen den Impulsen abgelaufen ist.
Das ist der Fall wenn kein Blink-Job mehr aktiv ist und die Zeit abgelaufen ist.

In der For-Schleife wird nun geprüft ob ein Fehlereingang true ist. Ist das der Fall, wird in die Variable BLINK_JOB die
Anzahl der Blinkvorgänge eintragen. Da das Array bei 0 beginnt, muss zum Schleifenindex i noch die 1 hinzuaddiert werden, denn wenn Fehler_1 aktiv ist soll ja auch einmal geblinkt werden.

Jetzt könnte man im einfachsten Fall wenn immer nur der erste Fehler angezeigt werden soll, die Schleife abbrechen werden und zum Blinken
übergehen. Da aber auch die folgenden Fehler angezeigt werden sollen, muss man sich merken welcher Blink-Job schon bearbeitet wurde.
Dieser Zustand wird in der Variable LAST_JOB gespeichert. Beim nächsten Schleifendurchlauf dient dieser Variablenwert
als Startwert für den Schleifenindex i. Mit EXIT wird die Schleife abgebrochen, es wird also direkt hinter der Zeile mit
dem END_FOR; mit der Bearbeitung fortgesetzt (quasi wie ein Sprung). Die Prüfungen von LAST_JOB und das Setzen auf Null dient dazu bei einem Überlauf wieder mit Index 0 zu beginnen.
Du kannst dir einfach mal die Variablenwerte während das Programm läuft im Instanz-DB ansehen, dann siehst du wie das funktioniert.

Der Rest des Programmes sind die Aufrufe der Timer-Bausteine, eine Flankenauswertung die zählt wie oft geblinkt wurde und den BLINK_JOB entsprechend herunterzählt.
 
Da aber auch die folgenden Fehler angezeigt werden sollen, muss man sich merken welcher Blink-Job schon bearbeitet wurde.
Dieser Zustand wird in der Variable LAST_JOB gespeichert. Beim nächsten Schleifendurchlauf dient dieser Variablenwert
als Startwert für den Schleifenindex i. Mit EXIT wird die Schleife abgebrochen, es wird also direkt hinter der Zeile mit
dem END_FOR;

Zuerst einmal möchte ich feststellen, dass Deine Lösung komplett aussieht und ich nicht daran rummäkeln will. Trotzdem glaube ich, dass die von mir vorgeschlagene Lösung ohne Schleifenbefehle und dafür mit inkrementieren des Index irgendwie "charmanter" daherkommt. Mich würde halt interessieren, wie die Anderen hier im Forum das machen würden. Was wäre denn die "elegantere" Lösung? Ich möchte halt einfach dazulernen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich habe mir das jetzt mal durch gelesen und würde selbst stark zu einer for-i-schleifen tendieren, sowas haben wir für saia-steuerungen schon mal gemacht, um hardwarediagnosse abzufahren, das problem mit dem EINEN FEHLER ist ansich einfach zu umgehen, man muß in der schleife einen zweites inkrement führen, welches angibt welcher array-datenbereich zuletzt ausgegeben wurde, das zweite inkrement ist dann nach beendigung des blinkjobs (oder wenn kein fehler vorhanden) direkt nach auswertung zu inkrementieren

also strukturell wäre es halt ne kombination aus case und for-i

hoffe ihr könnt mir folgen, evtl. kann ich meinen löungsweg ja mal aufbereiten, weiß nur nicht wann ich das schaffe
 
Zuletzt bearbeitet:
Vielen Dank nochmals an Thomas, sehr hilfreich!

Ich kämpfe aber an nochwas weil mir aufgefallen ist (wie immer erst im Nachhinein) das ich was vergessen hab :confused:

- es fehlt der resetbare Störpiepserausgang (piepst mit 1HZ bei neuer Fehlerflanke -lässt sich aber trotz weiter anstehendem Fehler mit Resettaster ausschalten)
- die Resettasterbeleuchtung (Ausgang leuchtet sobald Stoerung ansteht bis alle weg sind)
- der Tastereingang RESET (Stoerungen MÜSSEN erst resettet werden bevor Ausgang wieder schaltet -> kein selbständiger Wideranlauf)
- Eingang Baustein aktiv (zum Start damit wenn Anlage aus ist nix blinkt da bin ich grad mit Label und GOTO am rumprobieren allerdings wenn ich einen Sprung direkt vor END_FUNKTION_BLOCK mache dann meckert er, warum?)
 
- Eingang Baustein aktiv (zum Start damit wenn Anlage aus ist nix blinkt da bin ich grad mit Label und GOTO am rumprobieren allerdings wenn ich einen Sprung direkt vor END_FUNKTION_BLOCK mache dann meckert er, warum?)

Versuch mal


label**:
;
END_FUNCTION_BLOCK



Der Rest.. sollte kein Problem sein, wenn man den Code von Thomas verstanden hat.. wo scheiterts denn da im Detail?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
- Eingang Baustein aktiv (zum Start damit wenn Anlage aus ist nix blinkt da bin ich grad mit Label und GOTO am rumprobieren allerdings wenn ich einen Sprung direkt vor END_FUNKTION_BLOCK mache dann meckert er, warum?)

Mit einem GOTO einfach das Programm überspringen halte ich für keine gute Lösung. Denn wenn zufällig vor dem Überspringen die Lampe angesteuert wurde, würde diese die ganze Zeit anstehen wenn du einfach die Zuweisung überspringst.
Besser ist es das mit einer If-Abfrage zu machen, und nach dem Schema:
Code:
If NichtAktiv Then
    Lampen aus;
    Alles andere notwendige zurücksetzen oder auf Startwerte setzen;
Else
    Normale Auswertung;
End If;
 
Hallo zusammen also jetzt muss ich mich aber aufs Ohr hauen (leider :-(), hier mal wie weit ich gekommen bin.....

Der "Keine_Stoerung" Ausgang macht mir noch Probleme...... (und vor allem im Moment wenn ich Reset drücke wird er 1 trotz anstehendem Fehler!!!)

Code:

FUNCTION_BLOCK FB804 // FB für Fehlerauswertung
CONST
ANZ := 9;
END_CONST
VAR_INPUT
Baustein_aktiv: BOOL; // Baustein wird aktiviert
Fehler1: BOOL; // Fehlerzustand1 = 1x blinken (1Hz) und 5sec Pause
Fehler2: BOOL; // Fehlerzustand2 = 2x blinken (1Hz) und 5sec Pause
Fehler3: BOOL; // Fehlerzustand3 = 3x blinken (1Hz) und 5sec Pause
Fehler4: BOOL; // Fehlerzustand4 = 4x blinken (1Hz) und 5sec Pause
Fehler5: BOOL; // Fehlerzustand5 = 5x blinken (1Hz) und 5sec Pause
Fehler6: BOOL; // Fehlerzustand6 = 6x blinken (1Hz) und 5sec Pause
Fehler7: BOOL; // Fehlerzustand7 = 7x blinken (1Hz) und 5sec Pause
Fehler8: BOOL; // Fehlerzustand8 = 8x blinken (1Hz) und 5sec Pause
Fehler9: BOOL; // Fehlerzustand9 = 9x blinken (1Hz) und 5sec Pause
Fehler10: BOOL; // Fehlerzustand10 = 10x blinken (1Hz) und 5sec Pause
Reseteingang: BOOL; // Reset für Fehler und Stoerpiepser
Ueberbrueckungszeit: TIME; // Eingabe der Überbrückungszeit im Fehlerfall bei drücken des Resettasters
END_VAR
VAR_OUTPUT
LED: BOOL; // Blinkauswertung des anstehenden Fehler (eine LED)
Piepser: BOOL; // Akustische Fehlermeldung
Sammelstoerung: BOOL; // Visuelle Fehleranzeige am Resettaster
Keine_Stoerung: BOOL; // Stoerungsfreier Ausgang
END_VAR

VAR
T_Blink_E: TON;
T_Blink_P: TON;
T_PAUSE: TON;
BLINK_JOB: INT;
LAST_JOB: INT;
HM_P: BOOL;
Alarmueberbrueckung: TOF;
Keine_Stoerung_FRG: BOOL;
FM2_ok: BOOL; //Flankenmerker ok
FM1_err: BOOL; //Klankenmerker störung
END_VAR
VAR_TEMP
Fehler: ARRAY[0..10]OF BOOL;
i: INT;
BEGIN;
Fehler[0] := Fehler1;
Fehler[1] := Fehler2;
Fehler[2] := Fehler3;
Fehler[3] := Fehler4;
Fehler[4] := Fehler5;
Fehler[5] := Fehler6;
Fehler[6] := Fehler7;
Fehler[7] := Fehler8;
Fehler[8] := Fehler9;
Fehler[9] := Fehler10;

// Auf Fehler prüfen und Blink-Job eintragen
IF T_PAUSE.Q THEN // Kein Blinkauftrag aktiv und Pausenzeit abgelaufen
FOR i := LAST_JOB TO ANZ DO
IF Fehler = true THEN // Fehler steht an, dann
BLINK_JOB := i + 1; // Nummer als "Blink-Job" eintragen = Anzahl Blinken
LAST_JOB := BLINK_JOB; // damit bei nächstem Schleifendurchlauf mit nächstem Fehler fortgesetzt wird.
IF LAST_JOB > ANZ THEN
LAST_JOB := 0;
END_IF;
EXIT; // Schleife verlassen und Blink-Job abarbeiten
END_IF;
END_FOR;
IF i > ANZ THEN // Wenn kein Blink-Job eingetragen (Schleife ist durchgelaufen)
LAST_JOB := 0; // dann beim nächsten mal bei 0 beginnen
END_IF;
END_IF;

// Blink-Job abarbeiten
// Timer Einschaltdauer LED
T_BLINK_E(
IN := NOT T_BLINK_P.Q AND BLINK_JOB > 0,
PT := T#300ms
);
// Timer Ausschaltdauer LED
T_BLINK_P(
IN := T_BLINK_E.Q,
PT := T#300ms
);
// Timer Pausenzeit zwischen Blinkjobs
T_PAUSE(
IN := BLINK_JOB = 0,
PT := T#2s
);
// Anzahl blinken zählen
IF NOT T_BLINK_E.Q AND HM_P THEN
BLINK_JOB := BLINK_JOB - 1;
END_IF;
HM_P := T_BLINK_E.Q;

LED := NOT T_BLINK_E.Q AND BLINK_JOB > 0;

// Freigabe des Ausgangs bei Fehlerfreiem Zustand
IF NOT Fehler1 AND NOT Fehler2 AND NOT Fehler3 AND NOT Fehler4 AND NOT Fehler5 AND NOT Fehler6 AND NOT Fehler7 AND NOT Fehler8 AND NOT Fehler9 AND NOT Fehler10 THEN Keine_Stoerung_FRG :=true;
ELSE Keine_Stoerung_FRG :=false;
END_IF;


// ----------------> Ab hier die neuen Funktionen......
//Hier soll die Sammelstoerung (Störmeldeleuchte des Resettasters) angesteuert werden, immer wenn ein Fehler besteht und nur bei Fehlerfreiheit ausgehen:
IF Fehler = true THEN Sammelstoerung:=true;
ELSE Sammelstoerung:=false;
END_IF;

//Hier sollen die Ausgänge abgeschalten werden wenn der Baustein inaktiv ist:
IF NOT Baustein_aktiv THEN LED:=false; Piepser:=false; Sammelstoerung:=false; Keine_Stoerung:=false;
// wie bestimme ich jetzt dass ELSE der normale Zyklus abgearbeitet wird? Oder passiert das automatisch wenn die Bedingung nicht erfüllt ist?
END_IF;

//Hier soll der Piepser im Takt des Fehlers gesetzt werden und bei drücken des Resettasters eine "gewisse Zeit" (Eingangsparameter) überbrückt werden.... steht er nach der Zeit immernoch an kommt erneut ein Alarm
IF LED AND NOT Alarmueberbrueckung.Q THEN Piepser:=true;
ELSE Piepser:=false;
END_IF;
Alarmueberbrueckung( //Sollte ein Reset betätigt werden erlischt der Alarm und soll nach abgleaufener Zeit wieder melden......-> wenn Fehler noch ansteht!
IN := Reseteingang,
PT := Ueberbrueckungszeit //Überbrückungszeit vorgegeben durch Eingangsparameter
);

//und zu guter letzt die speichernden Fehler dass erst nach drücken des Resettasters der Ausgang wieder gesetzt wird......
// puuuhhh mhhhh grübel...........grrrrrrrrrr
IF BLINK_JOB > 0 THEN Keine_Stoerung:=false;
ELSIF BLINK_JOB = 0 AND FM2_ok THEN Keine_Stoerung:=true;
ELSE Keine_Stoerung:=false;
END_IF;
FM2_ok := Reseteingang AND NOT FM1_err;
FM1_err := Reseteingang AND BLINK_JOB > 0;

END_FUNCTION_BLOCK
 
// ----------------> Ab hier die neuen Funktionen......
//Hier soll die Sammelstoerung (Störmeldeleuchte des Resettasters) angesteuert werden, immer wenn ein Fehler besteht und nur bei Fehlerfreiheit ausgehen:
IF Fehler = true THEN Sammelstoerung:=true;
ELSE Sammelstoerung:=false;
END_IF;

Mach dich doch mal bitte schlau was ein Array ist und was der Index dabei macht..
//Hier sollen die Ausgänge abgeschalten werden wenn der Baustein inaktiv ist:
IF NOT Baustein_aktiv THEN LED:=false; Piepser:=false; Sammelstoerung:=false; Keine_Stoerung:=false;
// wie bestimme ich jetzt dass ELSE der normale Zyklus abgearbeitet wird? Oder passiert das automatisch wenn die Bedingung nicht erfüllt ist?
END_IF;
Wenn Baustein_aktiv = True ist, dann würde ja normal weitergemacht.. Willst du diesen Code am Anfang des Blockes bringen, dann müsstest du dir gedanken machen wie du den restlichen code überspringst.

Stellst du den Code ganz ans Ende, dann würde zwar der Baustein komplett durchlaufen >
ist baustein_aktiv = true = mache normal weiter
ist baustein_aktiv = false= mache alle deine ausgänge aus und gut.

//Hier soll der Piepser im Takt des Fehlers gesetzt werden und bei drücken des Resettasters eine "gewisse Zeit" (Eingangsparameter) überbrückt werden.... steht er nach der Zeit immernoch an kommt erneut ein Alarm
IF LED AND NOT Alarmueberbrueckung.Q THEN Piepser:=true;
ELSE Piepser:=false;
END_IF;
Alarmueberbrueckung( //Sollte ein Reset betätigt werden erlischt der Alarm und soll nach abgleaufener Zeit wieder melden......-> wenn Fehler noch ansteht!
IN := Reseteingang,
PT := Ueberbrueckungszeit //Überbrückungszeit vorgegeben durch Eingangsparameter
);
Hier fehlt noch was, dass dir den Piepser wieder einschaltet? Das Bit Sammelstoerung schreit einen dazu gerade an.


//und zu guter letzt die speichernden Fehler dass erst nach drücken des Resettasters der Ausgang wieder gesetzt wird......
// puuuhhh mhhhh grübel...........grrrrrrrrrr
IF BLINK_JOB > 0 THEN Keine_Stoerung:=false;
ELSIF BLINK_JOB = 0 AND FM2_ok THEN Keine_Stoerung:=true;
ELSE Keine_Stoerung:=false;
END_IF;
FM2_ok := Reseteingang AND NOT FM1_err;
FM1_err := Reseteingang AND BLINK_JOB > 0;
END_FUNCTION_BLOCK

Wie wäre es, wenn du an dieser Stelle ansetzt:
Fehler[0] := Fehler1;
Fehler[1] := Fehler2;
Fehler[2] := Fehler3;
Fehler[3] := Fehler4;
Fehler[4] := Fehler5;
Fehler[5] := Fehler6;
Fehler[6] := Fehler7;
Fehler[7] := Fehler8;
Fehler[8] := Fehler9;
Fehler[9] := Fehler10;
Soetwas in der richtung:
IF Fehler1 THEN
Fehler[0] := true;
ELSE
IF Reset_taster THEN
Fehler[0] := false;
END_IF;


Ganz wichtig! Schau dir an was:
a) Ein Array ist.
b) Wie eine For-Schleife funktioniert!

Morgen schreiben wird einen Test dann muss das sitzen! :p
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du Dir die FOR-Schleife ansiehst, kannst Du gleich dieses Konstrukt "entsorgen", indem Du das mit einer Schleife abfragst. Spätestens bei mehr als 20 Fehlern bekommt man wunde Fingerkuppen oder Augenkrebs :rolleyes:

// Freigabe des Ausgangs bei Fehlerfreiem Zustand
IF NOT Fehler1 AND NOT Fehler2 AND NOT Fehler3 AND NOT Fehler4 AND NOT Fehler5 AND NOT Fehler6 AND NOT Fehler7 AND NOT Fehler8 AND NOT Fehler9 AND NOT Fehler10 THEN Keine_Stoerung_FRG :=true;
ELSE Keine_Stoerung_FRG :=false;
END_IF;

Eigentlich hat sich ja mal wieder gezeigt, dass es wenig Sinn macht einen fertigen Code zu posten der dann zwangsläufig eine Menge neuer Fragen aufwirft. Aber wo wir schon mal dabei sind...

Code:
Keine_Stoerung := TRUE;
FOR i := 1 TO 10 DO
IF Fehler[i] = TRUE THEN
Keine_Stoerung := FALSE;
END_FOR;
Übrigens kannst Du mit der # über Deinem Posting einen Bereich zum Einfügen von Code einfügen. Das macht den Code etwas lesbarer.

Beherzige bitte den Rat und lies die verfügbare Literatur von Siemens. Dein Baustein läd ja förmlich dazu ein, mal so einige Dinge zu probieren, wenn man einen Einstieg sucht.

Weiterhin viel Erfolg!!!
 
Zuletzt bearbeitet:
Soetwas in der richtung:
IF Fehler1 THEN
Fehler[0] := true;
ELSE
IF Reset_taster THEN
Fehler[0] := false;
END_IF;

Oder auch:
Code:
Fehler[0] := Fehler1;
Fehler[1] := Fehler2;
Fehler[2] := Fehler3;
Fehler[3] := Fehler4;
Fehler[4] := Fehler5;
Fehler[5] := Fehler6;
Fehler[6] := Fehler7;
Fehler[7] := Fehler8;
Fehler[8] := Fehler9;
Fehler[9] := Fehler10; 			 		

IF Reset_Taster = TRUE THEN
FOR i := 0 to 9 DO
Fehler[i] := FALSE;
END_FOR;
END_IF;
 
Dankeschön

#
(Ich hoffe das klappt mit der Raute ;-)

Ich möchte mich nochmal vielmals bei Euch bedanken für die super Tipps und guten Hilfestellungen! Ich bin wirklich ein großes Stück weiter gekommen und bin Euch wirklich sehr dankbar dafür!

Der FB funktioniert so wie er soll, ich denke er kann bestimmt noch verbessert werden, bin dankbar für jeden Tipp :grin:

Hier der Code wie ich es gelöst habe:

//--------------------------------------------------------------------------------------------------------//
// Beschreibung FB804: Stoerungausgabe //
// //
// Erstellt : Schmidt M. am 09.09.11 - Code dokumentiert //
// //
//--------------------------------------------------------------------------------------------------------//
// //
// INHALTSVERZEICHNIS: 1) = Erfassung der Fehlerzustände mit definierter Blinkauswertung //
// 2) = Der Freigabezustand der Fehlereingänge //
// 3) = Auswertung für die Störtasterbeleuchtung //
// 4) = Auswertung für Akustisches Signal mit Überbrückungsfunktion //
// 5) = Sperrung des automatischen Wiederanlaufs durch Reseterwartung //
// 6) = Sicheres Abschalten der Ausgänge wenn Baustein nicht aktiv ist //
// //
//--------------------------------------------------------------------------------------------------------//

{SCL_OverwriteBlocks := 'y' ; SCL_CreateDebugInfo := 'y'}
{SetOKFlag := 'y' ; OptimizeObjectCode := 'y'}

FUNCTION_BLOCK FB804 // FB für Fehlerauswertung
CONST
ANZ := 9;
END_CONST
VAR_INPUT
Baustein_aktiv: BOOL; // Baustein wird aktiviert
Fehler1: BOOL; // Fehlerzustand1 = 1x blinken (1Hz) und 5sec Pause
Fehler2: BOOL; // Fehlerzustand2 = 2x blinken (1Hz) und 5sec Pause
Fehler3: BOOL; // Fehlerzustand3 = 3x blinken (1Hz) und 5sec Pause
Fehler4: BOOL; // Fehlerzustand4 = 4x blinken (1Hz) und 5sec Pause
Fehler5: BOOL; // Fehlerzustand5 = 5x blinken (1Hz) und 5sec Pause
Fehler6: BOOL; // Fehlerzustand6 = 6x blinken (1Hz) und 5sec Pause
Fehler7: BOOL; // Fehlerzustand7 = 7x blinken (1Hz) und 5sec Pause
Fehler8: BOOL; // Fehlerzustand8 = 8x blinken (1Hz) und 5sec Pause
Fehler9: BOOL; // Fehlerzustand9 = 9x blinken (1Hz) und 5sec Pause
Fehler10: BOOL; // Fehlerzustand10 = 10x blinken (1Hz) und 5sec Pause
Reseteingang: BOOL; // Reset für Fehler und Stoerpiepser
Ueberbrueckungszeit: TIME; // Eingabe der Überbrückungszeit im Fehlerfall bei drücken des Resettasters
END_VAR
VAR_OUTPUT
LED: BOOL; // Blinkauswertung des anstehenden Fehler (eine LED)
Piepser: BOOL; // Akustische Fehlermeldung
Sammelstoerung: BOOL; // Visuelle Fehleranzeige am Resettaster
Keine_Stoerung: BOOL; // Stoerungsfreier Ausgang
END_VAR

VAR
T_Blink_E: TON; // Blinkzeit EIN
T_Blink_P: TON; // Blinkzeit AUS
T_PAUSE: TON; // Blinkpause
BLINK_JOB: INT; // Anzahl der Blinkvorgänge
LAST_JOB: INT; // Merken welcher JOB schon abgearbeitet wurde (Startwert für den Schleifenindex i)
HM_P: BOOL; // Hilfsmerker Blinken
Alarmueberbrueckung: TOF; // Überbrückungszeit des Alarmsignals bei Fehlerreset
Keine_Stoerung_FRG: BOOL; // Freigabevariable zur weiterverarbeitung
FM1: BOOL; // Flankenmerker1 (Reseterfassung)
FM2: BOOL; // Flankenmerker2 (Reseterfassung)
END_VAR
VAR_TEMP
Fehler: ARRAY[0..10]OF BOOL; // Welcher Fehler steht in der Schleife
i: INT; // Der Fehlerschleifenindex
END_VAR
LABEL _1; // Sprungmarke für Überbrückung des Resetstops im Fehlerfreien Zustand
END_LABEL

BEGIN;
// ------------------------------------------------------------------------------------------------------------------------------//
// (1) Erfassung der Fehlerzustände mit definierter Blinkauswertung //
// ------------------------------------------------------------------------------------------------------------------------------//
Fehler[0] := Fehler1;
Fehler[1] := Fehler2;
Fehler[2] := Fehler3;
Fehler[3] := Fehler4;
Fehler[4] := Fehler5;
Fehler[5] := Fehler6;
Fehler[6] := Fehler7;
Fehler[7] := Fehler8;
Fehler[8] := Fehler9;
Fehler[9] := Fehler10;
// Auf Fehler prüfen und Blink-Job eintragen
IF T_PAUSE.Q THEN // Kein Blinkauftrag aktiv und Pausenzeit abgelaufen
FOR i := LAST_JOB TO ANZ DO
IF Fehler = true THEN // Fehler steht an, dann
BLINK_JOB := i + 1; // Nummer als "Blink-Job" eintragen = Anzahl Blinken
LAST_JOB := BLINK_JOB; // damit bei nächstem Schleifendurchlauf mit nächstem Fehler fortgesetzt wird.
IF LAST_JOB > ANZ THEN
LAST_JOB := 0;
END_IF;
EXIT; // Schleife verlassen und Blink-Job abarbeiten
END_IF;
END_FOR;
IF i > ANZ THEN // Wenn kein Blink-Job eingetragen (Schleife ist durchgelaufen)
LAST_JOB := 0; // dann beim nächsten mal bei 0 beginnen
END_IF;
END_IF;

// Blink-Job abarbeiten
// Timer Einschaltdauer LED
T_BLINK_E(
IN := NOT T_BLINK_P.Q AND BLINK_JOB > 0,
PT := T#300ms
);
// Timer Ausschaltdauer LED
T_BLINK_P(
IN := T_BLINK_E.Q,
PT := T#300ms
);
// Timer Pausenzeit zwischen Blinkjobs
T_PAUSE(
IN := BLINK_JOB = 0,
PT := T#2s
);
// Anzahl blinken zählen
IF NOT T_BLINK_E.Q AND HM_P THEN
BLINK_JOB := BLINK_JOB - 1;
END_IF;
HM_P := T_BLINK_E.Q;

LED := NOT T_BLINK_E.Q AND BLINK_JOB > 0;


// ------------------------------------------------------------------------------------------------------------------------------//
// (2) Der Freigabezustand der Fehlereingänge //
// ------------------------------------------------------------------------------------------------------------------------------//
Keine_Stoerung_FRG :=true;
FOR i := 0 TO 9 DO
IF Fehler = true THEN
Keine_Stoerung_FRG :=False;
END_IF;
END_FOR;


// ------------------------------------------------------------------------------------------------------------------------------//
// (3) Auswertung für die Störtasterbeleuchtung //
// ------------------------------------------------------------------------------------------------------------------------------//
//Hier soll die Sammelstoerung (Störmeldeleuchte des Resettasters) angesteuert werden, immer wenn ein Fehler besteht und NUR bei Fehlerfreiheit ausgehen:
IF Keine_Stoerung_FRG = false THEN Sammelstoerung:=true;
ELSE Sammelstoerung:=false;
END_IF;


// ------------------------------------------------------------------------------------------------------------------------------//
// (4) Auswertung für Akustisches Signal mit Überbrückungsfunktion //
// ------------------------------------------------------------------------------------------------------------------------------//
//Hier soll der Piepser im Takt des Fehlers gesetzt werden und bei drücken des Resettasters eine "gewisse Zeit" (Eingangsparameter) überbrückt werden.... steht er nach der Zeit immernoch an kommt erneut ein Alarm
IF LED AND NOT Alarmueberbrueckung.Q THEN Piepser:=true;
ELSE Piepser:=false;
END_IF; //OK
Alarmueberbrueckung( //Sollte ein Reset betätigt werden erlischt der Alarm und soll nach abgleaufener Zeit wieder melden......-> wenn Fehler noch ansteht!
IN := Reseteingang,
PT := Ueberbrueckungszeit //Überbrückungszeit vorgegeben durch Eingangsparameter
);


// ------------------------------------------------------------------------------------------------------------------------------//
// (5) Sperrung des automatischen Wiederanlaufs durch Reseterfassung //
// ------------------------------------------------------------------------------------------------------------------------------//
//Hier die speichernden Fehler damit erst nach drücken des Resettasters der Ausgang wieder gesetzt werden kann......
IF Keine_Stoerung AND Reseteingang THEN GOTO _1; //Überspringen des Rücksetzens im Fehlerfreien Betrieb durch drücken des Resets
END_IF;
FM2 := Reseteingang AND Keine_Stoerung_FRG AND NOT FM1; //Speichernde Flanke durch Reseteingang
FM1 := Reseteingang AND Keine_Stoerung_FRG;
IF FM2 = TRUE THEN //Flip-Flop Funktion
Keine_Stoerung:= Keine_Stoerung XOR Keine_Stoerung_FRG;
END_IF;
IF NOT Keine_Stoerung_FRG THEN Keine_Stoerung:=false; //Fehlerzustand setzt Ausgang sicher zurück
END_IF;
_1: //Sprungmarke wegen des Rücksetzens im Fehlerfreien Betrieb durch drücken des Resettasters


// ------------------------------------------------------------------------------------------------------------------------------//
// (6) Sicheres Abschalten der Ausgänge wenn Baustein nicht aktiv ist //
// ------------------------------------------------------------------------------------------------------------------------------//
//Hier sollen die Ausgänge abgeschalten werden wenn der Baustein inaktiv ist. WICHTIG: Am Ende des Bausteins damit alle Ausgänge überschrieben werden!!!
IF NOT Baustein_aktiv THEN LED:=false; Piepser:=false; Sammelstoerung:=false; Keine_Stoerung:=false;
END_IF;
// Hier darf nix mehr rein.........
END_FUNCTION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit der "Raute" war ds kleine Icon über dem Eingabefenster gemeint. Du schreibst den Code dann zwischen die eckigen Klammern...

Aber Dein Posting zeigt, wieviel Initiative Du dabei gezeigt hast.

So mag es das Forum ;)

Ich verstehe nur nicht ganz den "Umweg" mit dem Arraybit Fehler[0].

Deklariere doch das Array für den Bereich [1..10] und rangiere die Eingänge "passend" Fehler[1] := Fehler1;
Dann musst Du auch nicht Beim Blinkjob-Eintrag mit "i+1" arbeiten.
Oder gab es dafür doch noch einen Grund mit dem Feld[0] zu arbeiten ?!?

// ------------------------------------------------------------------------------------------------------------------------------//
// (3) Auswertung für die Störtasterbeleuchtung //
// ------------------------------------------------------------------------------------------------------------------------------//
//Hier soll die Sammelstoerung (Störmeldeleuchte des Resettasters) angesteuert werden, immer wenn ein Fehler besteht und NUR bei Fehlerfreiheit ausgehen:
IF Keine_Stoerung_FRG = false THEN Sammelstoerung:=true;
ELSE Sammelstoerung:=false;
END_IF;
geht einfacher mit:
Code:
Keine_Stoerung_FRG := not Sammelstoerung;

Und zu guter letzt: Mit dem Button "Vorschau" kannst Du Dir das Posting ansehen, bevor Du auf "Antworten" klickst.
 
Zurück
Oben