TIA In FB aufgerufenen FB beobachten oder Ausgangswerte passen nicht zu Code der Eingänge

Zombie

Level-1
Beiträge
732
Reaktionspunkte
120
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

gibt es eine Möglichkeit einen FB der in einem anderen FB aufgerufen wird online zu beobachten?

Grund: Ich habe einen FB der mir das Verhalten eines Fahrzeugs entlang der gesamten Strecke steuert. jedes Fahrzeug hat einen eigenen FB (FB 350). In der Anlage habe ich drei Übergabestationen, die jeweils einen Warteplatz haben. Steht nun ein Fahrzeug am Übergabeplatz, soll der auf dem Fahrzeug befindliche Förderer angesteuert werden, der Förderer des Fahrzeugs auf dem Warteplatz aber noch nicht (die Ladung würde sonst ins leere fallen). Jeder der Übergabeplätze ist als FB Aufruf (FB 1324) im Haupt FB (FB 350) realisiert. D.h. ich rufe den gleichen FB an drei verschiedenen Stellen im Haupt FB auf, jedesmal mit der selben Instanz. Da in dem FB mehrere Flankenmerker benötigt werden ist es ein FB, einfach um das ganze sauberer zu halten, es könnte eigentlich auch ein FC sein bei dem die Merker als In-Out übergeben werden. Wird der FB nicht benötigt, werden die Flankenmerker über einen Aufruf mit einem negativen Aktiv- Befehl zurückgesetzt.

Leider kommt es vor, dass die Fehlermeldung "Förderer aktiviert ohne Übergabebefehl" mehrmals pro Stunde kommt. Immer von Fahrzeugen die in der Warteposition stehen und den Eingangsbedingungen nach eigentlich keine Freigabe hätten den Förderer anzuschmeißen. Beispielhaft steht Fahrzeug 3 am ÜPlatz und Fahrzeug 9 auf dem Warteplatz dahinter, kommt die Meldung von Fahrzeug 9.
Schaut man nun in den Haupt FB rein, steht, wenn man vorher auf den FB des Fahrzeugs 9 per "Öffnen und beobachten" Online reinschaut, an den Ausgängen des FB 1324 drin, dass das Fahrzeug den Förderer zur Abgabe tatächlich anschalten soll. Möchte ich nun den FB 1324 ebenfalls mit "Öffnen und beobachten" Online betrachten, wechseln die Werte darin zwischen den Fahrzeugen hin und Her. D.h. ich sehe Integer- Werte, welche die Fahrzeugnummer angeben, zwischen allen Fahrzeugnummern wechseln die gerade an den Übergabestationen stehen. Obwohl ich im FB 350 keine Wechsel habe.

Habe dann versucht den FB einfach den FB 1324 Offline zu betrachten und dann anhand der Eingangswerte des FB- Aufrufs im FB 350 herauszufinden was falsch läuft. Jedoch konnte ich nicht herausfinden wie für dieses Fahrzeug, mit diesen Eingangswerten, diese Ausgangswerte herauskommen konnten. Der FB bekam die Fahrzeugposition ganz klar übergeben und in dieser Position wurde der Anschaltbefehl für den Förderer überhaupt nicht benutzt. Der Freigabebefehl würde erst gegeben wenn das Fahrzeug an der Übergabestation physisch stehen würde. Dies wird durch eine Sender- Empfänger Lichtschranke zusätzlich abgefragt, welche auch verhindert hat den Motor anzuschmeißen, da ich sie später nochmal als letzte Freigabe abfrage.
Die Fehlermeldung war eigentlich nur für mich gedacht, um mir anzuzeigen dass ich noch nen Programmierfehler habe.

Damit die Nachtschicht arbeiten kann, habe ich die FB Aufrufe des FB 1324 im FB 350 letzte Nacht rausgeschmissen und den Code dreimal auf die Position abgestimmt so reingeschrieben, seitdem läuft es.

Während der IBN war das ganze auch schon vereinzelt aufgetreten, da hatte ich das aber immer auf die IBN Bedingungen geschoben da das wie gesagt anhand des Codes nicht nachvollziehbar war.

