TIA Unterprogramm nicht zyklisch ausführen

bhmth

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

ich habe folgendes Problem ich habe einen Zebra Drucker der von einer SPS mit Daten gefüttert wird und einen Druckbefehl bekommt (beides über Ethernet). Das funktioniert soweit auch ganz gut allerdings druckt er in 1 von 100 Fällen zweimal hintereinander das selbe Etikett. Meine Vermutung (da es erst auf der S7-1500 vorkommt) ist das er bei einer sehr kurzen Zykluszeit den Befehlt 2 mal bekommt.
Wenn ich das ganze durch ein kleine Programm in Java/C# mache dann druckt er genau das was ich möchte. Deswegen die Vermutung das es an der zyklischen Bearbeitung liegt.

Um das ganze zu umschiffen würde ich gerne, wenn irgendwie möglich ein Programm Eventgetriggert einmal durchlaufen.

Hauptproblem sind vermutlich die T_SEND und T_RCV Bausteine, da diese ja antizyklisch arbeiten und man auf die Rückmeldung dieser ja warten müsste damit das Ganze konsistent bleibt.

Ich hatte mir schon überlegt das Ganze in eine zweite kleine S7-1200 auszulagern, in dieser eine sehr hohe Zykluszeit einzustellen.
Um auf die Rückmeldung der T_XXX Bausteine zu warten hätte ich dann eine Endlosschleife genommen... leider fehlt mir hier die Möglichkeit für einen Software-Interrupt um die SPS aus dieser Endlosschleife zu befreien wenn die Rückmeldung da ist

Fällt euch dazu irgendwas ein wie man das evtl. anstellen könnte ? Bin für (fast) jeden Input dankbar!
 
allerdings druckt er in 1 von 100 Fällen zweimal hintereinander das selbe Etikett. Meine Vermutung (da es erst auf der S7-1500 vorkommt) ist das er bei einer sehr kurzen Zykluszeit den Befehlt 2 mal bekommt.
Vermutlich ist Deine Logik/Verknüpfung zum Start des Ausdrucks fehlerhaft formuliert. Wie sieht die entsprechende Programmstelle in Deinem Programm aus?
Hast Du das Programm schon mal auf einer anderen SPS laufen gehabt?
Ein SPS-Programm weiß was es tut oder getan hat (und kann es sich ggf. merken), egal wie kurz die Zykluszeit ist.

Um auf die Rückmeldung der T_XXX Bausteine zu warten hätte ich dann eine Endlosschleife genommen... leider fehlt mir hier die Möglichkeit für einen Software-Interrupt um die SPS aus dieser Endlosschleife zu befreien wenn die Rückmeldung da ist
Eine SPS braucht keine Endlosschleife um auf etwas zu warten und auch keinen Interrupt, um aus der Schleife zu kommen. Das SPS-Programm selber ist eine Schleife. Es braucht einfach nur eine Variable abzufragen und nur reagieren wenn der erwartete Wert in der Variable steht/auftaucht.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi, ja das ist mir schon bewusst das die SPS eine Endlosschleife ist, und auch das es unter normalen Umständen funktionieren sollte was es ja auch in 99 % der Aufträge tut.

