So Anbei "mein" Baustein...
Folgende Funktionen hat er:
Der Baustein wird nur abgearbeitet wenn der Eingang ENABLE aktiv ist.
Über die Eingänge PROFIBUS oder PROFINET wählt man das Bussystem, es kann nur eines Aktiv sein.
Im Stat-Bereich liegt das Array Teilnehmer_Busfehler of BOOL. Hier werden bis zu 256 Busteilnehmerstörungen angezeigt, jeweils für das ausgewählte Bussystem.
Das es mehr PN-Teilnehmer geben kann ist mir klar, für mich ist aber mehr nicht nötig. Wer mag kann den Baustein gerne aufbohren.
PB habe ich getestet, die Zykluszeit bei einem IPC477C mit WinLC RTX wird nicht beeinflusst.
PN kann ich erst im laufe der Tage testen, gebe dann Feedback!
Eine Fehlerauswertung des SFC51 findet nicht statt.
Code:
FUNCTION_BLOCK FB126
TITLE = 'BUS_DIAG'
AUTHOR : 'Matze001'
VERSION : '1.0'
VAR_INPUT
ENABLE : BOOL;
PROFIBUS : BOOL;
PROFINET : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR
Teilnehmer_Busfehler : ARRAY[1..256] OF BOOL ;
SK1_NR : INT;
REQ1 : BOOL ;
REQ2 : BOOL ;
REQ3 : BOOL ;
REQ4 : BOOL ;
BUSY1 : BOOL ;
BUSY2 : BOOL ;
BUSY3 : BOOL ;
BUSY4 : BOOL ;
END_VAR
VAR_TEMP
Fehler : INT ;
i : INT;
SZL_Header : STRUCT
LenthDR : WORD ;
n_DR : WORD ;
END_STRUCT ;
Abfrage_PB_Slaves : STRUCT
projektiert : ARRAY[0..255] OF BOOL ;
in_Funktion : ARRAY[0..255] OF BOOL ;
END_STRUCT ;
Abfrage_PN_Slaves : STRUCT
projektiert_Status : WORD ;
projektiert : ARRAY[0..2047] OF BOOL ;
in_Funktion_Status : WORD ;
in_Funktion : ARRAY[0..2047] OF BOOL ;
mit_Stoerung_Status : WORD ;
mit_Stoerung : ARRAY[0..2047] OF BOOL ;
END_STRUCT ;
at_Abfrage_PN_Slaves AT Abfrage_PN_Slaves : STRUCT
projektiert : ARRAY[0..128] OF WORD ;
in_Funktion : ARRAY[0..128] OF WORD ;
mit_Stoerung : ARRAY[0..128] OF WORD ;
END_STRUCT ;
END_VAR
BEGIN
// Profibusauswertung
IF ENABLE AND PROFIBUS AND NOT PROFINET AND SK1_NR = 0 THEN
REQ1:=TRUE;
SK1_NR:=1;
END_IF;
Fehler := RDSYSST (REQ := REQ1
,SZL_ID := w#16#0092 // Abfrage der projektierten ProfiBus-Stationen
,INDEX := 1 // Mastersystem-ID
,BUSY := BUSY1
,SZL_HEADER := SZL_Header
,DR := Abfrage_PB_Slaves.projektiert // Ziel-Datenbereich für die abgefragten Daten
) ;
IF SK1_NR = 1 AND NOT BUSY1 AND FEHLER = 0 THEN
REQ1:=FALSE;
REQ2:=TRUE;
SK1_NR:=2;
END_IF;
Fehler := RDSYSST (REQ := REQ2
,SZL_ID := w#16#0292 // Abfrage der nicht ausgefallenen ProfiBus-Stationen
,INDEX := 1 // Mastersystem-ID
,BUSY := BUSY2
,SZL_HEADER := SZL_Header
,DR := Abfrage_PB_Slaves.in_Funktion // Ziel-Datenbereich für die abgefragten Daten
) ;
IF SK1_NR = 2 AND NOT BUSY2 AND FEHLER = 0 THEN
REQ2:=FALSE;
SK1_NR:=3;
END_IF;
IF SK1_NR = 3 THEN
FOR i:= 0 TO 255 DO
Teilnehmer_Busfehler[i+1] := Abfrage_PB_Slaves.projektiert[i] AND NOT Abfrage_PB_Slaves.in_Funktion[i];
END_FOR;
SK1_NR:= 0;
END_IF;
// Profinetauswertung
IF ENABLE AND NOT PROFIBUS AND PROFINET AND SK1_NR = 0 THEN
REQ3:=TRUE;
SK1_NR:=11;
END_IF;
Fehler := RDSYSST (REQ := REQ3
,SZL_ID := w#16#0094 // Abfrage der projektierten ProfiNet-Stationen
,INDEX := 100 // Mastersystem-ID
,BUSY := BUSY3
,SZL_HEADER := SZL_Header
,DR := at_Abfrage_PN_Slaves.projektiert // Ziel-Datenbereich für die abgefragten Daten
) ;
IF SK1_NR = 11 AND NOT BUSY3 AND FEHLER = 0 THEN
REQ3:=FALSE;
REQ4:=TRUE;
SK1_NR:=12;
END_IF;
Fehler := RDSYSST (REQ := REQ4
,SZL_ID := w#16#0294 // Abfrage der nicht ausgefallenen ProfiNet-Stationen
,INDEX := 100 // Mastersystem-ID
,BUSY := BUSY4
,SZL_HEADER := SZL_Header
,DR := at_Abfrage_PN_Slaves.in_Funktion // Ziel-Datenbereich für die abgefragten Daten
) ;
IF SK1_NR = 12 AND NOT BUSY4 AND FEHLER = 0 THEN
REQ4:=FALSE;
SK1_NR:=13;
END_IF;
IF SK1_NR = 13 THEN
FOR i:= 1 TO 255 DO
Teilnehmer_Busfehler[i] := Abfrage_PN_Slaves.projektiert[i] AND NOT Abfrage_PN_Slaves.in_Funktion[i];
END_FOR;
SK1_NR:= 0;
END_IF;
END_FUNCTION_BLOCK
Kritik sehr willkommen!
Grüße
Marcel
Edit: So hab mir doch noch die Zeit genommen PN zu testen! Hatte da nen haufen Fehler drin, da ich einfach den Profibusteil kopiert hab
Nun funktioniert auch PN einwandfrei!
Edit2: Also ich habe den Baustein noch einmal nach dem Vorbild von LL angepasst.
Ich versuche mal eine grobe Beschreibung abzuliefern, um auch oxidierenden Nägeln etwas gutes zu tun
Der Baustein wird immer aufgerufen. Mit dem Enable Eingang wird die Abfrage angestossen. Wird er auf Dauer TRUE gesetzt, wird nach jeder fertigen Abfrage eine neue gestartet.
Ich habe es so zur Zeit im Einsatz, und sehe keine Einbußen bei Zykluszeit o.ä.! Hier können natürlich Trigger aus den entsprechenden Fehler OBs, Timer, Zufallsgeneratoren oder what ever als Trigger genutzt werden.
Durch die Eingänge Profibus und Profinet wird das Bussystem vorgewählt. Sind beide auf TRUE wird keine Abfrage gestartet. Wenn ich Lust habe lösche ich alle Daten noch ab, das ist bisher nicht der Fall!
Der Zustand eines Teilnehmers kann dann dem Array Teilnehmer_Busfehler entnommen werden. Es wird nur Diagnostiziert ob der Teilnehmer am Bus ist.