Steuerung ist eine 1516 3PN/DP und Programmiert ist das ganze mit TIA V15.0.0 in SCL.



Danke
 
Zuletzt bearbeitet:
Könnt ihr das erläutern?

Die Ausgänge eines FB's müssten doch eigentlich abhängig von des Eingangsdaten in ebendiesem Aufruf sein.
In jeder Instanz des FB 350 wird der FB 1324 drei mal aufgerufen, aber immer nur dann, wenn die If- Abfrage die den Aufruf umschließt wahr ist.
Und das ist sie immer nur einmal, denn das Fahrzeug kann nicht an drei verschiedenen Positionen stehen.

Die Flanken sind für eine andere Funktion da, das was nicht funktioniert ist nur abhängig von den Eingangsdaten, keinen Daten die der FB von einem vorherigen Aufruf noch haben könnte.

Kennt trotzdem jemand eine Möglichkeit sich auch diesen FB online und nur für ein Fahrzeug zur selben zeit anzuschauen?
 
Kannst/Darfst du den Code hier posten ? Die Sache hört sich sehr dubios an. Warum eine Instanz mehrmals aufrufen ? Das macht man einfach nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sehe ich genauso wie meine Vorredner. Für jeden Aufruf eine eigene Instanz
Und: In einem mehrfach aufgerufenem FB haben absolut adressierte Flankenmerker nichts verloren
 
Zuletzt bearbeitet:
Hier der Aufruf im FB 350

Code:
 IF #iiFpNr = 2 THEN
#sHeber(iiFpNr := #iiFpNr,
                iiMpNr := #iiMpNr,
                iiFzgNr := #iiFzgNr,
                iiFzgZiel := #siFzgZiel,
                iiPositionEingang := 3,
                iiPositionHeber := 4,
                iiPositionAusgang := 5,
                iiAktionArt := #iiTaStatus,
                ixAktiv := #vke1,
                ixBel := #sxBel,
                ixInPos := #sxInPos,
                ixV1 := #sxFahreV1,
                ixV2 := #sxFahreV2,
                ixHalt:=#ixHalt,
                ixAutoHandHeber:="ixAutoHand_1HE1",
                ixFzgFahrenHeber:="ixFzgFahren_1HE1",
                ixEndlageGerade:="ixEndlageGerade_1WE2",
                ixAutoHandWeiche:="ixAutoHand_1WE2",
                ixFzgFahrenWeiche:="ixFzgFahren_1WE2",
                oiPosition => #oiVisuPos,
                oxFahreV2 => #iodFzgbefehle.xFahreV2,
                oxFahreV1 => #iodFzgbefehle.xFahreV1,
                oxFtRechts => #iodFzgbefehle.xFtRechts,
                oxFtLinks => #iodFzgbefehle.xFtLinks,
                oxPositioniere => #iodFzgbefehle.xPositioniere,
                oxSendTelegramm => #ioxSendeTelegramm,
                iodStatusHeber := "dbStrecke".Heber1,
                iodStatusWeiche := "dbStrecke".Weiche002);
END_IF;
IF #iiFpNr = 3 THEN
        #sHeber(ixAktiv := #vke0);
.
END_IF;
.
IF #iiFpNr = 5 THEN
        #saFlanke[4] := FALSE;
        #sHeber(iiFpNr := #iiFpNr,
                iiMpNr := #iiMpNr,
                iiFzgNr := #iiFzgNr,
                iiFzgZiel := #siFzgZiel,
                iiPositionEingang := 9,
                iiPositionHeber := 10,
                iiPositionAusgang := 11,
                iiAktionArt := #iiTaStatus,
                ixAktiv := #vke1,
                ixBel := #sxBel,
                ixInPos := #sxInPos,
                ixV1 := #sxFahreV1,
                ixV2 := #sxFahreV2,
                ixHalt:=#ixHalt,
                ixAutoHandHeber:="ixAutoHand_1HE2",
                ixFzgFahrenHeber:="ixFzgFahren_1HE2",
                ixEndlageGerade:="ixEndlageGerade_1WE4",
                ixAutoHandWeiche:="ixAutoHand_1WE4",
                ixFzgFahrenWeiche:="ixFzgFahren_1WE4",
                oiPosition => #oiVisuPos,
                oxFahreV2 => #iodFzgbefehle.xFahreV2,
                oxFahreV1 => #iodFzgbefehle.xFahreV1,
                oxFtRechts => #iodFzgbefehle.xFtRechts,
                oxFtLinks => #iodFzgbefehle.xFtLinks,
                oxPositioniere => #iodFzgbefehle.xPositioniere,
                oxSendTelegramm => #ioxSendeTelegramm,
                iodStatusHeber := "dbStrecke".Heber2,
                iodStatusWeiche := "dbStrecke".Weiche004);