Hier die Statemachine zum Senden & Empfangen
Code:
 CASE #step OF
        0:
           RESET_TIMER(#TON);
           #TSEND_C.REQ := FALSE;
           #io_type_control.active := FALSE;
           #step := 1;
            
        1:
            #TON(IN:=TRUE,PT:=UDINT_TO_TIME(#io_type_control.polling_rate));
            IF NOT #io_type_control.active AND #TON.Q THEN
                #step := 4;
            END_IF;
            
        4:
            #io_type_control.active := TRUE;
            IF #io_type_control.label_to_print = 0 AND #send = #STATUS THEN
                #step := 5;
            ELSIF #io_type_control.#label_to_print <> 0 AND #send <> #STATUS AND #send <> ' '   THEN
                #step := 5;
            END_IF;
            
        5:
            #TSEND_C.REQ := TRUE;
            IF #TSEND_C.BUSY THEN
                #step := 6;
            ELSIF #TSEND_C.ERROR THEN
                #countError += 1;
                #step := 0;
            END_IF;
            
        6:
            #TSEND_C.REQ := FALSE;
            #updateCounter += 1;
            IF #io_type_control.#label_to_print <> 0 THEN
                #io_type_control.label_to_print := 0;
                #io_HMI_print := FALSE;
            END_IF;
            
            IF #TSEND_C.DONE THEN
                #cycles += 1;
                #step := 0;
            ELSIF #TSEND_C.ERROR THEN
                #countError += 1;
                #step := 0;
            END_IF;
    END_CASE;
 
Zuletzt bearbeitet:
Hmm, kann Dein TIA keine Kommentare?
Mit so ganz ohne Kommentare, und Verknüpfung von Variablen die nie eine Zuweisung haben, und andererseits Mehrfachzuweisungen ist die Programmanalyse sehr schwierig.

Es ist in der Regel keine gute Idee, Timer nur bedingt oder immer nur mit TRUE am IN aufzurufen. Kriegt Dein Timer #TON auch mal FALSE am IN präsentiert?

Harald
 
Dein Problem aus meiner Sicht ist, dass du den Timer in deiner Schrittkette aufrufst. Das solltest du mal ändern (ihn also außerhalb aufrufen und als Trigger die Schrittnummer nehmen).

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das werde ich mal versuchen, danke!

Aber ich glaube eigentlich nicht das er deswegen einen Druckbefehl zweimal ausgibt.

Kurze Erklärung zu dem CASE
Schritt 0 = INIT gehe sofort in Schritt 1
Schritt 1 = Da wenn kein Druckbefehl aktiv ist ich mir den Status von dem Drucker hole, was auch nur geht wenn man einen String mit einem Befehl sendet, habe ich hier den Timer der die Schrittkette nur alle 500 ms laufen starten lässt.
Schritt 4 = hier wird entschieden ob ein Druckbefehl gesendet wird oder ein Statusbefehl, ist eines der beiden der Fall und der String nicht leer dann weiter zu Schritt 5
Schritt 5 = Daten senden, wenn kein Fehler zu Schritt 6 ansonsten Abbruch und Fehlerzähler +1 und zurück zu Schritt 0
Schritt 6 = Daten gesendet, in beiden Fällen (Fehler oder ok) wird ein Zähler inkrementiert und dann gehts zu Schritt 0

Die Übertragung funktioniert auch gut, die Counter für die Fehler zählen hoch wenn die Übertragung nicht funktioniert bei falscher Config, oder kein Kabel angeschlossen.
 
Ich werde es auf jeden Fall testen wenn ich wieder vor einem Drucker sitze.
Problematisch ist nur das ich 500 Etiketten drucken muss ohne das jemanden stört :rolleyes:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
allerdings druckt er in 1 von 100 Fällen zweimal hintereinander das selbe Etikett.
Wie wird gesteuert, daß normal nicht das selbe Etikett gedruckt wird?

Hier die Statemachine zum Senden & Empfangen
Ich sehe irgendwie nichts was wie eine Verarbeitung von Empfangsdaten aussieht

Was sind das für Variablen #send und #STATUS und #io_type_control.active?
Gibt es von dem Drucker auch Rückmeldungen?

Anstatt dieser komischen Anweisung "RESET_TIMER(#TON);" solltest Du besser schreiben "#TON(IN:=FALSE);"

Harald
 
Wie wird gesteuert, daß normal nicht das selbe Etikett gedruckt wird?

Ich sehe irgendwie nichts was wie eine Verarbeitung von Empfangsdaten aussieht

Was sind das für Variablen #send und #STATUS und #io_type_control.active?
Gibt es von dem Drucker auch Rückmeldungen?

Anstatt dieser komischen Anweisung "RESET_TIMER(#TON);" solltest Du besser schreiben "#TON(IN:=FALSE);"

Harald

#send ist der String der an den Drucker gesendet wird (ZPL II CODE)
#STATUS ist ein konstanter String, der Befehl dahinter veranlasst den Drucker seinen Status zu senden das sind drei riesige Strings dir man erst "zerpflücken" muss um daraus Informationen zu bekommen. Das nagt natürlich sehr an der Zykluszeit, deswegen hole ich mir nur eine Information daraus.
#io_type_control.active ist lediglich eine aktiv_Meldung die in einem DB gespeichert wird.

Der Druckbefehl wird nur von einem anderen Programmteil gestartet, dieser setzt #label_to_print <> 0, das Programm über der CASE - Anweisung setzt dann einen String #send zusammen und die CASE Anweisung läuft dann mit dem Label-String durch (ansonsten ist #send = STATUS) im letzen Schritt setzt die CASE - Anweisung #label_to_print = 0 und somit ist im nächsten Zyklus #send = STATUS und es wird wieder der Status des Druckers abgefragt.

Also eine direkte Rückmeldung gibt er nicht, wie aktiv, fertig, usw... Man könnte evtl. über diese Status-Strings sich Informationen holen aus denen man rauslesen kann das was gedruckt wurde. Das möchte ich aber eigentlich nicht unbedingt machen da es wirklich sehr auf die Ressourcen geht und auch nicht immer zuverlässig funktioniert.

Das mit dem Timer werde ich auf jeden Fall ausprobieren

Die Empfangsdaten werden an anderer Stelle verarbeitet da der Drucker diese ja nur sendet wenn man den STATUS an ihn sendet.
 
Zurück
Oben