End_IF;
IF #iiFpNr = 6 THEN
        #sHeber(ixAktiv := #vke0);
.
END_IF;
.
Den dritten Aufruf schenke ich mir
Code:
IF #iiMpNr = 61 AND ixAktiv THEN
    //Wenn Anmeldung frei ist, meldet sich das Fahrzeug an,
    //übergibt seine Fahrzeugnummer und seinen Belegungsstatus an den Heber
    IF #iodStatusHeber.iFzgNrAn = 0
        AND #iodStatusHeber.iFzgNr = 0 THEN
        //#iodStatus.xAnmeldFzg := TRUE;
        #iodStatusHeber.iFzgNr := #iiFzgNr;
        #iodStatusHeber.xFzgBel := #ixBel;
    END_IF;
    //Allgemeine Steuerbefehle geben
    #oxFtRechts := FALSE;
    #oxFtLinks := FALSE;
    IF #ixAutoHandHeber THEN //Wenn Automatik
        #oxFahreV1 := #iodStatusHeber.xFrgFahren
        AND #iodStatusHeber.iFzgNrAn = #iiFzgNr
        AND NOT #ixHalt;
        #oxFahreV2 := FALSE;
        #oxPositioniere := FALSE;
    ELSE //Im Handbetrieb
        #oxFahreV1 := #ixFzgFahrenHeber AND #iodStatusHeber.iFzgNrAn = #iiFzgNr;
        #oxFahreV2 := FALSE;
        #oxPositioniere := FALSE;
    END_IF;
    IF #ixV1 THEN //Anmeldung löschen
        IF #iodStatusHeber.iFzgNr = #iiFzgNr THEN
            #iodStatusHeber.iFzgNr := 0;
        END_IF;
    END_IF;
    #oiPosition := #iiPositionEingang;
ELSIF #iiMpNr = 62 AND ixAktiv THEN
    //Dem Fahrzeug wird befohlen zu positionieren
    IF NOT #ixInPos AND NOT #saFlanke[1] THEN
        #oxPositioniere := TRUE;
        #oxFahreV1 := FALSE;
        #oxFahreV2 := FALSE;
        #oxSendTelegramm := TRUE;
        #saFlanke[1] := TRUE;
    ELSIF #ixInPos THEN
        //Nachdem das Fahrzeug positioniert hat
        #oxSendTelegramm := FALSE;
        #oxPositioniere := FALSE;
        //wird nach der Auftragsart geschaut. Soll das Fahrzeug keine Interaktion mit dem Heber haben,
        //bekommt der Heber nicht mit dass ein Fahrzeug in ihm positioniert hat
        IF #iiAktionArt = 2 OR #iiAktionArt = 3 OR #iiAktionArt = 10 THEN
            #iodStatusHeber.xFzgInPos := TRUE;
            #iodStatusHeber.iAktionArt := #iiAktionArt;
        END_IF;
    END_IF;
    IF #ixAutoHandHeber THEN
        IF #iiFzgZiel = #iiFpNr AND #ixInPos THEN
            //Wenn der Heber dann in Position ist, wird anhand des Auftrags entschieden was gemacht
            //werden muss
            IF #iodStatusHeber.xHebPos THEN
                IF #iodStatusHeber.iAktionArt = 3 THEN //Abgeben
                    #oxFtRechts := TRUE;
                    #oxFtLinks := FALSE;
                ELSIF #iodStatusHeber.iAktionArt = 2 THEN //Aufnehmen
                    #oxFtRechts := FALSE;
                    #oxFtLinks := TRUE;
                ELSIF #iodStatusHeber.iAktionArt < 2 OR #iodStatusHeber.iAktionArt > 3 THEN
                    ;//Warten auf neuen Auftrag
                END_IF;
                //Hat das Fahrzeug seine Aktion fertiggestellt wird das Signal an den Heber gesendet
                IF NOT #ixBel THEN
                    #iodStatusHeber.xFzgBel := FALSE;
                ELSE
                    #iodStatusHeber.xFzgBel := TRUE;
                END_IF;
            ELSIF NOT #iodStatusHeber.xHebPos AND #iodStatusHeber.xHebBel AND #ixBel THEN
                //Ist der Heber bereits von einer Palette belegt, fährt das Fahrzeug durch
                #iodStatusHeber.xFzgInPos := FALSE;
                #oxFahreV1 := #iodStatusHeber.xFrgFahren
                AND #iodStatusHeber.iFzgNrAn = #iiFzgNr
                AND NOT #ixHalt;
                #oxFahreV2 := FALSE;
                #oxPositioniere := FALSE;
                //An der nächsten Weiche anmelden schon hier
                IF #iodStatusWeiche.iFzgNrAn = 0
                    AND #iodStatusWeiche.iFzgNrGerade = 0 THEN
                    #iodStatusWeiche.iFzgNrGerade := #iiFzgNr;
                END_IF;
            END_IF;
            //Ist Heber nicht in Automatik kann ich das Fahrzeug weiterfahren lassen
        ELSIF #iiFzgZiel <> #iiFpNr THEN
            //Hat die Steuerung ein neues Ziel gegeben und sagt der Heber fahren erlaubt, dann wird
            IF #iodStatusWeiche.iFzgNrAn = 0
                AND #iodStatusWeiche.iFzgNrGerade = 0 THEN
                #iodStatusWeiche.iFzgNrGerade := #iiFzgNr;
            END_IF;
            #oxFahreV1 := #iodStatusHeber.xFrgFahren
            AND #iodStatusHeber.iFzgNrAn = #iiFzgNr
            AND #ixAutoHandWeiche
            AND #iodStatusWeiche.xFrgFahren
            AND #iodStatusWeiche.iFzgNrAn = #iiFzgNr
            AND #ixEndlageGerade
            AND NOT #ixHalt;
            #oxFahreV2 := FALSE;
            #oxPositioniere := FALSE;
        END_IF;
    ELSE//Im Handbetrieb
        #oxFahreV1 := #ixFzgFahrenHeber AND NOT #iodStatusHeber.xHebPos;
        #oxFahreV2 := FALSE;
        #oxPositioniere := FALSE;
    END_IF;
    #oiPosition := #iiPositionHeber;
ELSIF #iiMpNr = 63 AND ixAktiv THEN
    //Flanke zurücksetzen
    #saFlanke[1] := FALSE;
    //Geschwindigkeit setzen
    #oxFahreV1 := NOT #ixHalt;
    #oxFahreV2 := FALSE;
    #oxPositioniere := FALSE;
    #oiPosition := #iiPositionAusgang;
ELSIF NOT ixAktiv THEN
    #saFlanke[0] := FALSE;
    #saFlanke[1] := FALSE;
    #saFlanke[3] := FALSE;
END_IF;
Mp 61 ist der Warteplatz, Mp 62 ist der Übergabeplatz, Mp 63 ist der Ausgangsplatz. Die Flanke wird im FB am Ausgangsplatz zurückgesetzt.
Im Mp 61 wird kein Befehl gegeben den Förderer zu starten, trotzdem kam das am Ausgang raus und das Fahrzeug wollte es tun.
Müsste nicht das was am Ausgang rauskommt, dem entsprechen was am Eingang reingeht?
Der Eingang iiMp war auf 61, andere Fahrzeuge waren gerade an 62, aber das dürfte diesem FB Aufruf egal sein, da jede Instanz des FB 350 nur für ein Fahrzeug ist.
saFlanke ist ein Array of Bool im Statischen Bereich des FB's, das sind die Flankenmerker. Die anderen beiden sind für die Visufunktion, die hab ich mir geschenkt.

Kann man sich den FB denn nun anschauen? Er wird nur einmal im FB aufgerufen, deshalb sollte er doch eigentlich keine wechselnden Fahrzeugnummern haben.
Hat er aber. Kann ich das mit eigenen Instanzen beheben? Denke nicht, denn wie gesagt, andere Fahrzeuge haben in dem FB nichts verloren und andere Aufrufe finden nicht statt, denn das Fahrzeug steht nur an einem Platz, entweder 2 oder 5, niemals beide zusammen.
 
Zuletzt bearbeitet:
Nein du kannst den FB nicht fahrzeugspezifisch betrachten, da du die gleiche Instanz mit drei verschiedenen Datensätzen fütterst. Erstelle doch zuerst einmal für jeden FB-Aufruf eine eigene Instanz und schau dir dann den jeweiligen FB an. Du vermischst einfach Daten und Zustände im FB miteinander da du drei mal die gleiche Instanz verwendest. Nur weil du drei mal den FB aufrufst wird er nicht drei mal gesondert abgearbeitet. Vielleicht ja, vielleicht nein. Mach zu erst einmal deine Aufrufe sauber und beginne dann mit der Diagnose.

Dir haben schon 3-4 Leute gesagt gesagt, dass du für jeden FB eine eigene Instanz erstellen sollst und du versuchst es bisher ja nicht umzusetzen..
 
Wenn man einen FB immer mit der gleichen Instanz verwendet, wozu dann ein FB? Dann kann man auch einen FC + Global DB verwenden.
Wenn du in deinem FB irgendwelche Statischen Variablen hast sind diese für alle Aufrufe gleich, z.B werden die Flanken dann bestimmt nicht so funktionieren wie gewünscht.
 
Die Flanken haben schon funktioniert, was nicht funktioniert ist der Teil der ohne Flanken war.
Das Fahrzeug steht an MP 61 und will den Förderer anmachen.
Code:
//Allgemeine Steuerbefehle geben[SIZE=2]
#oxFtRechts := FALSE;[/SIZE][SIZE=2][FONT=arial]
#oxFtLinks := FALSE;[/FONT][/SIZE][SIZE=2][FONT=arial]
wird komplett ignoriert. Ein anschalten ist erst vorgesehen wenn MP den Wert 62 angenommen hat.[/FONT][/SIZE]
Habe es heute mit 3 unterschiedlichen Instanzen probiert, habe das gleiche Verhalten gesehen, dass die Fahrzeugnummer beim Onlinebetrachten rumsprang.

Ich hab den FB jetzt komplett rausgeschmissen, bin die Fehlersuche satt, wird der FB350 halt über 4000Zeilen groß :sb6:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es scheint darum zu gehen, dass ein UnterProgramm an mehreren Stellen im Programm aufgerufen wird, man aber nur einen bestimmten Aufruf beobachten will, ohne dass die anderen Aufrufe dazwischenfunken.
Uraltes HilfsMittel:
Eine exakte Kopie des UnterProgramms anlegen und im interessierenden Fall diese aufrufen - in allen anderen Fällen das Original. Oder umgekehrt.
Das bedingt natürlich an der/den aufrufenden Stelle[n] ein wenig (provisorischen) MehrAufwand.
Es ermöglicht eine ungestörte Beobachtung, kann aber keine FehlFunktionen beseitigen, die durch Doppel-/MehrfachBelegung derselben Instanz eines FB entstehen.
 
Oder einfach die Aufrufumgebung festlegen.
Rechte Sidebar unter "Testing" Punkt "Call environment" dort auf den Button "Change"
Dort werden alle Aufrufe des Bausteins angezeigt. Eifach den zu beobachtenden Baustein auswählen und auf den Button "Transfer to "adjust manually" klicken und dann mit OK schließen.
Wenn du jetzt beobachtest siehst du auch nur das was bei dem Aufruf gültig ist.

Oder eine Beobachtungsliste erstellen auf die Daten der Instanzen dann siehst du auch was Sache ist.
Oder in dem Instanzdatenbaustein beobachten.

Gruß

Jens
 
Zurück
Oben